Skip to main content

Bound sessions

Mental model

  • Chat surface - where people keep talking (Discord channel, Telegram topic, iMessage chat).
  • ACP session - the durable Codex/Claude/Gemini runtime state OpenClaw routes to.
  • Child thread/topic - an optional extra messaging surface created only by --thread ....
  • Runtime workspace - the filesystem location (cwd, repo checkout, backend workspace) where the harness runs. Independent of the chat surface.

Current-conversation binds

/acp spawn <harness> --bind here pins the current conversation to the spawned ACP session - no child thread, same chat surface. OpenClaw keeps owning transport, auth, safety, and delivery. Follow-up messages in that conversation route to the same session; /new and /reset reset the session in place; /acp close removes the binding. Examples:
  • --bind here and --thread ... are mutually exclusive.
  • --bind here only works on channels that advertise current-conversation binding; OpenClaw returns a clear unsupported message otherwise. Bindings persist across gateway restarts.
  • On Discord, spawnSessions gates child thread creation for --thread auto|here - not --bind here.
  • If you spawn to a different ACP agent without --cwd, OpenClaw inherits the target agent’s workspace by default. Missing inherited paths (ENOENT/ENOTDIR) fall back to the backend default; other access errors (e.g. EACCES) surface as spawn errors.
  • Gateway management commands stay local in bound conversations - /acp ... commands are handled by OpenClaw even when normal follow-up text routes to the bound ACP session; /status and /session also stay local whenever command handling is enabled for that surface.
When thread bindings are enabled for a channel adapter:
  • OpenClaw binds a thread to a target ACP session.
  • Follow-up messages in that thread route to the bound ACP session.
  • ACP output is delivered back to the same thread.
  • /session unbind, close, archive, idle timeout, or max-age expiry removes the binding. /session unbind detaches only the current conversation and leaves the ACP session running.
  • /acp close, /acp cancel, /acp status, /status, and /session are Gateway commands, not prompts to the ACP harness.
Required feature flags for thread-bound ACP:
  • acp.enabled=true
  • acp.dispatch.enabled is on by default (set false to pause automatic ACP thread dispatch; explicit sessions_spawn({ runtime: "acp" }) calls still work).
  • Channel-adapter thread session spawns enabled (default: true):
    • Discord/Telegram: session.threadBindings.spawnSessions=true
Thread binding support is adapter-specific. If the active channel adapter does not support thread bindings, OpenClaw returns a clear unsupported/unavailable message.
  • Any channel adapter that exposes session/thread binding capability.
  • Current built-in support: Discord threads/channels, Telegram topics (forum topics in groups/supergroups and DM topics).
  • Plugin channels can add support through the same binding interface.

Persistent channel bindings

For non-ephemeral workflows, configure persistent ACP bindings in top-level bindings[] entries.

Binding model

"acp"
Marks a persistent ACP conversation binding.
object
Identifies the target conversation. Per-channel shapes:
  • Discord channel/thread: match.channel="discord" + match.peer.id="<channelOrThreadId>"
  • Slack channel/DM: match.channel="slack" + match.peer.id="<channelId|channel:<channelId>|#<channelId>|userId|user:<userId>|slack:<userId>|<@userId>>". Prefer stable Slack ids; channel bindings also match replies inside that channel’s threads.
  • Telegram forum topic: match.channel="telegram" + match.peer.id="<chatId>:topic:<topicId>"
  • WhatsApp DM/group: match.channel="whatsapp" + match.peer.id="<E.164|group JID>". Use E.164 numbers such as +15555550123 for direct chats and WhatsApp group JIDs such as 120363424282127706@g.us for groups.
  • iMessage DM/group: match.channel="imessage" + match.peer.id="<handle|chat_id:*|chat_guid:*|chat_identifier:*>". Prefer chat_id:* for stable group bindings.
string
The owning OpenClaw agent id.
"persistent" | "oneshot"
Optional ACP override.
string
Optional operator-facing label.
string
Optional runtime working directory.
string
Optional backend override.

Runtime defaults per agent

Use agents.entries.*.runtime to define ACP defaults once per agent:
  • agents.entries.*.runtime.type="acp"
  • agents.entries.*.runtime.acp.agent (harness id, e.g. codex or claude)
  • agents.entries.*.runtime.acp.backend
  • agents.entries.*.runtime.acp.mode
  • agents.entries.*.runtime.acp.cwd
Override precedence for ACP bound sessions:
  1. bindings[].acp.*
  2. agents.entries.*.runtime.acp.*
  3. Global ACP defaults (e.g. acp.backend)
Configured bindings also forward the owning agent’s explicit model and thinking policy. Thinking uses the agent’s thinkingDefault, then per-model agents.defaults.models["provider/model"].params.thinking, then agents.defaults.thinkingDefault. Without configured policy, the external harness keeps its own defaults. Changing a configured model or thinking value updates the existing session before its next turn without replacing the conversation. Each option is saved only after the harness accepts it; a rejected option returns an error and keeps that option’s previous selection. Model and thinking changes are independent, not an atomic batch. Removing a default uses any remaining configured policy; if none remains, OpenClaw retains the session’s last selection. Omission is not a backend reset. To change thinking explicitly, use /acp set thinking <level> with a level supported by the harness. For Codex ACP, off only omits a fresh session’s startup override. Switching an existing session to off is unsupported and returns an error without clearing its current reasoning effort or conversation.

Example

Behavior

  • OpenClaw ensures the configured ACP session exists after channel-specific admission and before use.
  • Messages in that channel, topic, or chat route to the configured ACP session.
  • Configured ACP bindings own their session route. Channel broadcast fan-out does not replace the configured ACP session for a matched binding.
  • In bound conversations, /new and /reset reset the same ACP session key in place.
  • Runtime bindings created by thread-bound spawns still apply where present.
  • For cross-agent ACP spawns without an explicit cwd, OpenClaw inherits the target agent workspace from agent config.
  • Missing inherited workspace paths fall back to the backend default cwd; non-missing access failures surface as spawn errors.