Agent Client Protocol(ACP)¶
ai-elements-acp 将应用作为 Agent Client Protocol 客户端,类似 Zed 或 JetBrains 编辑器。Claude Code、Codex、Gemini CLI 的 ACP adapter,以及基于 ACP SDK 的 Agent(例如 Pydantic AI Harness run_acp_stdio)均可作为聊天 provider。此模块使用官方 ACP Kotlin SDK。
class CodingAgentViewModel : ViewModel() {
private val agent = AcpAgent.webSocket("wss://dev-box.example.com/acp", cwd = "/home/me/project")
// Each conversation is one ACP session; permission requests show as approvals.
val chat = ChatController(backend = { approver -> AcpBackend(agent, approver) }, scope = viewModelScope)
override fun onCleared() = agent.close()
}
连接¶
// An agent on another machine, over the ACP Kotlin SDK's WebSocket transport
AcpAgent.webSocket("wss://dev-box.example.com/acp", cwd = "/home/me/project"),
// An agent the app starts itself, over stdio (the transport the ACP spec defines)
AcpAgent.process(listOf("npx", "@zed-industries/claude-code-acp"), cwd = "/workspace"),
- stdio 是 ACP 规范定义的传输。
AcpAgent.process启动子进程,适合桌面 JVM 或能运行 Agent 的设备,例如 harness 沙箱。 - WebSocket 连接其他机器。ACP 的远程传输 Streamable HTTP 仍是草案,因此使用 Kotlin SDK 的 WebSocket 传输:每个 text frame 一条 JSON-RPC 消息,与 stdio 相同。参考服务 位于
ws://…/acp。
安全
ACP Agent 能读写其运行机器上的文件并执行命令。只连接可信 Agent;在自己的网络之外使用带认证的 wss://。
cwd 是 Agent 机器上的工作目录,按 ACP session/new 要求必须为绝对路径。同一 Agent 的会话共享连接,失败后重新连接;使用完毕时关闭 Agent。
Session¶
每个聊天会话对应一个 ACP session。ID 保存在回复 Message.metadata 的 acp 字段,下一轮只发送新用户消息,由 Agent 保持历史。应用重启等原因使 session 丢失时,若 Agent 支持则使用 session/load 恢复,否则以之前的对话为上下文新建 session。
映射¶
| ACP | 聊天中的表示 |
|---|---|
agent_message_chunk |
文本;图片映射为文件,resource link 映射为来源 |
agent_thought_chunk |
推理 |
tool_call、tool_call_update |
title 作为工具名、rawInput 作为输入;content 的文本、unified diff、terminal 或 rawOutput 作为输出;failed 为错误 |
plan |
Plan 组件 |
session/request_permission |
批准选择 allow-once,始终允许选择 allow-always,拒绝选择 reject-once |
| 停止 | session/cancel |
PromptResponse |
用量;refusal、max_tokens、max_turn_requests 以错误结束本轮 |
ACP 权限回答只携带选中的 option,因此提供批准、拒绝和始终允许,不支持理由或修改参数。见 人工参与。
提供文件¶
客户端默认不声明文件系统。传入 AcpFileSystem 可处理 fs/read_text_file,非只读时也处理 fs/write_text_file,例如访问 harness 工作区或用户分享的文件夹:
AcpAgent.webSocket(url, files = object : AcpFileSystem {
override suspend fun read(path: String, line: Int?, limit: Int?) = workspaceFile(path).readText()
})
不提供 terminal 和仍不稳定的 ACP elicitation。