One-shot runs: run -p and --json
Edit on GitHuborrery run -p "<prompt>" opens a session, takes one turn, prints the final text and exits. It is the form for scripts and CI.
orrery run -p "List the TODOs in src/ as a Markdown table"- stdout is the answer. The session id, cost and a resume command go to stderr:
session <id> · $0.0008 · 823 tokens · resume: orrery --resume <id>. - Nothing set up is an error, not a prompt: a one-shot has nobody to ask. Set a provider first, or pass
--provider. - Consent defaults to
never, so anaskrule is denied instead of hanging. Pass--consent alwaysto allow every ask. - If sub-agents were started,
runstays open until each has reported and the main agent has answered.
Attach files
orrery run -p "What does this config do?" --attach ./orrery.toml --attach ./shot.pngA text file goes into the context inline, under its name. An image goes as an image when the model reads images, and is refused otherwise. Up to 5 MB a file, 10 MB in all.
Machine-readable output
--json prints the raw AG-UI event stream on stdout, one JSON object per line. Logs never mix into it.
orrery --json run -p "hello"{"type":"RUN_STARTED","threadId":"default","runId":"01a0ba74-…","metadata":{"orrery":{"seq":1}}}
{"type":"TEXT_MESSAGE_START","messageId":"…","role":"assistant","metadata":{"orrery":{"seq":2}}}
{"type":"TEXT_MESSAGE_CONTENT","messageId":"…","delta":"hello","metadata":{"orrery":{"seq":3}}}
{"type":"TEXT_MESSAGE_END","messageId":"…","metadata":{"orrery":{"seq":4}}}
{"type":"RUN_FINISHED","threadId":"default","runId":"01a0ba74-…","result":{…},"usage":[…],"metadata":{"orrery":{"seq":5}}}Tool calls arrive as TOOL_CALL_* events, and RUN_FINISHED.result.micro_usd is the cost. A failed turn ends in RUN_ERROR instead, never followed by RUN_FINISHED (see the wire protocol). --json never prompts; run without it to answer interactively.
Exit codes
| Code | Meaning |
|---|---|
| 0 | The turn completed. |
| 1 | The turn completed, but a grader or gate said no. |
| 2 | Usage error: a flag, an argument, a missing setup. |
| 3 | A budget was exceeded. |
| 4 | Denied by policy, with no fallback. |
| 5 | A provider needs a key or a sign-in. |
| 6 | The kernel or the transport failed. |
A conversation down a pipe
Without run, when stdin or stdout is not a terminal, orrery reads one line at a time. A line is a prompt, a /command, or the answer to a question a command asked:
/model
{"intent":{"surface":"<the question's id>","value":{"choice":"ollama qwen3:4b"}}}Wait for RUN_FINISHED before sending the next line. A branch takes one turn at a time, so a second prompt sent while the first runs is refused (branch … is busy). Closing stdin ends the session cleanly once every started run has finished.
In CI
orrery --provider "$PROVIDER" --max-turns 30 --budget 2 --consent never \
--json run -p "Fix the failing test in tests/parse.rs" > events.jsonlNo paid model in your test suite? The fixture provider replays a recorded stream: --provider fixture:<file.jsonl>. Repeat the flag for several model passes, in order; the last repeats.