☰
把acpx嵌入你的应用:acpx/runtime嵌入API与共享会话完全指南
2026/9/26 19:26:27 网站建设 项目流程

把acpx嵌入你的应用:acpx/runtime嵌入API与共享会话完全指南

【免费下载链接】acpxHeadless CLI client for stateful Agent Client Protocol (ACP) sessions项目地址: https://gitcode.com/gh_mirrors/ac/acpx

acpx不仅是命令行工具,它还是Agent Client Protocol(ACP)的无头客户端——通过acpx/runtime嵌入 API,你可以直接在 Node.js 应用里管理有状态的 AI 编码代理会话,无需启动子进程、无需解析终端输出。本指南带你掌握两种嵌入模式:进程内运行时与共享会话,让你把 Codex、Claude Code 等代理无缝接入自己的应用。

为什么选择嵌入:从"敲命令"到"调 API"

平时你用acpx codex "summarize this repository"时,其实每次都在启动进程、建立 ACP 连接。如果你的产品需要一个常驻的 AI 会话能力(IDE 插件、Web 后台、自动化编排器),每次都 spawn 进程就太慢了。

好消息是:acpx的 npm 包直接导出了运行时入口 🚀

"./runtime": "./dist/runtime.js"

安装后即可import { createAcpRuntime } from "acpx/runtime",在进程内获得完整的会话管理、权限策略、事件流和模型控制能力。

两种嵌入运行时:一张表看懂怎么选

acpx/runtime提供两套运行时,对应两种典型场景:

对比项createAcpRuntime(进程内)createSharedAcpRuntime(共享会话)
会话所有者你的应用自己持有应用与 acpx CLI共享同一个本地会话
oneshot一次性会话✅ 支持❌ 仅persistent
steer引导式回合✅ 支持❌ 仅prompt
每回合权限回调onPermissionRequest✅ 支持❌ 只能静态策略
自定义会话存储 / MCP 注入 / 子进程环境变量✅ 支持❌ 不支持
与终端 CLI 共用同一对话❌ 各自独立✅ 天然支持

💡选择口诀:会话只给你自己用 → 进程内;应用和终端要说同一句话、看同一段对话→ 共享会话。

三步跑通第一个进程内会话

进程内运行时的完整契约定义在 src/runtime/public/contract.ts,实现入口是 src/runtime.ts。核心流程只有三步:

  1. 创建运行时:指定工作目录、会话存储和权限模式
  2. 准备会话:ensureSession按sessionKey + agent复用一个持久会话
  3. 发起回合:startTurn提交提示词,消费events事件流,等待result
import { createAcpRuntime, createRuntimeStore } from "acpx/runtime"; const runtime = createAcpRuntime({ cwd: process.cwd(), sessionStore: createRuntimeStore({ stateDir: "~/.acpx" }), agentRegistry: undefined, // 使用内置代理注册表 permissionMode: "approve-reads", }); const handle = await runtime.ensureSession({ sessionKey: "reviewer", agent: "pi", mode: "persistent", }); const turn = runtime.startTurn({ handle, requestId: crypto.randomUUID(), mode: "prompt", text: "Summarize the repository", }); for await (const event of turn.events) { if (event.type === "text_delta") process.stdout.write(event.text); } console.log(await turn.result);

会话状态默认落在~/.acpx/,重启应用后同名会话可以带着上下文继续聊——这就是"有状态"的含义。

共享会话:让终端和你的应用聊同一个天

这是嵌入 API 里最惊艳的能力 ⚡createSharedAcpRuntime()让你的应用和acpxCLI 连接到同一个本地会话所有者(源码见 src/runtime/shared.ts,官方文档见 docs/shared-sessions.md):

import { createSharedAcpRuntime } from "acpx/runtime"; const runtime = createSharedAcpRuntime({ cwd: process.cwd(), permissionMode: "deny-all", }); const handle = await runtime.ensureSession({ sessionKey: "reviewer", agent: "pi", mode: "persistent", }); const turn = runtime.startTurn({ handle, requestId: crypto.randomUUID(), mode: "prompt", text: "Summarize the repository", });

创建好这个reviewer会话后,你的终端立刻就能加入同一场对话:

acpx pi -s reviewer 'Review the previous summary' acpx pi cancel -s reviewer acpx pi sessions show reviewer

应用和终端不会互相抢占连接,也不会产生两个竞争性的代理会话。几个使用要点:

  • 身份作用域:共享查找按(agentCommand, cwd, sessionKey)精确匹配,不会向父目录回溯。终端必须与你的应用使用相同的用户、主目录、工作目录和代理命令。
  • requestId 每次都要新的:重复使用正在排队的 ID 会被拒绝;它用于追踪请求,不提供幂等重试。
  • 取消语义清晰:turn.cancel()只针对当前请求,不会误伤终端正在跑的回合;runtime.cancel({ handle })则像 CLI 一样取消会话当前的活动回合。
  • 只读旁听:runtime.watchSession({ handle })可以旁观其他客户端的会话事件流,适合做实时 UI 面板。
  • shutdown 只是断开:runtime.shutdown()让客户端脱身并等待已接纳的操作收尾,不会杀掉共享所有者,也不会取消已接纳的回合。

回合生命周期:四个关键信号

无论进程内还是共享模式,startTurn返回的回合对象都由四个信号组成,理解它们就能优雅地驱动 UI:

信号含义用途
promptStarted传输层真正接受了提示词排队结束后再亮"发送中"状态
events异步事件流(text_delta、tool_call、status等)打字机渲染、工具调用面板
result回合结束,completed/cancelled/failed收尾逻辑的唯一权威信号
cancel()取消本回合(也响应你传入的AbortSignal)用户点"停止"

📌 老式写法runTurn(...)会把done/error终止事件混进事件流,属于兼容适配器;新代码建议直接用startTurn,把实时事件和最终结果分开处理。

回合失败时result会带结构化错误:code、detailCode和retryable字段,你可以据此决定提示用户还是自动重试。

权限、诊断与错误处理

嵌入时最容易踩的坑是权限。运行时支持三档静态权限模式:

  • approve-all:自动批准第一个允许项
  • approve-reads:自动批准读/搜索,其余询问
  • deny-all:尽量拒绝——CI 和无人值守场景的推荐起点

进程内模式还可以传入onPermissionRequest回调,把审批弹到你自己的 UI 里;共享模式则只接受静态策略(因为回合实际运行在所有者进程中,无法回调你的进程)。

两个实用工具:

  • runtime.doctor():返回健康报告(ok/message/installCommand),启动时自检代理是否可用,比裸试错友好得多。
  • AcpRuntimeError/isAcpRuntimeError:所有运行时错误都带稳定错误码(如ACP_BACKEND_UNAVAILABLE、ACP_TURN_FAILED),方便你写分支逻辑。

错误码全表可参考 docs/ACPX_ERROR_STRATEGY.md,CLI 侧退出码见 docs/exit-codes.md。

关键源码与文档索引

想深挖实现,按这个顺序读:

想理解什么看哪里
嵌入 API 总入口与导出src/runtime.ts
AcpRuntime契约、事件与结果类型src/runtime/public/contract.ts
进程内运行时实现(AcpxRuntime类)src/runtime.ts
共享运行时(SharedAcpRuntime)src/runtime/shared.ts
会话所有者与队列生命周期docs/sessions.md、docs/2026-02-17-architecture.md
共享会话完整语义(取消/断连/兼容)docs/shared-sessions.md
会话控制(cancel / mode / model / status)docs/session-control.md
内置代理注册表与自定义代理src/agent-registry.ts、docs/custom-agents.md
权限模型docs/permissions.md

常见疑问 FAQ

Q:共享会话和 CLI 的会话记录是同一份吗?是。sessionKey直接映射为 CLI 的会话名,查找使用精确的(agentCommand, cwd, name)作用域,应用和终端天然看到同一条记录。

Q:为什么共享模式不支持oneshot和steer?共享回合实际运行在会话所有者进程里,无法回调你的进程做交互式引导,也不能像进程内模式那样排队"旁观"活动回合——所以 API 在设计上直接拒绝这两种模式,避免隐式降级。一次性会话请用进程内运行时。

Q:findSession和ensureSession有什么区别?findSession只查本地记录,不会启动代理,适合"这个会话还开着吗?"的判断;ensureSession会按需创建或复用会话,可能拉起整个 ACP 连接。

Q:嵌入 API 稳定吗?acpx目前处于 1.0 之前,README 明确提示 CLI 与 runtime 接口仍在演进。建议锁定版本号,升级前跑一遍你的集成测试。

总结

acpx/runtime把"无头调用编码代理"从命令行脚本升级成了可编程的应用能力:

  • 🎯 进程内createAcpRuntime:完整控制——自定义存储、MCP 注入、交互权限回调、一次性会话一应俱全
  • ⚡ 共享createSharedAcpRuntime:应用与终端共用一个会话所有者,同一场对话、同一份记录、互不抢占
  • 🧭 回合四信号(promptStarted/events/result/cancel)让状态管理与取消逻辑清晰可预测

从npm install acpx开始,几十行代码就能给你的应用装上"持久 AI 会话引擎"。

【免费下载链接】acpxHeadless CLI client for stateful Agent Client Protocol (ACP) sessions项目地址: https://gitcode.com/gh_mirrors/ac/acpx

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询