DataMind Oda usually runs as its own app, and it can also run from a command line. A command-line run is Oda itself, without the app window: it starts one mode, does its work, and exits or keeps serving. Use it to answer one task from a script, to serve the interface to a browser, or to let a program of yours drive Oda.
Each start names one mode with --profile:
oda --profile <name>
Oda ships five modes:
| Mode | What it serves | Details |
|---|---|---|
web | The Oda interface in a browser on this computer. | Oda in the browser |
headless | Answers one task, then exits. | This page, below |
sdk | An Oda SDK client, over standard input and output. | Automation clients |
sdk-minimal | A small standalone runtime for an SDK client. | Automation clients |
acp | An automation client that speaks the Agent Client Protocol. | Automation clients |
-h or --help after a mode name prints that mode's help and exits with code 0, without starting it, and without claiming standard input or output.The headless mode answers one task and ends on its own:
oda --profile headless "run the tests"
git diff --stat | oda --profile headless. A lone - reads standard input as well, and mixing it with words is refused.a task is required, for example: oda --profile headless "run the tests". A task of only spaces is refused too, even when text is piped in.oda: reasoning: heading, so a script can read the answer without filtering it.Name an earlier chat with --session-id and give the new task:
oda --profile headless --session-id <id> "carry on with the task"
session "<id>" does not exist; omit --session-id to start a new Session.--session-id requires a non-empty session id. Otherwise the id is passed on exactly as typed.session event carrying the chat's id (see below).Add --json to write newline-delimited events to standard output instead of the final answer:
oda --profile headless --json "run the tests"
| Event | What it carries |
|---|---|
session | Opens the stream: the chat's id and the folder the run works in. |
status | The run's phase: turn_start, step_start, step_end or turn_end. |
text | A piece of the answer, when it is committed. |
thinking | The model's reasoning, when it is committed. |
tool_call | A tool the run starts, with its arguments. |
tool_result | How a tool ended: completed or error. |
final | The run's final answer. |
error | A problem with the invocation itself, such as a bad option or a missing task. |
final, and no error event; for a script, exit code 1 and the reason on the closing turn_end are the failure signal.truncated: true, and one event line stays under 32 KiB; the final answer is not capped.The full contract of one-off runs is on Headless runs.
A run needs a model credential before it can answer. Until one resolves, model requests fail with MISSING_CREDENTIAL.
. env file in the folder you run from; a . env file in Oda's home folder. Stored credentials covers the lookup order, and Set up models and providers shows how to save a key in the app.oda plugin --profile <name> add <package> adds a package to a mode; start the mode again afterwards, because a running mode keeps the set of packages it started with.--patch <path> lays a patch file of yours over a mode.Oda profiles and launchers covers how a mode is built from its packages, and how your own settings join its layers.
Oda ships five modes, one per start: web serves the interface in a browser on this computer, headless answers one task and exits, sdk and sdk-minimal serve SDK clients, and acp serves automation clients that speak the Agent Client Protocol. Name the mode with --profile.
Start the headless mode with the task: oda --profile headless "run the tests". The answer goes to standard output, the model's reasoning goes to standard error, and the run exits on its own when the task settles.
Nothing runs. With no task and nothing piped in, the run stops with a task is required, for example: oda --profile headless "run the tests". A task of only spaces is refused too, and the run exits 1 even when text is piped in.
From a run's event stream: with --json, the opening session event carries the chat's id. Name that id with --session-id to continue the chat in a later run.
Only ones the mode can adopt, and it refuses before the task runs when it cannot: the chat must not be live in this Oda process, must not have been saved under an agent preset this mode does not run, must not be a subagent or forked chat, must have a recorded folder that matches the one you run from, and must have undamaged records and their storage available.
MISSING_CREDENTIAL?The run has no credential for the model yet. Oda looks in the environment the run starts in, then the saved credential, then a . file in the folder you run from, and last in Oda's home folder. Save the key in the app on Settings > Models, or provide it where the run looks; Stored credentials covers the order.
Usually nothing. For about 40 seconds after a restart, requests can fail while Oda retries them; if the run still failed, wait a moment and start it again.
Add --json. The run writes one event per line to standard output instead of the final answer: session, status, text, thinking, tool_call, tool_result, final, and error for problems with the invocation itself. It is a projection of the run, not the chat's full log.
Yes: oda plugin --profile <name> add <package>, then start the mode again. A running mode keeps the set of packages it started with, so the change applies from the next start. Oda profiles and launchers covers the command and how a mode is built.