首页
/ OpenClaw ACPX 扩展实战:插件定位、依赖版本策略与本地验证流程全解

OpenClaw ACPX 扩展实战:插件定位、依赖版本策略与本地验证流程全解

2026-09-04 18:33:39作者:裘晴惠Vivianne

OpenClaw 的 ACPX 扩展是官方 ACP(Agent Client Protocol)运行时后端的宿主侧接入层,负责把外部编码 Agent(harness)以插件形式挂载到 Gateway。本文围绕 extensions/acpx/AGENTS.md 中沉淀的工程规范展开:先讲清这个扩展"薄封装"的设计定位,再完整继承其中的默认版本策略、未发布 ACPX 的开发流程、双 lockfile 机制、本地验证顺序与本地二进制策略,并结合 extensions/acpx/package.jsonextensions/acpx/index.tsextensions/acpx/src/config-schema.ts 等仓库源码,说明每一条规范背后的实现依据。读完后你可以独立完成 ACPX 插件的日常升级、临时接入未发布 ACPX 版本,以及在改动后按正确顺序完成验证。

定位:OpenClaw 对 acpx 包的薄封装

AGENTS.md 开宗明义:ACPX 扩展是已发布 acpx 包的"薄 OpenClaw 封装"(thin OpenClaw wrapper),可复用的 ACP 运行时逻辑应保留在上游 openclaw/acpx 仓库,而不是写进本扩展

这一"薄封装"定位在仓库中可以得到印证:

  • extensions/acpx/index.ts 是插件入口,它只做三件事:注册 Pi 会话目录(registerPiSessionCatalog)、通过 api.registerService 注册 ACPX 运行时服务(createAcpxRuntimeService)、以及把 reply_dispatch 钩子接到插件 SDK 的 tryDispatchAcpReplyHook 上并附带超时控制。真正的 ACP 协议逻辑来自 npm 依赖,而非本目录实现。
  • extensions/acpx/package.jsondependencies 明确依赖已发布的 acpx@0.13.1@agentclientprotocol/claude-agent-acp@0.70.0@agentclientprotocol/codex-acp@1.6.2smol-tomlzod。也就是说,Claude Code 与 Codex 的 ACP 适配、ACP 会话与传输管理都由上游包承担,扩展侧只维护"接线"。

因此,在动手修改这个扩展之前,先判断改动性质:

  • OpenClaw 侧的接线/配置/钩子问题 → 留在 extensions/acpx/
  • 看起来是共享 ACP 运行时行为(而非 OpenClaw 专属胶水) → 按 AGENTS.md 的边界规则(Boundary Rule),应把改动挪到 openclaw/acpx 上游仓库,在本扩展中通过消费依赖的方式使用,而不是在扩展内重新实现。

默认版本策略:永远指向已发布的 npm 版本

AGENTS.md 的默认版本策略(Default Version Policy)有三条硬性要求:

  1. extensions/acpx/package.json 默认应指向一个已发布的 npm release
  2. ACPX 正式发布后,不要把扩展停留在临时的 GitHub commit 或本地 checkout 上;
  3. 切回已发布包后,不要遗留临时的 pnpm build-script 白名单例外

对照当前仓库的实际状态,这三条策略都成立:

  • extensions/acpx/package.json"acpx": "0.13.1" 是一个确定的 npm 版本号,而非 github: 引用或 workspace 路径;
  • pnpm-workspace.yamlallowBuilds 段当前没有 acpx: true 条目——这正是策略第 3 条"清理临时白名单"在已发布版本状态下的应有结果。allowBuilds 的用途是允许指定包运行安装期的 lifecycle/build 脚本(例如 baileys: trueesbuild: true);当 ACPX 临时指向 GitHub commit 时,pnpm 可能拦截该临时包的构建脚本,需要临时加入 acpx: true 放行。

这条策略的实际价值在于:把"开发期临时 pin"与"发布态"严格区分开,避免主干上长期挂着不可复现的 commit 引用和一次性的构建放行例外。

未发布 ACPX 的临时接入流程

当 OpenClaw 需要用到尚未发布的 ACPX 变更时,AGENTS.md 给出了 8 步完整流程,这里逐步继承并结合仓库说明其用意:

  1. 先在上游 openclaw/acpx 仓库完成代码改动。 保持"逻辑在上游、接线在本扩展"的边界不变。

  2. 在 OpenClaw 侧把 extensions/acpx/package.json 临时指向所需的 ACPX GitHub commit。 即把 acpx 依赖从 npm 版本号临时改为对应 commit 的引用。

  3. 如果 pnpm 拦截该 GitHub 来源包的 ACPX lifecycle/build 脚本,临时在 pnpm-workspace.yamlallowBuilds 中加入 acpx: true 这是第 2 步的配套动作,因为 GitHub 来源的包通常不满足 pnpm 对构建脚本的信任要求。

  4. 刷新根 workspace 锁文件:

    pnpm install --lockfile-only --filter ./extensions/acpx
    

    注意 --filter ./extensions/acpx:只让该扩展参与的依赖参与解析,范围可控;--lockfile-only 表示只更新 pnpm-lock.yaml 而不落盘安装。

  5. 刷新扩展本地的 npm lock 以获得安装元数据:

    cd extensions/acpx && npm install --package-lock-only --ignore-scripts
    

    这一步生成/刷新 extensions/acpx/package-lock.json--ignore-scripts 保证刷新元数据时不会意外执行被禁用的构建脚本。

  6. 重新构建 OpenClaw 并重启 Gateway,之后才做 ACP 实时验证。 ACP 运行时行为属于 Gateway 进程内的服务,不重启不会生效。

  7. ACPX 发布后,把 extensions/acpx/package.json 切回已发布的 npm 版本,并再次刷新同样的两份 lockfile。 与第 4、5 步对应,形成"pin 与 unpin"的对称操作。

  8. 移除只为 GitHub 来源 pin 而临时添加的 acpx build-script 白名单条目。 呼应版本策略第 3 条。

这 8 步可以归纳为一个闭环:上游改代码 → 本仓库临时 pin + 放行构建 → 双 lockfile 刷新 → 重建重启验证 → 发布后回切 + 清理例外。任何一步遗漏(尤其是第 5 步和第 8 步)都会让主干留下不一致的锁文件或残留的构建放行。

Lockfile 双轨制:pnpm 工作区锁与插件本地 npm 锁

AGENTS.md 单独用一节说明了两份 lockfile 的职责分工,这也是本扩展依赖管理中最容易踩坑的地方:

文件 角色 说明
pnpm-lock.yaml(仓库根) 被 git 追踪的工作区锁文件 必须与 extensions/acpx/package.json 引用的 ACPX 版本保持一致,是 CI 与可复现安装的依据
extensions/acpx/package-lock.json 插件包本地的安装元数据 对插件包(作为 npm 包被安装时)有用;如果当前仓库状态中它被 gitignore,重新生成它对本地验证仍然有用,只是不会出现在 git status

实践含义:当你完成第 4 步的根锁刷新后,还应执行第 5 步刷新扩展本地锁,两份锁都指向同一个 ACPX 版本时,状态才算一致;只改其中一份,本地行为与安装态可能出现偏差。

本地运行时验证顺序

AGENTS.md 对 ACPX 集成改动给出的推荐验证序列是:

pnpm install --filter ./extensions/acpx   # 1. 只安装该扩展及其依赖
pnpm test:extension acpx                   # 2. 运行 acpx 扩展测试
pnpm build                                 # 3. 重新构建 OpenClaw
# 4. 若 ACP 运行时行为或 bundled plugin 接线有变化,重启本地 Gateway
# 5. 若改动影响聊天中的直接 ACP 行为,重启后跑一次真实 ACP smoke

其中 test:extension 命令在根 package.json 中定义为 node --import ./scripts/tsx.mjs scripts/test-extension.mts,传入 acpx 即只测该扩展。扩展内已有覆盖配置解析、插件注册与懒加载等行为的测试,例如 extensions/acpx/index.test.tsextensions/acpx/src/config.test.tsextensions/acpx/src/command-line.ts 对应的分词逻辑等,可作为第 2 步的具体验证内容。

顺序之所以重要:先装依赖再测,保证测的是刚 pin 的版本;测试通过后再构建,避免把坏版本带进产物;只有当改动触及 ACP 运行时行为或 bundled plugin 接线时才需要重启 Gateway——纯胶水代码改动不需要。最后一步"真实 ACP smoke"针对的是端到端链路(聊天消息 → ACP 会话 → 外部 harness 执行 → 回复分发),这是单元与集成测试无法完全替代的。

直接 ACPX 二进制策略:用插件本地二进制做验证

AGENTS.md 的 Direct ACPX Binary Policy 规定:

  • 优先使用插件本地的 ACPX 二进制,即 extensions/acpx/node_modules/.bin/acpx
  • 不要依赖全局安装的 acpx 二进制 来做 OpenClaw 的 ACP 验证;
  • 当插件本地二进制缺失或版本不对时,extensions/acpx/package.json 中 pin 的版本重新安装它。

这条策略保证验证时运行的 acpx 版本与 extensions/acpx/package.json 声明的版本(当前为 acpx@0.13.1)严格一致,排除"全局装了新版本、插件用的旧版本"这类环境偏差导致的误判。结合上文的工作区配置,pnpm 的 nodeLinker: isolatedverifyDepsBeforeRun: false(见 pnpm-workspace.yaml)意味着脚本命令不会自动校正共享安装,因此"以插件本地 node_modules/.bin/acpx 为准"是刻意为之的确定性选择。

补充:扩展的运行时配置面

AGENTS.md 本身聚焦工程流程,但要真正读懂这个扩展的"OpenClaw 侧接线",有必要了解它暴露给 Gateway 配置的参数面。这些参数由 extensions/acpx/src/config-schema.ts 中的 Zod schema(AcpxPluginConfigSchema)统一校验并补默认值,是运行时配置的单一事实来源:

配置项 类型 / 取值 默认值 说明
cwd 非空字符串 ACPX 会话的工作目录
stateDir 非空字符串 状态目录
probeAgent 非空字符串 探测用 agent
permissionMode approve-all / approve-reads / deny-all 交互工具请求的权限策略
nonInteractivePermissions deny / fail 无法向人请求批准时的策略
pluginToolsMcpBridge boolean 是否桥接插件工具到 MCP
openClawToolsMcpBridge boolean 是否桥接 OpenClaw 工具到 MCP
timeoutSeconds 数值 ≥ 0.001 120DEFAULT_ACPX_TIMEOUT_SECONDS ACPX 运行时回合的默认会话超时
piSessionCatalog.enabled boolean true 是否启用 Pi 会话目录
mcpServers Record<string, { command, args?, env? }> 自定义 MCP server 命令配置
agents Record<string, { command, args? }> 自定义 agent 命令映射

其中 timeoutSeconds 在入口处的用法值得注意:extensions/acpx/index.tsresolveReplyDispatchTimeoutMs 读取 api.pluginConfig.timeoutSeconds,仅当其为有限正数时生效,否则回落到 120 秒,再经 finiteSecondsToTimerSafeMilliseconds 换算为毫秒;reply_dispatch 钩子据此构建超时 AbortController,并与外部 ctx.abortSignal 通过 AbortSignal.any 合并(见 extensions/acpx/index.ts)。这解释了为什么验证流程强调"重启 Gateway 后再做实时验证"——这些超时与钩子是在插件 register 时求值并注册到 Gateway 进程中的。

此外,插件的构建配置(openclaw.build.staticAssets)会把 extensions/acpx/src/runtime-internals/mcp-proxy.mjsextensions/acpx/src/runtime-internals/mcp-command-line.mjs 作为静态运行时资产输出,供 ACP 进程桥接使用;mcp-command-line.mjs 的分词逻辑与 extensions/acpx/src/command-line.tssplitCommandParts 的简单引号/反斜杠规则相呼应,支持配置中的带引号命令串而无需调用 shell 解析器。

边界规则总结

把 AGENTS.md 的 Boundary Rule 与全文规范合起来看,ACPX 扩展的工程纪律可以浓缩为三句话:

  1. 逻辑归属:共享 ACP 运行时行为归 openclaw/acpx 上游,扩展内只做 OpenClaw 专属胶水;
  2. 版本一致性package.json、根 pnpm-lock.yaml、扩展本地 package-lock.json 与插件本地 .bin/acpx 二进制四处版本必须对齐,且主干默认指向已发布 npm 版本;
  3. 验证闭环pnpm install --filterpnpm test:extension acpxpnpm build → 按需重启 Gateway → 按需真实 ACP smoke,任何"pin 临时版本"操作都必须以"回切 + 清理白名单"收尾。

遵循这套流程,你可以安全地在 OpenClaw 主干上消费 ACPX 的每次演进,同时避免临时 pin、构建放行例外与不一致锁文件在仓库中残留。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
528
588
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
906
1.83 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
891
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.53 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.34 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
987
506
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384