Session Orchestration
Wait for session state and coordinate governed child sessions through CLI, HTTP, UDS, and native tools.
CompozyOS exposes session orchestration through the CLI, matching HTTP/UDS routes, and scoped native tools. Use these surfaces to wait on state, spawn bounded children, resolve their interactions, cancel one prompt, or stop a session without polling the catalog.
Wait for state
compozy session wait returns when a session reaches any requested state:
compozy session wait sess_1234 \
--until waiting-for-input,waiting-for-auth,stopped,failed \
--timeout 2m \
-o jsonWhen --until is omitted, the target set is waiting-for-input, waiting-for-auth, idle,
stopped, and failed. done satisfies idle. Explicit targets may also include done, running,
hung, unhealthy, and needs-attention. Include needs-attention when an unverified stop should wake the caller for a retry.
The default timeout is 5 minutes. --unbounded keeps the CLI waiting through gapless, bounded server
requests; the daemon never holds an unbounded HTTP/UDS request. Structured outcomes are
state-reached, timeout, session-gone, canceled, and overflow.
| Outcome or error | CLI exit |
|---|---|
| State reached | 0 |
| Invalid target | 65 |
| Session unavailable | 69 |
| Timeout | 75 |
HTTP and UDS use
POST /api/workspaces/{workspace_id}/sessions/{session_id}/wait with required timeout_ms from 1
through 1,800,000. A timeout is a normal result; a deleted or replaced session returns 410.
Cancel an active prompt
Cancel the prompt without stopping the session:
compozy session prompt-cancel sess_1234 -o jsonThe result is canceled with its turn_id, or nothing-in-flight. Repeating the command is safe and
uses the same cancellation path as
POST /api/workspaces/{workspace_id}/sessions/{session_id}/prompt/cancel and the native tool. The CLI
exits 0 after a cancel and 66 when there was nothing to cancel.
Messages between sessions
Agents use compozy__session_prompt to address another session. Supply session_id, message_id,
idempotency_key, and the message or attachments. Choose mode: "queue", "steer", or
"interrupt" when the target is busy. Retry with the same message and idempotency IDs.
CompozyOS stamps an immutable origin from the calling agent session. Queue and event responses
include kind: "session", session_id, workspace_id, hop, and optional agent_name,
title_at_send, notify_on_complete, and reply_watch_id. The origin survives all delivery modes
and daemon restarts. It cannot be supplied through a request body. CLI, HTTP and operator prompts
remain unattributed operator input.
The receiving provider sees a one-line sender header followed by the message. The header does not
become stored message text. Without a reply watch, it tells the recipient to answer by calling
compozy__session_prompt with the sender's session ID. Set notify_on_complete: true to request the
reply-watch flow from an agent session. Changing that flag on a retry conflicts, as does retrying
another sender's message identity. A sender rename preserves the original admission.
An operator can cancel an agent-authored queued message, but cannot replace or promote its text.
Those mutations return HTTP 409 input_agent_authored. Each message increases the active turn's
highest accepted hop; steer also raises that value before provider delivery. A ninth hop returns
message_hop_limit: ask the operator to continue in a fresh turn.
Native self-targeting returns invalid_request. To continue work in the same session, end the turn;
to schedule work, use a subagent or compozy session prompt from the operator. This approved
compatibility exception applies immediately. Existing v4 admission receipts still replay without
origin or a new reply watch; their boundary compatibility shim is scheduled for removal in v0.5.0.
The message tool's existing cross-workspace reach is unchanged. Origin includes the sender's workspace so readers can resolve that session correctly.
Governed child feedback
compozy spawn creates a child with a required TTL, lineage, capacity limits, and permissions that
cannot exceed its parent. By default, CompozyOS queues a sanitized synthetic turn on the parent when
the child completes a turn, stops, fails, or enters a needs-you state. A canceled child turn sends no
completed wake. The wake never interrupts an active parent prompt.
To hand one task to another agent, provider, or model from inside a turn and get the answer back without managing a child yourself, use subagents instead.
compozy spawn --agent researcher --ttl-seconds 3600
compozy spawn --agent researcher --ttl-seconds 3600 --no-notify-creator
compozy spawn --agent researcher --ttl-seconds 3600 \
--provider codex --model gpt-5.6-sol --reasoning-effort high --speed fastnotify_creator defaults to true on HTTP, UDS, and compozy__session_spawn. Set it explicitly to
false to opt out for one child. This default has no config.toml key.
Provider, model, reasoning effort, and speed are optional child-runtime overrides on the CLI, HTTP/UDS request, and native tool. Omit them to use the named agent and workspace defaults.
Native orchestration tools
Resolve each live descriptor with compozy__tool_info before calling it. All targets are restricted
to the caller's workspace, and a session cannot target itself.
| Tool | Purpose |
|---|---|
compozy__session_wait | Wait up to 30 minutes for a badge or lifecycle state. |
compozy__session_spawn | Create a governed child with a required TTL and narrowed permissions. |
compozy__session_stop | Stop another session; destructive approval policy applies. |
compozy__session_approve | Resolve another session's pending permission request. |
compozy__session_clarify_answer | Answer another session's pending clarification by choice or text. |
compozy__session_prompt_cancel | Cancel another session's active prompt without stopping the session. |
Approval and clarification resolution survive daemon restart. A successful orphaned resolution
returns resolved-after-restart; a race may return already-resolved, and a full durable input queue
returns queue-full without consuming the pending interaction.
Related pages
- Safe Spawn covers child constraints and cleanup.
- Delegate to subagents covers one-call delegation with a wake on completion.
- Session Lifecycle covers durable session and runtime state.
- Session Wait CLI lists the generated flags.
- Prompt Cancel CLI lists the generated command contract.
Ask another session for a reply
An agent can call compozy__session_prompt with notify_on_complete: true to receive a reply from an
existing session. The tool returns reply_watch: { id, state }, using its current persisted state
(armed, fired, delivered, or abandoned). Retrying the same message and idempotency key after a
pre-dispatch failure re-arms the same watch. The sender can then finish its turn;
CompozyOS delivers one synthetic reply wake after the turn that consumed the message settles.
Queued messages retain their watches across a target stop. A busy sender receives the wake after its
current turn.
Waiting is long-running work, not silence. While the asked session is live, the sender's open watch
counts as an awaiting_reply work signal, so inactivity supervision does not stop an orchestrator
that is waiting for an answer, however long the target works. If the sender was stopped anyway (the
target stopped with the message queued and the sender went quiet, a daemon restart, or an agent
crash), the reply resumes the sender and delivers the wake once. A sender you stopped yourself
stays stopped and receives the wake when you resume it.
compozy__session_status, the session status HTTP response, and compozy session status <id> -o json
include reply_watches while they are armed or fired. Each item identifies the watch, target
session, message, state, and creation time. The human CLI shows a Waiting for replies section.
Delivered and abandoned watches disappear from this list.
Replies contain the last non-empty assistant message of the consuming turn, bounded to 12000 Unicode
characters. Truncated replies include a pointer to compozy__session_history; empty replies use
(no reply text). Outcomes are completed, failed (with an error summary), canceled, dropped
(removed before execution), or unknown (delivery was uncertain; inspect the target session).
Archiving or deleting the sender abandons its outstanding watches. Canceling or clearing a reply wake
from the sender's queue does not send it again. notify_on_complete belongs to the agent-facing native
tool; HTTP operator prompts have no equivalent option. Operator-scoped native calls with this
option return invalid_request: notify_on_complete requires an agent session. Archiving or deleting
an unconsumed target settles its outstanding watches as unknown without waiting for a restart.