Run an interactive chat session with a recipe. Bare sonny is this command (see Overview and global flags ).

This command starts an interactive session where you can chat with the LLM using the configured recipe. The session supports tool execution, LSP integration, and agent management.

Usage:
  sonny run [flags]

Examples

# Run with packs discovered from default locations
sonny run

# Run with one or more pack directories (repeatable)
sonny run --dir ./packs --dir <data-dir>/packs

# Run with a specific pack file
sonny run --file ./my-pack.yaml

# Run with a specific provider and model
sonny run --provider anthropic --model claude-sonnet-4-20250514

# Run in simple mode (no TUI)
sonny run --simple

Flags

FlagTypeDescription
--continue—Resume the most recent session
--control-dbstringPath to the control-plane SQLite database (default: $SONNY_CONTROL_DB, then a control.db sibling of the session DB). Only opened/migrated when the control plane is in use (this flag, $SONNY_CONTROL_DB, --mesh-self, or --mesh-addr)
--criticstringComma-separated list of critic agents to run (code_quality,security,architecture,performance,testing,documentation)
--critic-recipestringCritic recipe ID or path to a recipe YAML file (default “critic”)
--dangerously-auto-approve-tools—DANGEROUS: approve every tool call automatically, with no prompt. Denied tools stay denied and isolation is unaffected. Refused when policy forbids it
--dangerously-bypass-all—DANGEROUS: --dangerously-auto-approve-tools and --dangerously-bypass-isolation together
--dangerously-bypass-isolation—DANGEROUS: run tools on the host with no isolation realm. Refused when a trusted isolation.yaml sets minimum_mode
-d, --dirstringsdirectory containing recipe YAML files (repeatable; env: SONNY_DIR)
--eval—run critic and sentiment evaluations on conversation
--eval-modelstringmodel for evaluations (fast/cheap recommended) (default “gpt-4o-mini”)
--eval-providerstringprovider for evaluation model (default “openai”)
-f, --filestringsingle recipe YAML file to load
--headless-mcp—connect the allowlisted MCP servers from --mcp-config in a headless --prompt run without an isolation realm; refused when trusted policy forbids it, same as the interactive session
-h, --help—help for run
--hyper-client-idstringOAuth client ID for Hyperbolic (required for /login hyper)
--init-models—Write the example model-category catalog to the user config dir and exit
--isolation-assurancestringminimum assurance override: guarded, native, docker, or vm
--isolation-backendstringisolation backend override: auto, native, docker, or vm
--isolation-machinestringtrusted Docker broker configuration (default: user config isolation-docker.yaml)
--isolation-modestringisolation mode override: required, preferred, or off
--isolation-policystringtrusted isolation policy file (default: user config isolation.yaml)
--mcp-configstringPath to the MCP server config (default: the profile config directory’s mcp.yaml)
--mesh-addrstringgRPC address of the mesh node to observe (default: SONNY_MESH_ADDR env)
--mesh-peerstringsgRPC endpoint of a mesh node to show in the UI Connect dialog (repeatable)
--mesh-self—expose this chat session over an in-process mesh.Node so remote clients can attach
--mesh-self-grpcstringgRPC listen address for the in-process mesh node (--mesh-self) (default “:50052”)
--mesh-self-synapsestringsynapse listen address for the in-process mesh node (--mesh-self) (default “:50053”)
--modelsstringPath to the user model-category catalog (default: $SONNY_MODELS_FILE, then <config-dir>/models.yaml; see ‘sonny config path’)
--new—start a fresh session instead of restoring the last one
--no-tools—disable all tools for a headless completion
--no-trace—disable conversation tracing (default: on; env: SONNY_TRACE=0)
--permissions—Prompt for approval before write/exec tool calls (default off; reads always auto-allow)
--pick-recipe—force the recipe picker even when a default is set
--policy-bindingstringpath to the decision-policy binding a controller dispatched this worker with (a file path, never the binding itself)
--promptstringrun a single headless turn with this text and exit (implies --simple); used to spawn sonny as a one-shot sub-agent
--recipestringselect an already-discovered recipe by its id (skips the picker)
--recipe-dirstringDEPRECATED: alias for --dir (single dir)
--recipe-filestringDEPRECATED: alias for --file
--result-jsonstringwrite the headless turn’s result (final reply, usage, tool calls, trace ids) as JSON to this path; requires --prompt
--sessionstringResume a specific session by UUID; fails fast if id is unknown
--session-dbstringPath to the session SQLite database (default: $XDG_DATA_HOME/sonny/sessions.db)
--show-prompt—show rendered system prompt and exit
--simple—use simple chat mode (no TUI)
--supervisor-deploymentstringabsolute protected JSON deployment for durable interactive supervision (env: SONNY_SUPERVISOR_DEPLOYMENT)
--task-refstringexternal work-item reference (Jira/GitLab issue URL) governing this session
--telemetrystringpath to JSONL file for logging interactions
--trace-castringCA certificate for trace upload
--trace-certstringclient certificate for trace upload
--trace-dirstringdirectory for saving conversation traces (default: <data-dir>/traces)
--trace-keystringclient key for trace upload
--trace-serverstringtrace aggregation server address (default “localhost:50051”)
--trace-upload—enable automatic trace upload to aggregation server
--training-formatstringexport metadata-bearing training data (openai_chat, openai_tools, sharegpt, sharegpt_tool, or chatml)
--training-include-tools—include tool calls in training export
--varstringArraySet recipe variable (key=value), repeatable
--variant-constraintstringpath to the model-variant constraint packet a parent dispatched this worker with (a file path, never the packet itself)

sonny run also accepts every global flag : --analysis-json, --config, --debug, --log-format, --log-level, -m/--model, -p/--provider, --quiet-deprecations, -C/--workdir.

Dangerous modes and policy refusals

The three --dangerously-* flags are command-local to run and are refused at startup — with a non-zero exit and a message naming the file or variable that denied them — when trusted policy forbids the mode:

  • A dangerous-mode request refused by policy exits 8 (denied_policy).
  • An unreadable or malformed permissions.yaml exits 3 (config).

Denied tools stay denied under --dangerously-auto-approve-tools, and that flag does not affect isolation. --dangerously-bypass-isolation is refused specifically when a trusted isolation.yaml sets minimum_mode. --dangerously-bypass-all is the two flags together, so it is refused whenever either one would be.

Isolation is off by default; an installed isolation policy (or --isolation-mode required|preferred) turns it on. --isolation-mode off remains an explicit opt-out that overrides a preferred policy.

Headless one-shot mode

--prompt "<text>" runs a single headless turn and exits (implies --simple); this is what sonny uses internally to spawn itself as a one-shot sub-agent.

--result-json <path> writes that turn’s result document (sonny-run-result/v1) and requires --prompt. Beyond the final reply, usage, tool calls and trace ids its --help names, it records mcp_servers — every external MCP server the run declared, in declaration order, each connected (with its tool count), refused (policy) or failed (this host could not start an allowed server), with the reason in detail. Without --headless-mcp the list is present and empty, which states that the turn had no external MCP server rather than leaving it unknown.

The document is private, like the conversation trace: it is written atomically with mode 0600, a parent directory Sonny creates gets mode 0700, and a destination that already exists as a symlink or other non-regular file is refused.

Use --no-tools to disable all tools for a headless completion.

Exposing one session over mesh

--mesh-self, --mesh-self-grpc and --mesh-self-synapse expose this one chat session over an in-process mesh node so a remote client can attach to it — a lighter-weight alternative to running a full sonny mesh serve node. See sonny mesh .

--mesh-addr observes an existing node instead, and --mesh-peer adds a node endpoint to the UI Connect dialog.

Session behaviour

  • An unknown --session <uuid> fails fast: it prints an error and exits 2 rather than silently starting a new session.
  • --continue resumes the most recent session; --new starts a fresh session instead of restoring the last one.
  • --recipe-dir/--recipe-file are deprecated aliases for --dir/--file; the reference also lists --pack-dir/--pack-file as deprecated aliases for the same pair.
  • In --simple (headless REPL) mode the engine directives behave as they do in the TUI. /goal <text> records the live objective and starts work on it: the objective runs as that turn’s prompt, exactly as if it had been typed as an ordinary message, so the agent pursues it immediately instead of waiting for the next thing you type. The /goal line itself is never sent to the model. /goal bare prints the current objective, and /goal clear (or /goal off) clears it — neither starts a turn.