Start it

omp --mode rpc --no-session       # headless: events out, commands in
omp --mode rpc-ui --no-session    # adds tool-card / selector UI frames

On startup omp writes {"type":"ready"}, then reads one JSON object per line on stdin and writes one per line on stdout. Mode flags are documented alongside every other CLI option on the CLI reference. Pass --no-session to keep the run out of ~/.omp/agent/sessions/; omit it to persist and later resume, fork, or branch through the same channels you’d use interactively (Sessions).

--mode rpc is fully headless. --mode rpc-ui layers the TUI’s interactive surfaces on top of the same wire: tool-execution cards, selectors, permission prompts arrive as extension_ui_request frames the embedder MUST answer with a matching extension_ui_response.

Message shape

Every command may carry an id; the matching response echoes it back with {"type":"response","command":"…","success":bool}. prompt and abort_and_prompt ack immediately — the turn itself streams as agent_start, message_update, tool_execution_*, and finishes with agent_end.

Commands

| Command | Payload | Returns | | -------------------------------------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------- | ---------- | --------------------------------------------------- | | prompt | message, images? | ack; streams agent_start → deltas → agent_end | | steer | message, images? | ack; inserted into the running turn | | follow_up | message, images? | ack; queued after the current turn | | abort | — | ack; the active turn ends with agent_end | | abort_and_prompt | message, images? | ack; aborts then starts a new turn | | new_session / switch_session / branch | session targets | session-tree transitions | | handoff | customInstructions? | { savedPath } \\ | null | | get_state / get_messages / get_session_stats | — | session snapshot | | set_model / cycle_model / set_thinking_level | model selectors | set_model / cycle_model return the selected model; thinking changes emit a thinking_level_changed event | | compact / set_auto_compaction | compaction controls | ack / CompactionResult | | bash / abort_bash | command | BashResult | | set_host_tools | tools: RpcHostToolDefinition[] | host-side tools surface as host_tool_call frames; reply with host_tool_result | | extension_ui_response | id, value \\ | confirmed \\ | cancelled | answers a previously emitted extension_ui_request | | get_login_providers / login | provider id | OAuth URLs arrive as extension_ui_request with method: "open_url" | | export_html | outputPath? | { path } |

Event stream

  • message_update — assistant output. assistantMessageEvent.type selects between text_delta, thinking_delta, tool_call_start, tool_call_delta, and tool_result.

  • message_start / message_end — message boundaries inside a turn.

  • tool_execution_start / _update / _end — tool lifecycle; carry toolCallId, toolName, and intent labell.

  • agent_start / agent_end — turn boundaries. agent_end carries the stop reason a single prompt waits on.

  • auto_compaction_start / _end, auto_retry_start / _end — mid-stream housekeeping.

  • available_commands_update — the current slash-command surface; emitted once at startup and again whenever command metadata changes. Session-tree transitions (new_session / switch_session / branch) are observed through their command responses.

  • extension_ui_request — the agent needs UI: a selector, a confirm, an input, or an OAuth URL. Reply with extension_ui_response using the same id. Tool-execution cards and permission prompts only arrive under --mode rpc-ui.

Shell example

One prompt in, text deltas out, exit on agent_end. No language binding required.

#!/usr/bin/env bash
set -euo pipefail
prompt='Say "ok" and nothing else.'
jq -nc --arg m "$prompt" '{id:"s1",type:"prompt",message:$m}' \
  | omp --mode rpc --no-session \
  | while IFS= read -r line; do
      t=$(jq -r '.type' <<<"$line")
      [["$t" == "message_update"]] && \
        jq -r '.assistantMessageEvent.delta // empty' <<<"$line"
      [["$t" == "agent_end"]] && exit 0
    done

JSON event stream mode

--mode json is the print-mode variant of the same wire. It accepts a prompt from argv (or -p), writes the same event objects to stdout, then exits. Use it for CI captures, golden-file tests, or piping into the HTML exporter without keeping a subprocess alive.

omp --mode json --no-session "Audit src/ for unused exports" > run.jsonl
omp --export run.jsonl audit.html

Same framing, same event types, same renderer. The difference is purely lifecycle: --mode rpc is a long-running pipe you keep feeding; --mode json is one prompt, one stream, exit.\n

Ask Docs

AI assistant to help answer questions about the documentation. Answers are read-only and cite docs/source.

Hi! How can I help you with the documentation today? Answers are read-only and cite docs/source.

Ctrl+Enter to send