ACP agents
Agent Client Protocol (ACP) 세션을 사용하면 OpenClaw가 ACP backend plugin을 통해 외부 coding harness(예: Pi, Claude Code, Codex, OpenCode, Gemini CLI)를 실행할 수 있습니다. OpenClaw에게 자연어로 “run this in Codex” 또는 “start Claude Code in a thread”라고 요청하면, OpenClaw는 그 요청을 네이티브 sub-agent runtime이 아니라 ACP runtime으로 라우팅해야 합니다.빠른 운영자 흐름
실용적인/acp runbook이 필요할 때 사용하세요.
- 세션을 spawn합니다.
/acp spawn codex --mode persistent --thread auto
- 바인딩된 스레드에서 작업합니다(또는 해당 session key를 명시적으로 지정).
- 런타임 상태를 확인합니다.
/acp status
- 필요에 따라 런타임 옵션을 조정합니다.
/acp model <provider/model>/acp permissions <profile>/acp timeout <seconds>
- 컨텍스트를 교체하지 않고 활성 세션을 살짝 유도합니다.
/acp steer tighten logging and continue
- 작업을 중단합니다.
/acp cancel(현재 turn 중단), 또는/acp close(세션 종료 + 바인딩 제거)
사람을 위한 빠른 시작
자연스러운 요청 예시:- “Start a persistent Codex session in a thread here and keep it focused.”
- “Run this as a one-shot Claude Code ACP session and summarize the result.”
- “Use Gemini CLI for this task in a thread, then keep follow-ups in that same thread.”
runtime: "acp"를 선택합니다.- 요청된 harness 대상(
agentId, 예:codex)을 해석합니다. - 스레드 바인딩이 요청되었고 현재 채널이 이를 지원하면, ACP 세션을 해당 스레드에 바인딩합니다.
- unfocus/close/expire될 때까지 이후 스레드 메시지를 동일한 ACP 세션으로 라우팅합니다.
ACP와 sub-agent 비교
외부 harness runtime이 필요하면 ACP를 사용하세요. OpenClaw 네이티브 delegated run이 필요하면 sub-agent를 사용하세요.| Area | ACP session | Sub-agent run |
|---|---|---|
| Runtime | ACP backend plugin (예: acpx) | OpenClaw 네이티브 sub-agent runtime |
| Session key | agent:<agentId>:acp:<uuid> | agent:<agentId>:subagent:<uuid> |
| Main commands | /acp ... | /subagents ... |
| Spawn tool | sessions_spawn with runtime:"acp" | sessions_spawn (default runtime) |
스레드 바운드 세션 (채널 불문)
채널 adapter에 대해 thread binding이 활성화되어 있으면 ACP 세션을 스레드에 바인딩할 수 있습니다.- OpenClaw가 스레드를 대상 ACP 세션에 바인딩합니다.
- 해당 스레드의 후속 메시지는 바인딩된 ACP 세션으로 라우팅됩니다.
- ACP 출력은 동일한 스레드로 다시 전달됩니다.
- unfocus/close/archive/idle-timeout 또는 max-age 만료 시 바인딩이 제거됩니다.
acp.enabled=trueacp.dispatch.enabled는 기본적으로 켜져 있음 (ACP dispatch를 일시 중지하려면false설정)- 채널 adapter의 ACP thread-spawn flag 활성화 (adapter별)
- Discord:
channels.discord.threadBindings.spawnAcpSessions=true - Telegram:
channels.telegram.threadBindings.spawnAcpSessions=true
- Discord:
스레드 지원 채널
- session/thread binding capability를 노출하는 모든 채널 adapter
- 현재 내장 지원:
- Discord threads/channels
- Telegram topics (groups/supergroups의 forum topic 및 DM topic)
- Plugin 채널도 동일한 binding interface를 통해 지원을 추가할 수 있습니다.
채널별 설정
비일시적 워크플로우의 경우, 최상위bindings[] 항목에 영속 ACP 바인딩을 설정하세요.
바인딩 모델
bindings[].type="acp"는 영속적인 ACP conversation binding을 표시합니다.bindings[].match는 대상 conversation을 식별합니다.- Discord channel 또는 thread:
match.channel="discord"+match.peer.id="<channelOrThreadId>" - Telegram forum topic:
match.channel="telegram"+match.peer.id="<chatId>:topic:<topicId>"
- Discord channel 또는 thread:
bindings[].agentId는 소유 OpenClaw agent id입니다.- 선택적 ACP override는
bindings[].acp아래에 둡니다.mode(persistent또는oneshot)labelcwdbackend
에이전트별 런타임 기본값
에이전트마다 ACP 기본값을 한 번만 정의하려면agents.list[].runtime을 사용하세요.
agents.list[].runtime.type="acp"agents.list[].runtime.acp.agent(harness id, 예:codex또는claude)agents.list[].runtime.acp.backendagents.list[].runtime.acp.modeagents.list[].runtime.acp.cwd
bindings[].acp.*agents.list[].runtime.acp.*- 전역 ACP 기본값 (예:
acp.backend)
- OpenClaw는 사용 전에 구성된 ACP 세션이 존재하는지 확인합니다.
- 해당 channel 또는 topic의 메시지는 구성된 ACP 세션으로 라우팅됩니다.
- 바인딩된 대화에서는
/new와/reset이 같은 ACP session key를 제자리에서 reset합니다. - 임시 런타임 바인딩(예: thread-focus 흐름에서 생성된 것)은 존재할 경우 여전히 적용됩니다.
ACP 세션 시작 (인터페이스)
sessions_spawn에서 시작
agent turn 또는 tool call에서 ACP 세션을 시작하려면 runtime: "acp"를 사용하세요.
runtime의 기본값은subagent이므로, ACP 세션에는runtime: "acp"를 명시적으로 설정하세요.agentId가 생략되면, 설정된 경우 OpenClaw는acp.defaultAgent를 사용합니다.mode: "session"은 영속적인 바인딩 대화를 유지하려면thread: true가 필요합니다.
task(필수): ACP 세션으로 전송되는 초기 프롬프트.runtime(ACP에 필수): 반드시"acp"여야 합니다.agentId(선택 사항): ACP 대상 harness id. 설정되어 있으면acp.defaultAgent로 fallback됩니다.thread(선택 사항, 기본값false): 지원되는 경우 thread binding 흐름을 요청합니다.mode(선택 사항):run(one-shot) 또는session(영속).- 기본값은
run thread: true이고 mode를 생략하면 OpenClaw는 runtime path에 따라 영속 동작을 기본값으로 삼을 수 있음mode: "session"은thread: true가 필요
- 기본값은
cwd(선택 사항): 요청된 runtime working directory (backend/runtime policy로 검증됨).label(선택 사항): session/banner 텍스트에 사용되는 운영자 표시용 label.streamTo(선택 사항):"parent"는 초기 ACP run 진행 요약을 system event로 요청자 session에 다시 스트리밍합니다.- 사용 가능한 경우, 허용된 응답에는 전체 relay 이력을 tail할 수 있는 session-scoped JSONL log(
<sessionId>.acp-stream.jsonl)를 가리키는streamLogPath가 포함됩니다.
- 사용 가능한 경우, 허용된 응답에는 전체 relay 이력을 tail할 수 있는 session-scoped JSONL log(
기존 세션 재개
resumeSessionId를 사용하면 새 ACP 세션을 시작하는 대신 이전 세션을 이어서 사용할 수 있습니다. agent는 session/load를 통해 이전 대화 이력을 다시 불러오므로, 기존 컨텍스트를 유지한 채 계속 진행할 수 있습니다.
운영자 smoke test
gateway 배포 후 ACP spawn이 단지 unit test를 통과하는 수준이 아니라 실제로 종단간 동작하는지 빠르게 확인하려면 이를 사용하세요. 권장 게이트:- 대상 호스트에서 배포된 gateway version/commit을 확인합니다.
- 배포된 소스에
src/gateway/sessions-patch.ts의 ACP lineage acceptance가 포함되어 있는지 확인합니다 (subagent:* or acp:* sessions). - 라이브 agent에 대한 임시 ACPX bridge session을 엽니다 (예:
razor(main)onjpclawhq). - 그 agent에게 다음으로
sessions_spawn을 호출하라고 요청합니다.runtime: "acp"agentId: "codex"mode: "run"- task:
Reply with exactly LIVE-ACP-SPAWN-OK
- agent가 다음을 보고하는지 검증합니다.
accepted=yes- 실제
childSessionKey - validator error 없음
- 임시 ACPX bridge session을 정리합니다.
- 스레드 바운드 영속 ACP 세션을 의도적으로 테스트하는 것이 아니라면, 이 smoke test는
mode: "run"으로 유지하세요. - 기본 게이트에서는
streamTo: "parent"를 요구하지 마세요. 이 경로는 요청자/session capability에 의존하며 별도의 통합 검사입니다. - 스레드 바운드
mode: "session"테스트는 실제 Discord thread 또는 Telegram topic에서 두 번째, 더 풍부한 통합 단계로 취급하세요.
Sandbox 호환성
ACP 세션은 현재 OpenClaw sandbox 내부가 아니라 호스트 런타임에서 실행됩니다. 현재 제한 사항:- 요청자 세션이 sandboxed 상태라면,
sessions_spawn({ runtime: "acp" })와/acp spawn모두에서 ACP spawn이 차단됩니다.- Error:
Sandboxed sessions cannot spawn ACP sessions because runtime="acp" runs on the host. Use runtime="subagent" from sandboxed sessions.
- Error:
runtime: "acp"를 사용하는sessions_spawn은sandbox: "require"를 지원하지 않습니다.- Error:
sessions_spawn sandbox="require" is unsupported for runtime="acp" because ACP sessions run outside the sandbox. Use runtime="subagent" or sandbox="inherit".
- Error:
runtime: "subagent"를 사용하세요.
/acp 명령에서 시작
채팅에서 명시적인 운영자 제어가 필요할 때는 /acp spawn을 사용하세요.
--mode persistent|oneshot--thread auto|here|off--cwd <absolute-path>--label <name>
세션 대상 해석
대부분의/acp 동작은 선택적인 세션 대상(session-key, session-id, 또는 session-label)을 받습니다.
해석 순서:
- 명시적인 대상 인수(또는
/acp steer의--session)- 먼저 key 시도
- 다음으로 UUID 형태의 session id
- 다음으로 label
- 현재 스레드 바인딩(이 대화/스레드가 ACP 세션에 바인딩된 경우)
- 현재 요청자 세션 fallback
Unable to resolve session target: ...)를 반환합니다.
Spawn 스레드 모드
/acp spawn은 --thread auto|here|off를 지원합니다.
| Mode | Behavior |
|---|---|
auto | 활성 스레드 안에서는 그 스레드를 바인딩합니다. 스레드 밖에서는 지원되는 경우 child thread를 생성/바인딩합니다. |
here | 현재 활성 스레드를 요구하며, 스레드 안이 아니면 실패합니다. |
off | 바인딩하지 않습니다. 세션은 unbound 상태로 시작합니다. |
- non-thread binding surface에서는 기본 동작이 사실상
off입니다. - 스레드 바운드 spawn에는 채널 정책 지원이 필요합니다.
- Discord:
channels.discord.threadBindings.spawnAcpSessions=true - Telegram:
channels.telegram.threadBindings.spawnAcpSessions=true
- Discord:
ACP 제어
사용 가능한 명령 계열:/acp spawn/acp cancel/acp steer/acp close/acp status/acp set-mode/acp set/acp cwd/acp permissions/acp timeout/acp model/acp reset-options/acp sessions/acp doctor/acp install
/acp status는 유효 runtime option을 보여주며, 가능할 경우 runtime 레벨과 backend 레벨의 session identifier를 모두 표시합니다.
일부 제어는 backend capability에 의존합니다. backend가 특정 제어를 지원하지 않으면, OpenClaw는 명확한 unsupported-control 오류를 반환합니다.
ACP 명령 cookbook
| Command | What it does | Example |
|---|---|---|
/acp spawn | ACP 세션 생성; 선택적으로 thread bind. | /acp spawn codex --mode persistent --thread auto --cwd /repo |
/acp cancel | 대상 세션의 진행 중 turn 취소. | /acp cancel agent:codex:acp:<uuid> |
/acp steer | 실행 중 세션에 steer instruction 전송. | /acp steer --session support inbox prioritize failing tests |
/acp close | 세션 종료 및 thread target unbind. | /acp close |
/acp status | backend, mode, state, runtime option, capability 표시. | /acp status |
/acp set-mode | 대상 세션의 runtime mode 설정. | /acp set-mode plan |
/acp set | 일반적인 runtime config option 쓰기. | /acp set model openai/gpt-5.2 |
/acp cwd | runtime working directory override 설정. | /acp cwd /Users/user/Projects/repo |
/acp permissions | approval policy profile 설정. | /acp permissions strict |
/acp timeout | runtime timeout(초) 설정. | /acp timeout 120 |
/acp model | runtime model override 설정. | /acp model anthropic/claude-opus-4-5 |
/acp reset-options | 세션 runtime option override 제거. | /acp reset-options |
/acp sessions | store에서 최근 ACP 세션 목록 표시. | /acp sessions |
/acp doctor | backend health, capability, 실행 가능한 수정안 표시. | /acp doctor |
/acp install | 결정적인 설치 및 활성화 단계 출력. | /acp install |
런타임 옵션 매핑
/acp에는 편의 명령과 일반 setter가 있습니다.
동등한 작업:
/acp model <id>는 runtime config keymodel에 매핑됩니다./acp permissions <profile>은 runtime config keyapproval_policy에 매핑됩니다./acp timeout <seconds>는 runtime config keytimeout에 매핑됩니다./acp cwd <path>는 runtime cwd override를 직접 갱신합니다./acp set <key> <value>는 일반 경로입니다.- 특수 케이스:
key=cwd는 cwd override 경로를 사용합니다.
- 특수 케이스:
/acp reset-options는 대상 세션의 모든 runtime override를 지웁니다.
acpx harness 지원 (현재)
현재 acpx 내장 harness alias:piclaudecodexopencodegeminikimi
agentId로 이 값들을 우선 사용하세요.
직접 acpx CLI를 사용할 때는 --agent <command>를 통해 임의 adapter를 대상으로 지정할 수도 있지만, 이 raw escape hatch는 acpx CLI 기능이지 일반적인 OpenClaw agentId 경로는 아닙니다.
필요한 설정
Core ACP 기본선:- Discord:
channels.discord.threadBindings.spawnAcpSessions=true
acpx backend용 plugin 설정
plugin을 설치하고 활성화합니다.acpx command 및 version 설정
기본적으로@openclaw/acpx로 배포되는 acpx plugin은 plugin-local pinned binary를 사용합니다.
- command의 기본값은
extensions/acpx/node_modules/.bin/acpx입니다. - 예상 version의 기본값은 extension pin입니다.
- startup은 ACP backend를 즉시 not-ready 상태로 등록합니다.
- 백그라운드 ensure job이
acpx --version을 검증합니다. - plugin-local binary가 없거나 일치하지 않으면 다음을 실행합니다.
npm install --omit=dev --no-save acpx@<pinned>후 다시 검증합니다.
command는 절대 경로, 상대 경로, 또는 명령 이름(acpx)을 받을 수 있습니다.- 상대 경로는 OpenClaw workspace directory 기준으로 해석됩니다.
expectedVersion: "any"는 엄격한 version 일치를 비활성화합니다.command가 커스텀 binary/path를 가리키면 plugin-local auto-install은 비활성화됩니다.- backend health check가 실행되는 동안 OpenClaw startup은 비차단 상태를 유지합니다.
권한 설정
ACP 세션은 비대화형으로 실행됩니다. 파일 쓰기 및 shell 실행 permission prompt를 승인하거나 거부할 TTY가 없습니다. acpx plugin은 권한 처리 방식을 제어하는 두 개의 config key를 제공합니다.permissionMode
prompt 없이 harness agent가 수행할 수 있는 작업을 제어합니다.
| Value | Behavior |
|---|---|
approve-all | 모든 파일 쓰기와 shell command를 자동 승인합니다. |
approve-reads | 읽기만 자동 승인하고, 쓰기와 exec는 prompt가 필요합니다. |
deny-all | 모든 permission prompt를 거부합니다. |
nonInteractivePermissions
permission prompt가 표시되어야 하지만 대화형 TTY를 사용할 수 없을 때(ACP 세션에서는 항상 해당) 어떻게 할지 제어합니다.
| Value | Behavior |
|---|---|
fail | AcpRuntimeError와 함께 세션을 중단합니다. (기본값) |
deny | permission을 조용히 거부하고 계속 진행합니다 (graceful degradation). |
설정
plugin config를 통해 설정합니다.중요: OpenClaw는 현재 기본값으로permissionMode=approve-reads와nonInteractivePermissions=fail을 사용합니다. 비대화형 ACP 세션에서는 permission prompt를 유발하는 모든 write 또는 exec가AcpRuntimeError: Permission prompt unavailable in non-interactive mode와 함께 실패할 수 있습니다. 권한을 제한해야 한다면, 세션이 크래시하는 대신 graceful degradation되도록nonInteractivePermissions를deny로 설정하세요.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
ACP runtime backend is not configured | Backend plugin이 없거나 비활성화됨. | backend plugin을 설치하고 활성화한 다음 /acp doctor를 실행하세요. |
ACP is disabled by policy (acp.enabled=false) | ACP가 전역적으로 비활성화됨. | acp.enabled=true를 설정하세요. |
ACP dispatch is disabled by policy (acp.dispatch.enabled=false) | 일반 스레드 메시지에서의 dispatch가 비활성화됨. | acp.dispatch.enabled=true를 설정하세요. |
ACP agent "<id>" is not allowed by policy | agent가 allowlist에 없음. | 허용된 agentId를 사용하거나 acp.allowedAgents를 업데이트하세요. |
Unable to resolve session target: ... | 잘못된 key/id/label token. | /acp sessions를 실행해 정확한 key/label을 복사한 뒤 다시 시도하세요. |
--thread here requires running /acp spawn inside an active ... thread | --thread here를 스레드 컨텍스트 밖에서 사용함. | 대상 스레드로 이동하거나 --thread auto/off를 사용하세요. |
Only <user-id> can rebind this thread. | 다른 사용자가 thread binding을 소유하고 있음. | 소유자로 다시 bind하거나 다른 스레드를 사용하세요. |
Thread bindings are unavailable for <channel>. | adapter에 thread binding capability가 없음. | --thread off를 사용하거나 지원되는 adapter/channel로 이동하세요. |
Sandboxed sessions cannot spawn ACP sessions ... | ACP runtime은 host 측에서 실행되고, 요청자 세션은 sandboxed 상태임. | sandboxed 세션에서는 runtime="subagent"를 사용하거나, sandbox되지 않은 세션에서 ACP spawn을 실행하세요. |
sessions_spawn sandbox="require" is unsupported for runtime="acp" ... | ACP runtime에 대해 sandbox="require"를 요청함. | 필수 sandboxing에는 runtime="subagent"를 사용하거나, sandbox되지 않은 세션에서 ACP와 sandbox="inherit"를 사용하세요. |
| Missing ACP metadata for bound session | 오래되었거나 삭제된 ACP session metadata. | /acp spawn으로 다시 생성한 뒤 스레드를 다시 bind/focus하세요. |
AcpRuntimeError: Permission prompt unavailable in non-interactive mode | permissionMode가 비대화형 ACP 세션에서 write/exec를 차단함. | plugins.entries.acpx.config.permissionMode를 approve-all로 설정하고 gateway를 재시작하세요. Permission configuration 참고. |
| ACP session fails early with little output | permission prompt가 permissionMode/nonInteractivePermissions에 막힘. | AcpRuntimeError가 있는지 gateway log를 확인하세요. 전체 권한이 필요하면 permissionMode=approve-all, graceful degradation이 필요하면 nonInteractivePermissions=deny를 설정하세요. |
| ACP session stalls indefinitely after completing work | harness process는 끝났지만 ACP session이 완료를 보고하지 않음. | ps aux | grep acpx로 모니터링하고, 오래된 프로세스를 수동으로 종료하세요. |