AI SDK 的 ACP Harness 适配器:用 `@ai-sdk/harness-acp` 统一接入任意 Agent Client Protocol 实现
AI SDK 的 ACP Harness 适配器用ai-sdk/harness-acp统一接入任意 Agent Client Protocol 实现【免费下载链接】aiThe AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and agents项目地址: https://gitcode.com/GitHub_Trending/ai/aiai-sdk/harness-acp是 AI Toolkit 中基于 Agent Client ProtocolACPv1 构建的HarnessV1适配器它作为元适配器让HarnessAgent可以连接 Codex ACP、Grok Build 等任意 ACP 兼容的 agent 实现。本文结合该包在仓库中的源码与变更记录系统讲解其桥接架构、createACP()完整配置面、模型/指令/权限/技能映射机制、会话恢复与凭证代理等核心能力帮助你把它接入自己的沙箱化 Agent 应用。为什么需要 ACP Harness 适配器ACPAgent Client Protocol是 agent 客户端与 agent 实现之间的通用通信协议。不同厂商的 agent 产品如 Codex、Grok Build都通过 ACP 暴露会话创建、消息发送、工具调用、权限请求等标准操作但底层协议细节、安装方式、模型选择方式各不相同。如果没有一层统一的适配层接入每个 agent 都要重写一遍启动、鉴权、流式解析、恢复逻辑。ai-sdk/harness-acp正是为消除这种重复而设计它对外实现 AI SDK 的HarnessV1接口对内则把HarnessAgent的调用翻译成 ACP v1 的 JSON-RPC 请求。这一点在该包 1.0.0 的变更记录中写得很清楚——introduce ACP harness adapter as a meta adapter to connect to any ACP compatible harnessCHANGELOG.md即它是一个连接任意 ACP 兼容 harness的元适配器。从包结构看createACP()是唯一的公开入口其类型签名定义在 acp-harness.ts并最终委托给createACPV1()acp-v1-harness.ts协议版本通过version字段选择当前仅支持v1传入其他值会直接抛出Unsupported ACP protocol version错误。桥接架构沙箱内的 Bridge 进程ACP 实现通常需要访问宿主机的文件系统、执行命令因此不能直接在宿主进程内运行。该适配器的架构核心是一条桥接bridge通道配置的 ACP 实现被安装在沙箱sandbox内部首次会话启动时完成安装适配器在沙箱内同时拉起一个 bridge 进程bridge.mjs负责与宿主机通信bridge 通过沙箱代理的 loopback 端口暴露一个 WebSocket 服务宿主机侧的SandboxChannel通过 WebSocket 与之双向通信ACP 实现与 bridge 并排运行在沙箱内bridge 将宿主机的HarnessAgent调用翻译为对 ACP 实现的会话操作。源码中可以看到这一启动流程doStart中先解析沙箱工作目录、确定 bridge 目录与实现目录然后通过sandboxSession.spawn执行node .../bridge.mjs --workdir ... --bridge-state-dir ... --implementation-dir ...并通过BRIDGE_CHANNEL_TOKEN与BRIDGE_WS_PORT环境变量传递桥接令牌与端口acp-v1-harness.ts。随后用waitForBridgeReady等待 bridge 就绪默认超时为 120 秒可通过startupTimeoutMs覆盖再用SandboxChannel打开 WebSocket 连接acp-v1-harness.ts。因此bridge 背书的 ACP harness 要求沙箱至少暴露一个 TCP 端口要么在创建沙箱时传入ports: [...]要么在 harness 配置中显式提供port与portEndpoint。源码resolveBridgePort与validateBasicSandboxSettings严格实施了这一约束——对于不支持getPortEndpoint的基础沙箱会话两者缺一就会抛错acp-v1-harness.ts。安装与最小接入示例在 Node.js 22 环境中安装三个包npm i ai-sdk/harness-acp ai-sdk/harness ai-sdk/sandbox-vercel下面这段来自 README.md 的示例演示如何用HarnessAgent通过 Codex ACP 直接使用 OpenAI 认证import { HarnessAgent } from ai-sdk/harness/agent; import { createACP } from ai-sdk/harness-acp; import { createCredentialRequestTransformation } from ai-sdk/harness/utils; import { createVercelSandbox } from ai-sdk/sandbox-vercel; const codexACP createACP({ harnessId: acp-codex, source: { type: npm-simple, packageName: agentclientprotocol/codex-acp, packageVersion: 1.1.4, }, executable: codex-acp, modelMapping: { type: session-config-option, path: model, }, credentialEnv: [CODEX_API_KEY, OPENAI_API_KEY], credentialBrokering: ({ env, sandboxEnv }) { const environmentVariableName env.CODEX_API_KEY ? CODEX_API_KEY : OPENAI_API_KEY; const credential env[environmentVariableName]; const sandboxCredential sandboxEnv?.[environmentVariableName]; if (!credential || !sandboxCredential) return []; return [ createCredentialRequestTransformation({ matchUrl: https://api.openai.com/v1, matchHeaders: { Authorization: Bearer ${sandboxCredential}, }, transformHeaders: { Authorization: Bearer ${credential} }, }), ]; }, instructionMapping: { type: launch-env-json, variable: CODEX_CONFIG, path: [developer_instructions], }, permissionModeMapping: { allow-reads: null, allow-edits: null, allow-all: { type: session-mode, modeId: agent-full-access }, }, authentication: { methodId: api-key, }, }); const agent new HarnessAgent({ harness: codexACP, sandbox: createVercelSandbox({ runtime: node24, ports: [4000], }), }); const session await agent.createSession(); try { const result await agent.generate({ session, prompt: Inspect this project and summarize its purpose., }); console.log(result.text); } finally { await session.destroy(); }几点实操提示同样来自 README宿主环境需要设置CODEX_API_KEY或OPENAI_API_KEY支持增量请求变换的沙箱只会收到占位凭证真正的值仅在出站请求携带预期占位符时被注入其他沙箱保留旧行为直接把值转发给 ACP 进程Codex ACP 只支持permissionMode: allow-all因为它更严格的模式会启用 Codex 内部沙箱与桥接架构冲突bridge 背书的 ACP harness 必须使用至少暴露一个端口的沙箱。完整配置面createACP()设置项详解createACP(settings)接收ACPHarnessSettings其中绝大部分字段都透传给ACPV1Settings定义见 acp-v1-settings.ts。下面按职责分组说明。实现来源source与executablesource决定 ACP 实现如何被安装支持三种类型类型说明npm-simple从 npm 安装单个包packageName必填packageVersion可选。省略版本时安装latestdist-tag且版本不参与实现身份上游发布新版本不会使既有生命周期状态失效acp-v1-settings.tsnpm-locked提供完整packageJson与pnpmLockYaml可选pnpmWorkspaceYaml安装时使用--frozen-lockfile锁定依赖implementation.tsinstall-command适用于没有 npm 包的 ACP 实现1.0.23 新增提供一条 shell 命令适配器会生成install.sh在隔离 HOME 下执行implementation.tsexecutable必须是不带路径的裸命令名正则^[A-Za-z0-9][A-Za-z0-9._-]*$校验implementation.ts。args可补充启动参数。环境与凭证转发forwardEnv按名称列表把宿主环境变量转发进沙箱进程credentialEnv声明哪些环境变量属于敏感凭证与credentialBrokering必须成对配置否则createACP直接抛错acp-harness.tscredentialBrokering({ env, sandboxEnv, headers })返回一组请求变换HarnessV1RequestTransformation让支持增量变换的沙箱只拿占位凭证、在出站请求匹配时注入真实值credentialForwarding在每个凭证值进入沙箱进程前做定制改写1.0.25 引入用于精细化控制env字面量环境变量只允许出现在 bootstrap 与生命周期兼容身份中且键名必须符合环境变量命名规则、值不能含 NULimplementation.tsforwardEnv、credentialEnv、env三者之间同一键不能重复配置否则校验失败implementation.ts。认证相关authACPAuthenticationMode即HarnessV1Authentication1.0.30 起支持从隔离环境认证会话同时移除了旧的 legacy auth 选项类型authentication{ methodId, meta?, clientCapabilities? }描述向 ACP 实现声明的认证方法resolveAuthenticationEnvironment在宿主侧解析适配器自有认证再决定转发哪些环境值给实现authenticationFiles在实现启动前把敏感文件物化到实现私有 home 目录下路径必须为相对路径、禁止穿越并统一chmod 600收紧权限acp-v1-harness.tsproviderAuthentication声明网关类认证direct或ai-gatewayai-gateway模式下支持$source引用的gateway-api-key、gateway-base-url、gateway-authorization、client-app等动态值acp-v1-settings.ts。1.0.28 的变更 harden credential brokering to only apply with correct ephemeral secret 强化了凭证代理仅在使用正确的临时密钥时才生效。模型映射modelMapping必填不同 ACP 实现的模型选择操作不同因此modelMapping是必填配置{ type: session-config-option, path }通过 ACP 标准session/setConfigOption写入path为配置项 IDCodex ACP 即用path: model{ type: session-model, path }通过非标准的session/set_model方法写入Grok Build 等实现使用path为请求属性名。源码在 model-mapping.ts 中实现了两种分支当HarnessAgent没有配置 model 时不发送任何模型操作。1.0.31 起model参数被统一提升到HarnessAgent层面addmodelparameter toHarnessAgentinstead of having each harness adapter support it on their own constructor functions1.0.32 进一步支持通过 call options 在轮次之间切换模型1.0.42 则移除了此前已废弃的 adapter settings 上的model/modelId配置。指令映射instructionMapping当 ACP 实现暴露原生 system / developer prompt 时通过instructionMapping把HarnessAgent的指令路由进去底层由ai-sdk/harness的writeInstructions助手支撑1.0.40 引入。三种形态session-meta写入 ACP 会话请求_meta字段下的指定路径launch-env-json把指令合并进某个 JSON 环境变量如示例中的CODEX_CONFIG的developer_instructions实现启动前生效filesystem把指令写成实现有效$HOME下相对路径的 markdown 文件1.0.40 新增需要文件系统型沙箱会话支持。不配置映射时适配器保留向后兼容行为把指令前置到第一条用户 promptREADME 原文说明1.0.3 曾修复过指令应追加到 system/developer prompt 而非塞进首条 user prompt的问题此后新增的instructionMapping提供了原生通道。由于 ACP 没有原生每轮更新指令的操作指令变更时会前置到下一轮用户 prompt。实现细节上session-meta与launch-env-json的路径都会经过assertSafePath检查禁止空段以及__proto__、constructor、prototype等危险属性名launch-env-json还会先校验环境变量中是合法 JSON 对象再写入instruction-mapping.ts。权限模式映射permissionModeMapping把 AI SDK 的标准权限模式映射到实现侧的具体操作{ type: session-mode, modeId }调用 ACP 会话模式切换{ type: session-config-option, configId, value }通过配置项设置null表示该权限模式不需要任何 ACP 侧操作。示例中allow-reads: null、allow-edits: null、allow-all: { type: session-mode, modeId: agent-full-access }。工具与 MCPmcpServers按服务器名组织的 MCP 服务器定义1.0.2 起支持 per-harness MCP 服务器格式为底层运行时的原生 MCP 服务器配置名字ai-sdk-harness-tools被保留给 HarnessAgent 工具占用即抛错acp-harness.tsisMcpToolCall判断某个 ACP 工具调用是否来自 MCPhostToolMcpTransport暴露宿主工具给 ACP 实现的 MCP 服务器传输方式默认stdio对只接受 HTTP/SSE MCP 服务器的实现可设为http要求实现声明agentCapabilities.mcpCapabilities.http1.0.40 引入askUserQuestionsaskUserQuestions工具的归一化支持1.0.39 引入需要提供requestMethod、fromNativeRequest、toNativeResponse等转换函数开启后自动注入HARNESS_V1_BUILTIN_TOOLS.askUserQuestions内置工具acp-harness.tsbuiltinTools扩展内置工具集outputSchemaMapping把结构化输出的 JSON Schema 映射到 ACP 会话 prompt 的_meta下1.0.11 起HarnessAgent支持output结构化输出。其他设置harnessId必须是小写 kebab-case 标识正则^[a-z0-9](?:-[a-z0-9])*$acp-v1-harness.tsport/portEndpoint覆盖沙箱暴露端口与宿主连接端点mintBridgeToken(sandboxId)可定制 bridge 令牌默认随机 32 字节十六进制1.0.2 引入createBridgeToken/withBridgeToken助手在 1.0.33 提取为公共工具session.meta附加到 ACP 会话请求的_meta字段startupTimeoutMsbridge 启动超时默认 120 秒clientApp/clientCapabilities声明客户端应用身份与能力默认ai-sdk/harness-acp 当前版本acp-harness.ts1.0.40 起HarnessAgentSettings支持通过headers属性向推理请求附带任意请求头。会话生命周期与故障恢复这是该适配器最复杂的部分变更记录中多次提到相关修复。doStart会根据传入的continueFrom/resumeFrom生命周期状态走不同的恢复路径acp-v1-harness.ts热附加attach生命周期状态中带 bridge 坐标端口、令牌、lastSeenEventId时直接通过 WebSocket 重新挂接现有 bridge若isContinue为真则先发resume再继续磁盘回放disk-replaybridge 进程丢失但事件日志完整时从磁盘event-log.ndjson重放事件1.0.38 修复了续接启动时重放 terminal 事件被丢弃的问题有损重跑lossy-rerun事件日志不可回放时用持久化的turnStartConfig ACP 会话 ID 重新执行上一轮冷恢复cold-restore非续接场景下用持久化的冷会话配置恢复 ACP 会话resume或load。acpResumeStateSchema中可以看到恢复状态携带的字段bridge、coldSession、turnStartConfig、recovery模式与原因、restorationresume/load、instructionsFingerprint、skillsDirectory等acp-harness.ts。此外 1.0.16 为会话增加了轮次中转向steering agent conversations mid-turn的实验支持以及文件系统/受限进程沙箱会话的 fallback 支持。技能Skills写入Skills 默认写入 ACP 实现有效$HOME下的.agents/skills目录常量DEFAULT_ACP_SKILLS_DIRECTORYacp-v1-skills.ts由实现原生发现需要时可把skillsDirectory改成其他相对路径如.claude/skills。1.0.29 修复了把 skills 放到 harness 原生支持目录而非手工 workaround的问题1.0.40 澄清writeSkills助手意图是必须把 skills 物化到 HOME 目录。校验方面skill 名必须是 kebab-case slug、不能重复附加文件路径必须是相对 POSIX 路径、禁止穿越SKILL.md保留给 skill 定义acp-v1-skills.ts。实现启动前会生成 implementation identity对来源、可执行文件、参数、client 身份、模型映射、环境键、权限映射等做稳定序列化后取 SHA-256用于校验生命周期状态的兼容性implementation.ts。版本演进与依赖关系从 CHANGELOG.md 可以清晰看到该包的成长脉络1.0.0以元适配器身份首次发布仅支持 ACP v11.0.1简化createACP()公共 API、延迟认证解析到会话启动、改进 bridge 错误处理防止特定错误下无限挂起1.0.2per-harness MCP 服务器、mintBridgeToken1.0.10修复finish-step事件发出时机1.0.11HarnessAgent结构化输出支持1.0.16轮次中转向实验支持、受限沙箱会话 fallback1.0.23无 npm 包的 ACP 实现走install-command来源1.0.25 允许固定 OpenCode / Grok Build 安装脚本1.0.25title与toolUseKind支持、credentialForwarding1.0.29skills 落入原生支持目录1.0.30会话可从不透传凭证的隔离环境认证1.0.31model统一上移到HarnessAgent、prepareCall()支持轮次间改设置1.0.33createBridgeToken()/withBridgeToken()助手、bridge 解析不再查找会触发 Turbopack 报错的备选路径1.0.38续接启动时保留重放的 terminal 事件1.0.39askUserQuestions工具归一化1.0.40writeInstructions助手、文件系统型instructionMapping、stopWhen相关条件修复、请求头透传、hostToolMcpTransport1.0.42移除已废弃的 adapter 级model/modelId配置1.0.43~1.0.45随ai-sdk/harness与ai-sdk/provider-utils持续跟进。依赖上该包仅依赖ai-sdk/harness、ai-sdk/provider-utils与wsWebSocket 客户端peer 依赖zod^3.25.76 或 ^4.1.8要求 Node.js 22package.json。bridge 目录自带独立的package.json与pnpm-lock.yaml构建时会原样复制进dist/bridge保证 bridge 在沙箱隔离运行时拥有最小依赖集。深入阅读包总览与接入示例packages/harness-acp/README.md公开 API 与设置类型src/index.ts、src/acp-harness.tsv1 实现会话启动、恢复、桥接src/v1/acp-v1-harness.ts设置与来源/映射类型src/v1/acp-v1-settings.ts安装与身份校验src/v1/implementation.ts桥接侧实现指令映射、模型映射、宿主工具 MCP、权限、流翻译等src/v1/bridge/变更记录packages/harness-acp/CHANGELOG.md【免费下载链接】aiThe AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and agents项目地址: https://gitcode.com/GitHub_Trending/ai/ai创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →