add-harness-package
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAdding a New Harness Package
新增 Harness 包
This guide covers creating a new package for an agent harness.
@ai-sdk/harness-<name>A harness can be host-driven, where the runtime runs in the host process and uses the sandbox remotely, or bridge-backed, where a small bridge runs inside the sandbox because the runtime needs local access to the sandbox filesystem or process environment.
Prefer host-driven when the runtime supports it.
本指南介绍如何为 Agent Harness 创建全新的 包。
@ai-sdk/harness-<name>Harness 可分为宿主驱动型(host-driven)和桥接支撑型(bridge-backed):前者的运行时运行在宿主进程中,远程调用沙箱;后者则在沙箱内部运行一个小型桥接程序,因为运行时需要本地访问沙箱的文件系统或进程环境。若运行时支持,优先选择宿主驱动型。
First-Party vs Third-Party Harnesses
官方 Harness 与第三方 Harness
- Third-party packages: Any runtime can publish an external harness package.
- First-party packages: Create an issue first to discuss whether the runtime belongs in this repo.
@ai-sdk/harness-<name>
- 第三方包:任何运行时都可以发布外部 Harness 包。
- 官方 包:请先创建 Issue 讨论该运行时是否适合纳入本仓库。
@ai-sdk/harness-<name>
Reference Example
参考示例
See https://github.com/vercel/ai/pull/16255/changes for a complete example of adding a new harness.
新增 Harness 的完整示例可参考:https://github.com/vercel/ai/pull/16255/changes
Harness Architecture
Harness 架构
The AI SDK uses a layered harness architecture following the adapter pattern:
- Harness specification (): Defines interfaces like
@ai-sdk/harnessandHarnessV1HarnessV1Session - Utilities (): Shared code for implementing harnesses
@ai-sdk/harness/utils - Harness implementations (): Concrete adapters for harnesses
@ai-sdk/harness-<name> - Harness agent (): The high-level user-facing
@ai-sdk/harness/agentAPIHarnessAgent
AI SDK 采用遵循适配器模式的分层 Harness 架构:
- Harness 规范():定义
@ai-sdk/harness、HarnessV1等接口HarnessV1Session - 工具库():实现 Harness 所需的共享代码
@ai-sdk/harness/utils - Harness 实现():具体的 Harness 适配器
@ai-sdk/harness-<name> - Harness Agent():面向用户的高层
@ai-sdk/harness/agentAPIHarnessAgent
Step-by-Step Guide
分步指南
1. Create Package Structure
1. 创建包结构
Create with this baseline structure:
packages/harness-<name>packages/harness-<name>/
├── src/
│ ├── index.ts
│ ├── <name>-harness.ts
│ ├── <name>-harness.test.ts
│ └── <name>-auth.ts # if the runtime needs auth resolution
├── package.json
├── tsconfig.json
├── tsconfig.build.json
├── tsup.config.ts
├── turbo.json
├── vitest.node.config.js
└── README.mdIf the runtime must execute inside the sandbox, add bridge files as well:
src/
├── <name>-bridge-protocol.ts
├── <name>-bridge-protocol.test.ts
└── bridge/
├── index.ts
├── package.json
└── pnpm-lock.yamlAdd a containing just the package heading (). Every package is required to have one.
CHANGELOG.md# @ai-sdk/harness-<name>创建 目录,基础结构如下:
packages/harness-<name>packages/harness-<name>/
├── src/
│ ├── index.ts
│ ├── <name>-harness.ts
│ ├── <name>-harness.test.ts
│ └── <name>-auth.ts # if the runtime needs auth resolution
├── package.json
├── tsconfig.json
├── tsconfig.build.json
├── tsup.config.ts
├── turbo.json
├── vitest.node.config.js
└── README.md如果运行时必须在沙箱内执行,还需添加桥接文件:
src/
├── <name>-bridge-protocol.ts
├── <name>-bridge-protocol.test.ts
└── bridge/
├── index.ts
├── package.json
└── pnpm-lock.yaml添加 文件,内容仅需包含包标题()。所有包都必须有该文件。
CHANGELOG.md# @ai-sdk/harness-<name>2. Configure package.json
2. 配置 package.json
Use existing harness packages as the source of truth for scripts, exports, repository metadata, and publish settings.
Required package basics:
"name": "@ai-sdk/harness-<name>""type": "module"- (starting point for new packages)
"version": "0.0.0" "license": "Apache-2.0""sideEffects": false- dependency on via
@ai-sdk/harnessworkspace:* - dependency on via
@ai-sdk/provider-utilswhen using sandbox/auth/schema utilitiesworkspace:* - runtime SDK/CLI dependencies required by the harness
- dev dependencies matching existing harness packages
"engines": { "node": ">=22" }
For bridge packages, add any bridge asset copy step required for files under .
src/bridge/Bridge dependency rules (bridge-backed harnesses):
- The bridge's runtime deps live in (installed in-sandbox at bootstrap), not the main package.json. After changing them, regenerate
src/bridge/package.jsonwithsrc/bridge/pnpm-lock.yaml(runnable from the repo root).pnpm --dir packages/harness-<name>/src/bridge install --lockfile-only --ignore-workspace - For every third-party import in , keep three things in sync: the import, the
src/bridge/array inexternal, and the dep intsup.config.ts. A missing entry shows up only at sandbox runtime as a module-resolution error.src/bridge/package.json - Include packages the runtime lazily imports — e.g. provider SDKs (,
@anthropic-ai/sdk) resolved from the model id at runtime — even though nothing imports them directly. These fail only when a model of that provider is actually used.openai - Match shared dependency versions (transport, schema, tooling, runtime SDKs) to what the other harness packages currently use — copy from a sibling package rather than choosing your own pins. Stale pins drift from security patches and can desync from the shared bridge runtime; check the current versions at creation time.
脚本、导出配置、仓库元数据和发布设置请以现有 Harness 包为标准参考。
包的基础必填项:
"name": "@ai-sdk/harness-<name>""type": "module"- (新包的起始版本)
"version": "0.0.0" "license": "Apache-2.0""sideEffects": false- 通过 依赖
workspace:*@ai-sdk/harness - 若使用沙箱/认证/Schema 工具,需通过 依赖
workspace:*@ai-sdk/provider-utils - Harness 所需的运行时 SDK/CLI 依赖
- 与现有 Harness 包一致的开发依赖
"engines": { "node": ">=22" }
对于桥接型包,需添加 目录下文件的桥接资源复制步骤。
src/bridge/桥接依赖规则(桥接支撑型 Harness):
- 桥接的运行时依赖放在 中(启动时在沙箱内安装),而非主 package.json。修改依赖后,需执行
src/bridge/package.json重新生成pnpm --dir packages/harness-<name>/src/bridge install --lockfile-only --ignore-workspace(可在仓库根目录执行)。src/bridge/pnpm-lock.yaml - 对于 中的每一个第三方导入,需同步维护三处内容:导入语句、
src/bridge/中的tsup.config.ts数组,以及external中的依赖。缺少对应条目只会在沙箱运行时表现为模块解析错误。src/bridge/package.json - 需包含运行时懒加载的包——例如根据模型 ID 在运行时解析的提供商 SDK(、
@anthropic-ai/sdk)——即使没有直接导入它们。这些包只有在实际使用对应提供商的模型时才会报错。openai - 共享依赖(传输、Schema、工具、运行时 SDK)的版本需与其他 Harness 包当前使用的版本一致——直接从同级包复制版本号,不要自行指定。过时的版本会错过安全补丁,还可能与共享桥接运行时不同步;创建时请确认当前最新版本。
3. Create TypeScript, Build, and Test Configs
3. 创建 TypeScript、构建和测试配置
Copy the nearest existing harness package config files and adjust paths/package names:
tsconfig.jsontsconfig.build.jsontsup.config.tsturbo.jsonvitest.node.config.js
Harness packages currently use Node tests only unless the implementation has a specific reason to add another runtime.
复制最相近的现有 Harness 包的配置文件,并调整路径/包名:
tsconfig.jsontsconfig.build.jsontsup.config.tsturbo.jsonvitest.node.config.js
目前 Harness 包仅使用 Node 测试,除非实现有特殊需求才需要添加其他运行时。
4. Implement the Harness Adapter
4. 实现 Harness 适配器
Export a factory from and re-export it from .
<name>-harness.tssrc/index.tsUse the architecture doc for contract details. At implementation time, verify:
- return a with
HarnessV1;specificationVersion: 'harness-v1' - use a stable kebab-case ;
harnessId - expose adapter-native built-in tools through ;
builtinTools - keep construction synchronous and side-effect free;
- use and
startOpts.sandboxSession; never create a separate sandbox;startOpts.sessionWorkDir - throw from the method that needs an unsupported runtime capability;
HarnessCapabilityUnsupportedError - don't hardcode a default model unless the runtime technically requires one — some underlying SDKs have no default of their own. Otherwise pass the model only when the consumer configured one and leave the original SDK's default untouched; keep the session's consistent with what's actually sent (don't report a model the bridge silently overrode);
modelId - handle the and
toolsthatinstructions/doPromptTurnmay receive: if the runtime can't take customdoContinueTurn, throwtoolsso it's obvious rather than silently dropped; if it has no nativeHarnessCapabilityUnsupportedErrorinput, prepend them to the first user message (the Codex/Claude Code workaround);instructions - quote interpolated paths (, bridge-state dir, …) when building shell commands for
workDir/sandbox.run— they can contain spaces.sandbox.spawn
If the runtime needs in-sandbox setup, expose .
getBootstrap()在 中导出工厂函数,并在 中重新导出。
<name>-harness.tssrc/index.ts契约细节请参考架构文档。实现时需确认以下事项:
- 返回的 需带有
HarnessV1;specificationVersion: 'harness-v1' - 使用稳定的 kebab-case 格式 ;
harnessId - 通过 暴露适配器原生的内置工具;
builtinTools - 构造过程保持同步且无副作用;
- 使用 和
startOpts.sandboxSession;切勿创建独立的沙箱;startOpts.sessionWorkDir - 若方法需要运行时不支持的能力,需抛出 ;
HarnessCapabilityUnsupportedError - 不要硬编码默认模型,除非运行时技术上要求——部分底层 SDK 本身没有默认模型。否则仅在使用者配置了模型时传入,保留原 SDK 的默认行为;保持会话的 与实际发送的内容一致(不要上报被桥接程序静默覆盖的模型);
modelId - 处理 /
doPromptTurn可能收到的doContinueTurn和tools:如果运行时不支持自定义instructions,抛出tools,这样问题会很明显,而不是被静默丢弃;如果运行时没有原生的HarnessCapabilityUnsupportedError输入,将其拼接到第一条用户消息前面(Codex/Claude Code 的变通方案);instructions - 在为 /
sandbox.run构建 shell 命令时,对插值路径(sandbox.spawn、桥接状态目录等)加引号——路径可能包含空格。workDir
如果运行时需要在沙箱内进行初始化,暴露 方法。
getBootstrap()5. Implement Runtime-Specific Concerns
5. 实现运行时特定逻辑
Add only the concerns the runtime needs:
- auth resolution — for AI Gateway support, use the central helper rather than reading env directly. This ensures both
getAiGatewayAuthFromEnv()andVERCEL_OIDC_TOKENare accepted as Gateway credential. When the runtime resolves provider per model, resolve the provider from the model id and set that provider's env; if routing through the gateway, note that base-URL conventions differ per provider (e.g. an Anthropic client appendsAI_GATEWAY_API_KEYto a root base, an OpenAI client appends to a/v1/messagesbase);/v1 - AI Gateway client attribution — follow the convention in existing harness packages: define a versioned client app value such as and use it for Gateway requests. Configure both
ai-sdk/harness-<name>/${VERSION}andUser-Agentheaders when the underlying runtime/SDK supports both; at least one of those two headers is required. If the runtime cannot set arbitrary headers directly, use the runtime-supported equivalent that produces one of those headers (e.g. an SDK client-app environment variable);x-client-app - custom-tool schema translation — if you convert host tools' JSON Schema into the runtime's tool format, convert recursively (nested objects, array , enums, descriptions); a flat top-level-only conversion silently drops the model's structured guidance. Passing the JSON Schema through directly, if the runtime accepts it, avoids the problem;
items - skill or discovery-file materialization;
- native protocol to harness stream/control translation;
- lifecycle state schema;
- bridge protocol and diagnostics.
Certain structural conventions for harness adapters are being enforced via the CLI.
Run once you're done to check for those. Fix any violations flagged before proceeding.
konsistentpnpm konsistent仅添加运行时需要的逻辑:
- 认证解析——如需支持 AI Gateway,请使用中央 辅助函数,而非直接读取环境变量。这样可确保
getAiGatewayAuthFromEnv()和VERCEL_OIDC_TOKEN都能作为 Gateway 凭证被接受。当运行时按模型解析提供商时,从模型 ID 解析提供商,并设置对应提供商的环境变量;如果通过 Gateway 路由,请注意不同提供商的 base URL 约定不同(例如 Anthropic 客户端会在根 base URL 后追加AI_GATEWAY_API_KEY,而 OpenAI 客户端会追加到/v1/messages基础路径后);/v1 - AI Gateway 客户端标识——遵循现有 Harness 包的约定:定义带版本的客户端应用值,例如 ,并用于 Gateway 请求。如果底层运行时/SDK 支持,同时配置
ai-sdk/harness-<name>/${VERSION}和User-Agent头;至少需要配置其中一个。如果运行时无法直接设置任意请求头,请使用运行时支持的等效方式来生成其中一个头(例如 SDK 的客户端应用环境变量);x-client-app - 自定义工具 Schema 转换——如果你需要将宿主工具的 JSON Schema 转换为运行时的工具格式,请递归转换(嵌套对象、数组 、枚举、描述);仅做顶层的扁平转换会静默丢失模型的结构化引导信息。如果运行时支持直接传入 JSON Schema,直接透传即可避免该问题;
items - Skill 或发现文件的物化;
- 原生协议到 Harness 流/控制的转换;
- 生命周期状态 Schema;
- 桥接协议与诊断信息。
Harness 适配器的部分结构约定通过 CLI 强制校验。完成实现后运行 检查,修复所有标记的违规项后再继续。
konsistentpnpm konsistent6. Write Tests
6. 编写测试
Add focused Node tests for:
- factory metadata and settings;
- auth resolution;
- sandbox usage and path placement;
- host-driven remote operations or bridge protocol behavior;
- prompt/control event translation;
- resume session vs continue turn behavior;
- unsupported capability errors;
- skill materialization, if supported.
Use mocked sandbox sessions and bridge/runtime boundaries where possible. Do not require live provider credentials in unit tests.
getBootstrap()dist/bridge/index.mjssrcENOENTnode:fs/promisesreadFile添加针对性的 Node 测试,覆盖以下场景:
- 工厂元数据与设置;
- 认证解析;
- 沙箱使用与路径放置;
- 宿主驱动型远程操作或桥接协议行为;
- 提示/控制事件转换;
- 恢复会话 vs 继续轮次的行为;
- 不支持能力的错误;
- Skill 物化(如支持)。
尽可能使用模拟的沙箱会话和桥接/运行时边界。单元测试不需要真实的提供商凭证。
getBootstrap()dist/bridge/index.mjssrcENOENTnode:fs/promisesreadFile7. Add README
7. 添加 README
Keep README short:
- package purpose;
- setup command;
- minimal usage;
HarnessAgent - required sandbox capabilities, such as ports for bridge-backed runtimes;
- notable auth configuration.
Link to the main harness docs for broader concepts.
README 保持简洁:
- 包的用途;
- 安装命令;
- 最简 使用示例;
HarnessAgent - 所需的沙箱能力,例如桥接支撑型运行时需要的端口;
- 重要的认证配置。
更广泛的概念请链接到 Harness 主文档。
8. Add Examples
8. 添加示例
Add relevant examples for the new harness.
- Add API/function examples under when the harness package needs a scriptable provider-behavior example.
examples/ai-functions - Add interactive examples mirroring the existing harness examples in (Next.js) and
examples/harness-e2e-next(TUI).examples/harness-e2e-tui
为新 Harness 添加相关示例。
- 当 Harness 包需要可脚本化的提供商行为示例时,在 下添加 API/函数示例。
examples/ai-functions - 在 (Next.js)和
examples/harness-e2e-next(TUI)中添加与现有 Harness 示例对应的交互式示例。examples/harness-e2e-tui
9. Add Documentation
9. 添加文档
Create documentation in .
content/providers/02-ai-sdk-harnesses/<next number>-<name>.mdxInclude:
- Setup instructions
- Required sandbox capabilities
- Authentication configuration
- Harness-specific options
- Usage examples
- Known limitations
Update to list the new harness when it is ready to be public.
content/docs/03-ai-sdk-harnesses/05-harness-adapters.mdx在 中创建文档。
content/providers/02-ai-sdk-harnesses/<next number>-<name>.mdx包含内容:
- 安装说明
- 所需沙箱能力
- 认证配置
- Harness 特定选项
- 使用示例
- 已知限制
当新 Harness 准备好公开发布时,更新 ,将其加入列表。
content/docs/03-ai-sdk-harnesses/05-harness-adapters.mdx10. Update References and Validate
10. 更新引用并验证
Run from the workspace root:
bash
pnpm konsistent
pnpm update-references
pnpm --filter @ai-sdk/harness-<name> build
pnpm --filter @ai-sdk/harness-<name> test
pnpm type-check:fullAdd a changeset with . For a brand-new harness package's first release, use (not the usual ), matching the other harness packages.
pnpm changesetmajorpatchRun relevant harness examples against a live sandbox early — don't rely on unit tests and alone. Runtime API constraints (e.g. unexpected config-option rejections, the exact streaming event names the runtime emits, gateway base-URL format) surface only when the bridge actually drives the runtime, and they're far cheaper to find before the docs/examples are built on top.
type-check在工作区根目录执行:
bash
pnpm konsistent
pnpm update-references
pnpm --filter @ai-sdk/harness-<name> build
pnpm --filter @ai-sdk/harness-<name> test
pnpm type-check:full使用 添加变更集。全新 Harness 包的首次发布请使用 版本(而非通常的 ),与其他 Harness 包保持一致。
pnpm changesetmajorpatch尽早在真实沙箱上运行相关 Harness 示例——不要仅依赖单元测试和 。运行时 API 的限制(例如意外的配置选项拒绝、运行时发出的具体流事件名称、Gateway base URL 格式)只有在桥接程序实际驱动运行时时才会显现,在文档/示例构建完成前发现这些问题成本要低得多。
type-checkChecklist
检查清单
- Package structure created in
packages/harness-<name> - configured with correct dependencies
package.json - TypeScript configs set up (,
tsconfig.json)tsconfig.build.json - Build configuration ()
tsup.config.ts - Test configuration ()
vitest.node.config.js - Harness adapter implementation complete
- Runtime placement handled without creating a hidden sandbox
- Bridge assets copied during build, if bridge-backed
- Auth resolution implemented, if needed
- AI Gateway requests include and/or
User-Agentclient attributionx-client-app - Harness infra, skills, bridge code, and secrets kept out of
sessionWorkDir - Session resume and turn continuation tested
- Unit tests written and passing
- README.md written
- added (package heading; required by
CHANGELOG.md)konsistent - Changeset added (for a first release)
major - Examples added
- Documentation added in
content/providers/02-ai-sdk-harnesses/ - Harness adapter list updated, if public
- Validated against a live sandbox (not just unit tests / type-check)
- run
pnpm update-references - Package build passing
- Package tests passing
- Type checking passing (from root)
pnpm type-check:full - Relevant examples run successfully
- 已在 中创建包结构
packages/harness-<name> - 已配置正确的依赖
package.json - TypeScript 配置已设置(、
tsconfig.json)tsconfig.build.json - 构建配置()
tsup.config.ts - 测试配置()
vitest.node.config.js - Harness 适配器实现完成
- 运行时放置处理正确,未创建隐藏沙箱
- 如为桥接支撑型,构建时会复制桥接资源
- 已实现认证解析(如需要)
- AI Gateway 请求包含 和/或
User-Agent客户端标识x-client-app - Harness 基础设施、Skill、桥接代码和密钥未放入
sessionWorkDir - 会话恢复和轮次续跑已测试
- 单元测试已编写且通过
- README.md 已编写
- 已添加 (包标题;
CHANGELOG.md强制要求)konsistent - 已添加变更集(首次发布使用 )
major - 已添加示例
- 已在 中添加文档
content/providers/02-ai-sdk-harnesses/ - 如公开,已更新 Harness 适配器列表
- 已在真实沙箱上验证(而非仅单元测试/类型检查)
- 已运行
pnpm update-references - 包构建通过
- 包测试通过
- 类型检查通过(根目录执行 )
pnpm type-check:full - 相关示例运行成功
Related Documentation
相关文档
- Harness Abstraction Architecture
- README
@ai-sdk/harness - Existing harness packages with similar runtime placement
- Harness 抽象架构
- README
@ai-sdk/harness - 运行时放置方式相似的现有 Harness 包