Soli is built for AI.
Soli gives coding agents the same thing it gives you: one way to do each thing,
a short language, and a complete product stack. Token-efficient code that agents
can write and humans can review — from soli new
to production, including the LLM and the retrieval layer.
01
Convention over configuration
Soli gives agents a map.
One folder for models, one for controllers, one for jobs.
resources("posts"),
soli generate scaffold,
and a root CLAUDE.md so generated
changes land closer to idiomatic Soli with less prompting.
02
Token efficiency
Less language means more context.
Soli is a small language on purpose: postfix
unless, implicit returns,
no package manager, no bundler. Agents spend tokens on the product,
not on boilerplate or five ways to import a model.
03
A contract, not a prompt
Verification is non-negotiable.
Every soli new app ships
AGENTS.md, per-directory
guides, /soli-verify, and
a coverage gate. If lint or tests fail, the rule is to fix the
cause — never weaken the suite.
04
The one-person stack
One person can ship more. MVC, jobs, auth, LiveView, and the LLM live in one binary. Add an agent and you are not stitching a vector DB, a queue, and a chat SDK together from scratch.
Agents on Soli
The same idea as Rails’ Agents on Rails: measure coding
agents on a frozen corpus of atomic Soli tasks. First board:
Claude Code (claude -p),
OpenCode + DeepSeek, and Grok Build. Graded with
soli lint and
soli test. Stage 1 only —
one capability per task. Not a Cursor-vs-Claude-Code table, and not
Soli vs Rails on the same numbers.
Methodology: Agents on Soli.
Harness soli-evals/0.2,
3 runs per model.
No numbers until the first run is committed.
The corpus is in evals/ (12 tasks).
The harness is scripts/evals/run.py.
A paid refresh writes www/data/ai_evals.json.
We will not invent scores for this table.
What ships on day one
soli new myapp is already an agent workspace.
Claude Code, Cursor, Aider, Copilot CLI, and Codex read the same files.
| Path | Purpose |
|---|---|
| CLAUDE.md | Root guide: verification loop, footguns, recipes |
| AGENTS.md | Tool-agnostic pointer to that guide |
| app/*/CLAUDE.md | Controllers, models, views, middleware, tests, migrations |
| .claude/commands/ | /soli-verify, /soli-test, /soli-resource |
| .claude/settings.json | Safe soli subcommands pre-allowed |
| docs/ | Bundled language docs so the agent does not need the network |
$ soli lint app/controllers/orders_controller.sl
$ soli test tests/controllers/orders_controller_spec.sl
$ soli test --coverage --coverage-min 90
Full walkthrough: AI agents in Soli projects and the agent philosophy post.
AI in the product, not a sidecar
The same binary that serves your app talks to an OpenAI-compatible chat API, embeds rows, and walks a code graph. No extra process.
llm_generate
Chat completions with SOLI_LLM_API_KEY. Stream tokens with out.llm_stream inside sse.
.similar() · Model.rag
Embed on save, retrieve by cosine / hybrid search, ground the prompt. Product discovery tutorial.
soli graph
Index routes, callers, and views with embeddings. Agents get a neighbourhood, not a random snippet. Code Graph RAG.
# retrieve, then stream
hits = Product.similar(q, { "limit": 8 })
answer = out.llm_stream(
"Answer only from the catalogue.",
"Question: #{q}\n\nContext:\n#{hits.map(fn(h) h.name).join(\"\\n\")}"
)
Why agents do well here
Convention over configuration is not nostalgia. It is a prior. One MVC layout, one test DSL, one job folder, one
CLAUDE.md— the model already knows the shape of the next file.
A fast
soli testloop is the difference between an agent that guesses and an agent that finishes. If it is red, it is not done.