< 返回我的博客

Bigfish 发表于 2026-10-14 23:51

架构

Zed  ──ACP (JSON-RPC over stdio)──▶  rpi --acp  ──spawn──▶  rpi --mode rpc  (每会话一个)

rpi-acp 是个 cdylib 扩展,做三件事:抢 stdio、说 ACP v1、给每个会话挂一个 rpi --mode rpc 子进程。桥接层自己不跑模型——tools、models、auth、skills 全在子进程里,所以行为跟终端里跑 rpi 完全一致。

关键机制:抢夺 stdio

宿主默认会 drain stdin,扩展就拿不到 stdio,ACP server 无从谈起。解法:带 --acp 时,扩展在注册阶段声明 {"ownsStdio": true},宿主随即停止 drain,改走 StdioLifecycle,把 stdin/stdout 交给扩展。

从终端直接跑 --acp 会快速失败(一条消息 + exit 2),而不是空转。要注册用 rpi --install-zed。

事件映射

rpi RPC 事件 ACP update
text_delta / thinking_delta agent_message_chunk / agent_thought_chunk
tool_execution_start tool_call(edit/write 带 diff)
tool_execution_update / _end tool_call_update
plan_mode_complete plan
outcome aborted / completed stopReason: cancelled / end_turn

流式文本用累积快照 + finalText 去重,不重发已发过的 chunk。

会话持久化

稳定 UUID,原生 JSONL 历史落在 ~/.rpi/agent/acp/sessions(可用 RPI_ACP_SESSION_DIR 覆盖),进程退出后仍在。session/load 恢复并重放,session/resume 恢复但不重放。未知会话返回错误,不静默开空对话。

权限与问题扩展

  • 权限:插件弹窗(如 bash 确认)映射成标准 session/request_permission,用户选择回传插件。默认带 --permission-gate。
  • 问题:ACP v1 没有通用多选方法,于是双方在 initialize 里用 _meta: {"pi-rust/questions": 1} 协商。只有广告了 v1 的客户端才收到 _rpi/request_question;超时默认 300s,配套 _rpi/dialog_closed 通知回收 UI。

安装配置

rpi install rpi-acp    # 或 task install

Zed settings.json:

{ "agent_servers": { "rpi": { "type": "custom", "command": "rpi", "args": ["--acp"] } } }

args 可透传普通 flag,如 ["--acp", "--model", "gateway/model"]。--acp 会自动注册到 Zed(幂等、原子写、保留 JSONC 注释);设 RPI_ACP_NO_AUTO_REGISTER_ZED=1 可关掉。

独立二进制 rpi-acp-bridge

同样的 server 也能编成独立二进制,原生拥有 stdin/stdout,不需要 ownsStdio,可直接对着 stock rpi 跑。找 agent 的顺序:RPI_BIN → 自身 → 兄弟文件 → PATH。

cargo build --release -p rpi-acp --bin rpi-acp-bridge
task pack-acp   # 打包进 ACP Registry

相关链接

评论区

写评论

还没有评论

1 共 0 条评论, 1 页