Delivery model
ACP sessions can be either interactive workspaces or parent-owned background work. The delivery path depends on that shape.Interactive ACP sessions
Interactive ACP sessions
Interactive sessions are meant to keep talking on a visible chat surface:
/acp spawn ... --bind herebinds the current conversation to the ACP session./acp spawn ... --thread ...binds a channel thread/topic to the ACP session.- Persistent configured
bindings[].type="acp"route matching conversations to the same ACP session.
- Normal bound follow-ups are sent as prompt text, plus attachments only when the harness/backend supports them.
/acpmanagement commands and local Gateway commands are intercepted before ACP dispatch.- Runtime-generated completion events are materialized per target. OpenClaw agents get OpenClaw’s internal runtime-context envelope; external ACP harnesses get a plain prompt with the child result and instruction. The raw
<<<BEGIN_OPENCLAW_INTERNAL_CONTEXT>>>envelope should never be sent to external harnesses or persisted as ACP user transcript text. - ACP transcript entries use the user-visible trigger text or the plain completion prompt. Internal event metadata stays structured in OpenClaw where possible and is not treated as user-authored chat content.
Parent-owned one-shot ACP sessions
Parent-owned one-shot ACP sessions
One-shot ACP sessions spawned by another agent run are background
children, similar to sub-agents:
- The parent asks for work with
sessions_spawn({ runtime: "acp", mode: "run" }). - The child runs in its own ACP harness session.
- Child turns run on the same background lane used by native sub-agent spawns, so a slow ACP harness does not block unrelated main-session work.
- Completion reports back through the task-completion announce path. OpenClaw converts internal completion metadata into a plain ACP prompt before sending it to an external harness, so harnesses do not see OpenClaw-only runtime context markers.
- The parent rewrites the child result in normal assistant voice when a user-facing reply is useful.
sessions_send and A2A delivery
sessions_send and A2A delivery
sessions_send can target another session after spawn. For normal peer
sessions, OpenClaw uses an agent-to-agent (A2A) follow-up path after
injecting the message:- Wait for the target session’s reply.
- Optionally let requester and target exchange a bounded number of follow-up turns.
- Ask the target to produce an announce message.
- Deliver that announce to the visible channel or thread.
tools.sessions.visibility
settings.OpenClaw skips the A2A follow-up only when the requester is the parent of
its own parent-owned one-shot ACP child. In that case, running A2A on top
of task completion can wake the parent with the child’s result, forward
the parent’s reply back into the child, and create a parent/child echo
loop. Accepted sessions_send results report target admission separately
from announcement delivery: targetDisposition is queued or steered,
while delivery.status is pending or skipped. For this owned-child case,
delivery.status="skipped" because the completion path is already responsible
for the result.Resume an existing session
Resume an existing session
Use Common use cases:
resumeSessionId to continue a previous ACP session instead of
starting fresh. The agent replays its conversation history via
session/load, so it picks up with full context of what came before.- Hand off a Codex session from your laptop to your phone - tell your agent to pick up where you left off.
- Continue a coding session you started interactively in the CLI, now headlessly through your agent.
- Pick up work that was interrupted by a gateway restart or idle timeout.
resumeSessionIdonly applies whenruntime: "acp"; the default sub-agent runtime ignores this ACP-only field.streamToonly applies whenruntime: "acp"; the default sub-agent runtime ignores this ACP-only field.resumeSessionIdis a host-local ACP/harness resume id, not an OpenClaw channel session key; OpenClaw still checks ACP spawn policy and target agent policy before dispatch, while the ACP backend or harness owns authorization for loading that upstream id.resumeSessionIdrestores the upstream ACP conversation history;threadandmodestill apply normally to the new OpenClaw session you are creating, somode: "session"still requiresthread: true.- The target agent must support
session/load(Codex and Claude Code do). - If the session id is not found, the spawn fails with a clear error - no silent fallback to a new session.
Post-deploy smoke test
Post-deploy smoke test
After a gateway deploy, run a live end-to-end check rather than trusting
unit tests:
- Verify the deployed gateway version and commit on the target host.
- Open a temporary ACPX bridge session to a live agent.
- Ask that agent to call
sessions_spawnwithruntime: "acp",agentId: "codex",mode: "run", and taskReply with exactly LIVE-ACP-SPAWN-OK. - Verify
accepted=yes, a realchildSessionKey, and no validator error. - Clean up the temporary bridge session.
mode: "run" and skip streamTo: "parent" -
thread-bound mode: "session" and stream-relay paths are separate richer
integration passes.Sandbox compatibility
ACP sessions currently run on the host runtime, not inside the OpenClaw sandbox. Current limitations:- If the requester session is sandboxed, ACP spawns are blocked for both
sessions_spawn({ runtime: "acp" })and/acp spawn. sessions_spawnwithruntime: "acp"does not supportsandbox: "require".