Limitations
Worth knowing before you depend on this:
sonata initdiscovers models for four harnesses — opencode, pi, codex and reasonix. Codex has nomodelssubcommand, so its catalogue comes fromcodex app-server'smodel/list(JSON-RPC over stdio), with a real response captured intests/fixtures/codex/model-list.json. Theclaudeharness is the host and is never offered for discovery.Nested agents are unbounded and unattributed. A generated agent can spawn further agents, and nothing counts depth — a
code-normalagent can callAgent(subagent_type: "code-normal")on itself. Read-only roles are told to delegate only to other read-only roles, but that is prompt text:tools:frontmatter grants tools, not permitted argument values.sonata usageattributes spend per session rather than to the dispatch that caused nested cost.Some dispatch runs cannot be attributed. Two dispatches to the same harness in the same directory at the same time are both reported
unobservablerather than split by guesswork.[budget]counts a dispatch when it finishes.sonata dispatchrefuses to launch once a cap is reached, but one run already under way can carry spend past it.Prompt detection is regex against TUIs sonata does not control. Codex's patterns are written from captured real output in
tests/fixtures/panes/, but they will still break when codex changes its interface. TheSTALLEDtimeout is the backstop. OpenCode and Pi cannot prompt at all, so there is nothing to detect. An answered prompt also stays in the pane, so it can be re-reportedPAUSED— wastedapprove/waitround trips, and a digit that lands in the harness's composer as text.Codex through a proxy needs that proxy up. If
~/.codex/config.tomlsetsopenai_base_url,sonata doctorchecks the endpoint is listening — a dead proxy otherwise wastes minutes in retries before failing.opencode run --format jsonis broken upstream (v1.18.15 produces no output and never exits), so progress comes from pane text rather than a structured event stream. Pi's--mode jsondoes work; the adapter keeps a seam for adopting it.opencode's
eventtable grows without bound — 6.5 GB across 140k rows on the development machine, which is what produceddatabase is lockedunder three concurrent dispatches. Sonata cannot prune another harness's store.No streaming granularity guarantees. Progress is whatever the harness prints.
ChatGPT's Codex endpoint occasionally returns an empty completion under concurrent load instead of a 429, which LiteLLM surfaces as a 500. The router recognizes this specific case and re-emits it as 529 (overloaded) so Claude Code retries automatically instead of treating it as a hard failure.
Tier fallback retries only before a response starts. The router tries each ranked candidate in order and returns the first one that answers with status < 500; once a response starts streaming there is no mid-stream failover to the next candidate. A candidate that fails cools down for 60 seconds so a repeated request doesn't retry a model that just failed.
A conversation prefers the candidate that served its first turn. Switching models mid-conversation can hand one model's thinking blocks to another, which the API rejects — a multi-turn agent then dies mid-task on a 400. Affinity and thinking-block stripping make that survivable, not impossible.
normalis optional. A config may keep onlysimpleandcomplex, preserving its previous behaviour; addingnormalprovides the uncapped value-ranked choice.simpleis the value order capped at 12 times the best-value model's cost per task, so it leads with the best-value model whilenormalleads with the knee of the price-performance frontier.A plan's overflow is invisible. A subscription gateway's work is reported as covered and left out of
[budget]. Some plans bill usage past their allowance per token (OpenCode Go with "Use balance" on, Chutes, NanoGPT, Ollama Cloud's extra credits), and nothing in a response says which requests did — so that spend is reported covered too.auth = "session"needs a live Claude Code session. Outside that context the session credential may be unavailable, and subscription spend is estimated at Anthropic list prices — a report, not a bill.