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:
Binding rules and exclusivity
Binding rules and exclusivity
--bind hereand--thread ...are mutually exclusive.--bind hereonly works on channels that advertise current-conversation binding; OpenClaw returns a clear unsupported message otherwise. Bindings persist across gateway restarts.- On Discord,
spawnSessionsgates 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;/statusand/sessionalso stay local whenever command handling is enabled for that surface.
Thread-bound sessions
Thread-bound sessions
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 unbinddetaches only the current conversation and leaves the ACP session running./acp close,/acp cancel,/acp status,/status, and/sessionare Gateway commands, not prompts to the ACP harness.
acp.enabled=trueacp.dispatch.enabledis on by default (setfalseto pause automatic ACP thread dispatch; explicitsessions_spawn({ runtime: "acp" })calls still work).- Channel-adapter thread session spawns enabled (default:
true):- Discord/Telegram:
session.threadBindings.spawnSessions=true
- Discord/Telegram:
Thread-supporting channels
Thread-supporting channels
- 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-levelbindings[] 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+15555550123for direct chats and WhatsApp group JIDs such as120363424282127706@g.usfor groups. - iMessage DM/group:
match.channel="imessage"+match.peer.id="<handle|chat_id:*|chat_guid:*|chat_identifier:*>". Preferchat_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
Useagents.entries.*.runtime to define ACP defaults once per agent:
agents.entries.*.runtime.type="acp"agents.entries.*.runtime.acp.agent(harness id, e.g.codexorclaude)agents.entries.*.runtime.acp.backendagents.entries.*.runtime.acp.modeagents.entries.*.runtime.acp.cwd
bindings[].acp.*agents.entries.*.runtime.acp.*- Global ACP defaults (e.g.
acp.backend)
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,
/newand/resetreset 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.