Loading...
Loading...
Compare original and translation side by side
AgentACPConfigAgentAgentACPConfigAgentfs_rootag2-a2aag2-mcppermission_policy="ask"ag2-hitlfs_rootag2-a2aag2-mcppermission_policy="ask"ag2-hitlpip install "ag2[acp]"acpagent-client-protocolPATH| Agent | Adapter install | Auth |
|---|---|---|
| Claude Code | | |
| Codex | | |
| OpenCode | | |
ClaudeCodeConfig(command=["npx", "-y", "@agentclientprotocol/claude-agent-acp"])from ag2.acp import ...ACPConfigClaudeCodeConfigCodexConfigOpenCodeConfigpip install "ag2[acp]"acpagent-client-protocolPATH| 代理 | 适配器安装方式 | 认证方式 |
|---|---|---|
| Claude Code | | 环境变量 |
| Codex | | |
| OpenCode | 直接使用 | |
ClaudeCodeConfig(command=["npx", "-y", "@agentclientprotocol/claude-agent-acp"])from ag2.acp import ...ACPConfigClaudeCodeConfigCodexConfigOpenCodeConfigimport asyncio
from ag2 import Agent
from ag2.acp import ClaudeCodeConfig
async def main():
config = ClaudeCodeConfig(cwd="/path/to/repo") # workspace root
agent = Agent("coder", config=config)
try:
reply = await agent.ask("Refactor the auth module and add tests")
print(reply.body)
finally:
await config.aclose() # tear down the CLI subprocess
asyncio.run(main())ask()run()import asyncio
from ag2 import Agent
from ag2.acp import ClaudeCodeConfig
async def main():
config = ClaudeCodeConfig(cwd="/path/to/repo") # 工作区根目录
agent = Agent("coder", config=config)
try:
reply = await agent.ask("重构认证模块并添加测试用例")
print(reply.body)
finally:
await config.aclose() # 终止CLI子进程
asyncio.run(main())ask()run()ClaudeCodeConfig()claude-agent-acpANTHROPIC_MODELCodexConfig()codex-acpMODEL_PROVIDEROpenCodeConfig()opencode acpopencode.json"model": "provider/model"The presets'field is response metadata only — it is not sent to the agent. Pick the model through each adapter's own mechanism (env var / config file) as above.model
ClaudeCodeConfig()claude-agent-acpANTHROPIC_MODELCodexConfig()codex-acpMODEL_PROVIDEROpenCodeConfig()opencode acpopencode.json"model": "provider/model"预设中的字段仅作为响应元数据——不会发送给代理。请通过上述适配器自身的机制(环境变量/配置文件)选择模型。model
from ag2 import Agent
from ag2.acp import ClaudeCodeConfig
from ag2.acp.events import ACPPlan
from ag2.events import ModelMessageChunk, ModelReasoning
from ag2.events.tool_events import BuiltinToolCallEvent
agent = Agent("coder", config=ClaudeCodeConfig(cwd="/path/to/repo"))
def observe(event):
if isinstance(event, ModelReasoning):
print("thinking:", event.content)
elif isinstance(event, ModelMessageChunk):
print(event.content, end="")
elif isinstance(event, BuiltinToolCallEvent):
print(f"tool: {event.name}({event.arguments})") # arguments = JSON string of the tool input
elif isinstance(event, ACPPlan):
for step in event.entries:
print(f" [{step.status}] {step.content}")
async with agent.run("Add a healthcheck endpoint") as run:
run.stream.subscribe(observe)
reply = await run.result()| ACP update | AG2 event |
|---|---|
| agent message chunk | |
| thinking chunk | |
| tool call / tool result | |
| plan | |
| mode change | |
| available commands | |
ag2.acp.eventsag2.eventsfrom ag2 import Agent
from ag2.acp import ClaudeCodeConfig
from ag2.acp.events import ACPPlan
from ag2.events import ModelMessageChunk, ModelReasoning
from ag2.events.tool_events import BuiltinToolCallEvent
agent = Agent("coder", config=ClaudeCodeConfig(cwd="/path/to/repo"))
def observe(event):
if isinstance(event, ModelReasoning):
print("思考中:", event.content)
elif isinstance(event, ModelMessageChunk):
print(event.content, end="")
elif isinstance(event, BuiltinToolCallEvent):
print(f"工具调用: {event.name}({event.arguments})") # arguments = 工具输入的JSON字符串
elif isinstance(event, ACPPlan):
for step in event.entries:
print(f" [{step.status}] {step.content}")
async with agent.run("添加健康检查端点") as run:
run.stream.subscribe(observe)
reply = await run.result()| ACP更新 | AG2事件 |
|---|---|
| 代理消息块 | |
| 思考内容块 | |
| 工具调用/工具结果 | |
| 计划 | |
| 模式变更 | |
| 可用命令 | |
ag2.acp.eventsag2.eventspermission_policy| Policy | Behavior |
|---|---|
| Route to the agent's |
| Approve automatically (headless orchestration) |
| Reject automatically |
agent = Agent(
"coder",
config=ClaudeCodeConfig(cwd="/repo", permission_policy="auto"), # fully autonomous
)Pitfall:with no input route available (no"ask", no interactive context) denies the request — a headless run with the default policy will quietly reject every sensitive action. For unattended runs sethitl_hookexplicitly.permission_policy="auto"
permission_policy| 策略 | 行为 |
|---|---|
| 路由到代理的 |
| 自动批准(无头编排场景) |
| 自动拒绝 |
agent = Agent(
"coder",
config=ClaudeCodeConfig(cwd="/repo", permission_policy="auto"), # 完全自主运行
)注意事项:在没有可用输入路由的情况下使用(无"ask"、无交互上下文)会拒绝请求——默认策略下的无头运行会静默拒绝所有敏感操作。无人值守运行请显式设置hitl_hook。permission_policy="auto"
ACPConfig| Field | Default | Purpose |
|---|---|---|
| preset per agent | Executable + args launching the agent in ACP mode |
| | Workspace root for the session |
| | Extra env vars, merged over a trimmed base env ( |
| | Response metadata only — see "Choosing an adapter" |
| | |
| | Root for mediated |
| | Advertise the ACP terminal capability |
| | Extra workspace roots |
| | Subprocess spawn + handshake timeout (s) |
| | Per-prompt-turn timeout (s); on expiry the turn is cancelled and the reply body is whatever streamed so far |
| | Grace period (s) after a timed-out turn signals |
fs_rootconfig.copy(**overrides)ACPConfig| 字段 | 默认值 | 用途 |
|---|---|---|
| 各代理预设值 | 启动代理进入ACP模式的可执行文件+参数 |
| | 会话的工作区根目录 |
| | 额外环境变量,与精简版基础环境变量合并(包含 |
| | 仅作为响应元数据——查看「选择适配器」部分 |
| | |
| | 受管控的 |
| | 启用ACP终端功能 |
| | 额外工作区根目录 |
| | 子进程启动+握手超时时间(秒) |
| | 单轮对话超时时间(秒);超时后终止轮次,回复内容为已流式传输的部分 |
| | 超时轮次发送 |
fs_rootconfig.copy(**overrides)await config.aclose()await config.aclose()ag2.acp.testing.fake_acp_configACPConfigACPTurnsession/updateAgent.runimport asyncio
from acp import schema
from ag2 import Agent
from ag2.acp.testing import ACPTurn, fake_acp_config
def text(t):
return schema.TextContentBlock(type="text", text=t)
async def main():
config = fake_acp_config(
ACPTurn(updates=[
schema.AgentThoughtChunk(session_update="agent_thought_chunk", content=text("planning")),
schema.AgentMessageChunk(session_update="agent_message_chunk", content=text("done")),
]),
permission_policy="auto", # overrides forward to ACPConfig
)
agent = Agent("coder", config=config)
try:
reply = await agent.ask("hello")
assert reply.body == "done"
finally:
await config.aclose()
asyncio.run(main())ACPTurn(hang=True)turn_timeoutag2.acp.testing.fake_acp_configACPConfigACPTurnsession/updateAgent.runimport asyncio
from acp import schema
from ag2 import Agent
from ag2.acp.testing import ACPTurn, fake_acp_config
def text(t):
return schema.TextContentBlock(type="text", text=t)
async def main():
config = fake_acp_config(
ACPTurn(updates=[
schema.AgentThoughtChunk(session_update="agent_thought_chunk", content=text("planning")),
schema.AgentMessageChunk(session_update="agent_message_chunk", content=text("done")),
]),
permission_policy="auto", # 覆盖ACPConfig的配置
)
agent = Agent("coder", config=config)
try:
reply = await agent.ask("hello")
assert reply.body == "done"
finally:
await config.aclose()
asyncio.run(main())ACPTurn(hang=True)turn_timeoutacppip install "ag2[acp]"from ag2.acp import ...acpenv=export ANTHROPIC_API_KEY=...env={"ANTHROPIC_API_KEY": ...}CLAUDE_CONFIG_DIRHOMEclaude-code-acp@zed-industries/claude-code-acpclaude-agent-acp@agentclientprotocol/claude-agent-acpClaudeCodeConfig"ask"permission_policy="auto"model=ANTHROPIC_MODELMODEL_PROVIDERopencode.jsonPATHstartup_timeoutnpx -ytools=[...]acppip install "ag2[acp]"from ag2.acp import ...acpenv=export ANTHROPIC_API_KEY=...env={"ANTHROPIC_API_KEY": ...}CLAUDE_CONFIG_DIRHOMEclaude-code-acp@zed-industries/claude-code-acpclaude-agent-acp@agentclientprotocol/claude-agent-acpClaudeCodeConfig"ask"permission_policy="auto"model=ANTHROPIC_MODELMODEL_PROVIDERopencode.jsonPATHstartup_timeoutnpx -ytools=[...]ag2/acp/config.pyACPConfigag2/acp/client.pybridge.pysession.pyag2/acp/mappers.pyag2/acp/permissions.pypermission_policyag2/acp/events.pyACPPlanACPModeChangeACPAvailableCommandsag2/acp/testing.pyfake_acp_configACPTurnag2/acp/config.pyACPConfigag2/acp/client.pybridge.pysession.pyag2/acp/mappers.pyag2/acp/permissions.pypermission_policyag2/acp/events.pyACPPlanACPModeChangeACPAvailableCommandsag2/acp/testing.pyfake_acp_configACPTurn