@coder/ai-sdk-sandbox

中文文档
0.4.57发布于 2026/11/01Apache-2.0TypeScriptES Module构建来源已验证近 30 天下载 4803

Vercel AI SDK v7 HarnesAgent 的编码工作空间沙盒提供者

中文使用文档
文档目录16 节
  1. 安装
  2. 快开始
  3. 本地交通
  4. 根据需要创建工作空间
  5. 创建设置
  6. 提供无会话的工作空间
  7. 终端用户界面
  8. 工作空间要求
  9. 模板作者:零安装会话
  10. 设置
  11. 生命周期模式
  12. 港口
  13. 如何运作
  14. 限制和注释
  15. 发展
  16. 许可证

@coder/ai-sdk-sandbox (英语)

从 Vercel AI SDK v7 运行 CLI 编码代理 调用代理 真实的 编码器 工作空间而不是麻风云沙盒.

  • 执行 HarnessV1SandboxProvider 合同来源 @ai-sdk/harness数字 : 传为正 sandbox 改为 HarnessAgent完全一样 @ai-sdk/sandbox-vercel。 。 。 .
  • 克劳德代码被验证为端到端. Codex 预计将通过同一程序工作 桥架机制,但尚未在此还原中验证.

状态 : 实验 跟踪稳定的AI SDK v7 套接字(参见 页:1 @ai-sdk/harness 对应区域 package.json) (中文(简体) ).

安装

pnpm add @coder/ai-sdk-sandbox @ai-sdk/harness @ai-sdk/harness-claude-code @ai-sdk/provider-utils

选择一个主机传输 :

运输东道国要求
CoderCliTransport (默认)coder 国 际,认证 coder login,以及 OpenSSH 客户端(ssh在路径
CoderNativeTransport部署 URL 和符号 。 没有 coder 或者说 ssh 二进制. 见 本地交通

快开始

将一个已存在的、正在运行的工作空间包入其中并运行 Claude 代码 :

import { HarnessAgent } from "@ai-sdk/harness/agent";
import { createClaudeCode } from "@ai-sdk/harness-claude-code";
import { createCoderWorkspace } from "@coder/ai-sdk-sandbox";

const agent = new HarnessAgent({
  harness: createClaudeCode({ thinking: { type: "adaptive" } }),
  sandbox: createCoderWorkspace({ workspace: "my-dev-workspace" }),
  instructions: "You are a careful coding assistant.",
});

const session = await agent.createSession();
try {
  const result = await agent.generate({
    session,
    prompt: "Create a short TODO.md in the repo root.",
  });
  console.log(result.text);
} finally {
  await session.destroy();
}

可运行版本 : examples/claude-code.ts。 。 。 .

本地交通

使用 CoderNativeTransport 当主机不应该依赖于代码 CLI 或 打开SSH :

import { CoderNativeTransport, createCoderWorkspace } from "@coder/ai-sdk-sandbox";

const transport = new CoderNativeTransport({
  url: process.env.CODER_URL!,
  token: process.env.CODER_SESSION_TOKEN!,
});

const sandbox = createCoderWorkspace({
  workspace: "my-dev-workspace",
  transport,
});

// On application shutdown, close cached relay WebSockets:
await transport.close();
  • 构造器掉回 CODER_URL 财务报告和审定财务报表 CODER_SESSION_TOKEN这样 new CoderNativeTransport() 两者都准备好了就够了.
  • 符号只发送到 Coder-Session-Token 头曰. 没错 从未复制到工作区 .

根据需要创建工作空间

添加一个 create 块从模板创建工作空间(带有参数) 和(或)预设),并当会话结束时将其拆除:

const agent = new HarnessAgent({
  harness: createClaudeCode({ thinking: { type: "adaptive" } }),
  sandbox: createCoderWorkspace({
    create: {
      template: "docker", // required: the template to create from
      preset: "Large", // optional: a template version preset
      parameters: { cpus: 8, region: "us-west-2" },
      useParameterDefaults: true, // accept template defaults for the rest
      stopAfter: "8h", // auto-stop TTL
    },
  }),
});

默认这是 新鲜的每会数字 :

  • 工作空间名称来源于绳子 sessionId (例如:. agent-1a2b3c4d5e6f因此,每个会话都有自己的工作空间.
  • session.destroy() 删除它. resumeSession 重划同名并 复为后相.
  • 吊带在工作空间代理完成后运行 运行其启动脚本( e)lifecycle_state: ready) (中文(简体) ). 一个成功的 构建 实值 单靠自己是不够的.

改为: 获取或创建一个命名的工作空间组合 workspace 与 create如果 它的存在,提供者附着于它(而永远不会删除它). 如果没有的话, 供养者创造它(默认为拥有).

createCoderWorkspace({
  workspace: "my-agent-ws",
  create: { template: "docker", ifExists: "attach" }, // 'attach' (default) | 'error'
});

参数对预设 :

  • 预设参数值优先于重叠值 parameters 同名条目(Coder的行为). 通过预设设置给定值 或者说 parameters而不是两个.
  • 每个未设置的非偶数参数必须通过 parameters, (中文(简体) ), parameterFile,或一个 preset,除非 useParameterDefaults 接受其定义 模板默认.
  • 标记所需的参数没有可用的默认值,必须始终是 提供; 否则创建失败, 因为它不能提示 非交互性.
  • 如果你设置一个 preset,提供方对 模板的预设,但无法快速使用可用名称。 设定 validate: false 跳过.

创建设置

createCoderWorkspace({
  create: {
    template: "docker", // required
    templateVersion: undefined, // default: the template's active version
    preset: undefined, // 'none' forces no preset
    parameters: {}, // { name: value }; numbers/bools stringified
    parameterFile: undefined, // path to a YAML rich-parameter file
    useParameterDefaults: false, // accept template defaults where unset
    ephemeralParameters: {}, // one-time build parameters
    stopAfter: undefined, // e.g. '8h' (auto-stop TTL)
    automaticUpdates: undefined, // 'always' | 'never'
    org: undefined, // --org, for ambiguous template names
    owner: undefined, // owner for a derived name (owner/name)
    ifExists: "attach", // 'attach' | 'error'
    namePrefix: "agent", // prefix for the derived per-session name
    validate: true, // preflight-check the preset name
  },
  readyTimeoutMs: 300_000, // wait budget for the agent to become ready
});

提供无会话的工作空间

ensureCoderWorkspace(settings) 提供工作空间 其他工具 改为 约束。 它运行同样的获得或创造 ~ 如果开始 -停止 ~等待 -准备 管道作为创建模式,而不创建带状沙盒会话.

设置页:1
workspace要求明确 [owner/]workspace 名称( 没有) sessionId 以获得一个来源.
create可选;形状与以上相同(namePrefix编号 :owner 页:1 没有它,工作空间必须存在.
readyTimeoutMs, (中文(简体) ), transport, (中文(简体) ), abortSignal可选的.

停止的工作空间总是开始。 调用返回一个 EnsuredCoderWorkspace数字 :

  • 工作空间的最后(准备)状态快照;
  • created:这个电话是否创造了它;
  • id:工作空间UUID,当运输报告一个。 其他编码器 包绑在这个手柄上.

@coder/ai-sdk-agent 这是故意的 没有 a 此软件包的依赖性. 二者由平淡的串接来作曲:

import { ensureCoderWorkspace } from "@coder/ai-sdk-sandbox";
import { CoderAgent } from "@coder/ai-sdk-agent";

const ws = await ensureCoderWorkspace({
  workspace: "agent-ws",
  create: { template: "docker" },
});

const agent = new CoderAgent({
  baseUrl: process.env.CODER_URL!,
  token: process.env.CODER_SESSION_TOKEN!,
  organizationId: "<org-uuid>",
  workspaceId: ws.id!, // binds the chat's workspace-scoped tools
});

非核的主张是安全的 coder 发射的 CLIs id 内 coder list -o json旧的CLI省略它,所以小心 (单位:千美元)if (ws.id === undefined) throw …)当无法将CLI版本接上.

终端用户界面

用于交互终端聊天而不是一发 generate() 电话, 包接 代理人与 @ai-sdk/tui数字 :

pnpm add @ai-sdk/tui

TUI 驱动一个无会话的代理, 因此为 TUI 注入会话 寿命 :

import { HarnessAgent, type HarnessAgentSession } from "@ai-sdk/harness/agent";
import { createClaudeCode } from "@ai-sdk/harness-claude-code";
import { runAgentTUI, type AgentTUIAgent } from "@ai-sdk/tui";
import { createCoderWorkspace } from "@coder/ai-sdk-sandbox";

const agent = new HarnessAgent({
  harness: createClaudeCode({ thinking: { type: "adaptive" } }),
  sandbox: createCoderWorkspace({ workspace: "my-dev-ws" }),
  // or, to create a fresh workspace per session from a template:
  // sandbox: createCoderWorkspace({ create: { template: 'claude-code-test' } }),
});

const toTUIAgent = (agent: HarnessAgent, session: HarnessAgentSession): AgentTUIAgent => ({
  version: "agent-v1",
  id: agent.id,
  tools: agent.tools,
  generate: (request) => agent.generate({ ...request, session }),
  stream: (request) => agent.stream({ ...request, session }),
});

const session = await agent.createSession();
try {
  await runAgentTUI({ title: "Claude Code @ Coder", agent: toTUIAgent(agent, session) });
} finally {
  await session.destroy();
}

可运行版本 : CODER_WORKSPACE=my-dev-ws npx tsx examples/claude-code-tui.ts (单位:千美元)来源; 用 Esc 或 Ctrl+C 退出.

工作空间要求

桥通向工作空间内部,因此工作空间图像需要:

所需经费为什么
节点.js 22 登录 shell 路径桥是 node bridge.mjs,本地交通的继电器是 node -e和被钉住 @anthropic-ai/claude-code 桥梁依赖需要节点22+.
小时 在登录 shell 路径(例如)上. npm install -g pnpm(中文(简体) )适配器的靴子 pnpm install --frozen-lockfile 安装桥的依赖.
出入境 npm 登记在第一次使用时,"靴子"下载了桥的依赖性,包括克洛德代码CLI的~250MB平台二进制(被作为npm包发去). 全部跳过注册的预扣:见 模板编写。 。 。 .
出入境 型号 APIapi.anthropic.com 克劳德代码, api.openai.com 用于 Codex.
这个 模型 API 密钥 (单位:千美元)ANTHROPIC_API_KEY 编号 : OPENAI_API_KEY(中文(简体) )可用桥:通过适配器配置 auth 选项或把它放入工作空间环境.
bash 财务报告和审定财务报表 base64远程命令运行通过 bash -lc;文件 I/O是基础64-编码.
stty本地运输的接力靴子.

bash, (中文(简体) ), base64,以及 stty 是任何 Linux dev 图像上的标准.

模板作者:零安装会话

将适配器的靴子绑入工作空间映像, 从而启动会话 零运行时间安装空闲。 这个 模板编写指南 覆盖多克文件, main.tf大小 核查 经验证的一对生活在 examples/template/。 。 。 .

设置

至少其中一个 workspace 或者说 create 需要时间. 您可以同时设置 根据需要创建工作空间。 。 。 .

import {
  createCoderWorkspace,
  CoderCliTransport,
  CoderNativeTransport,
} from "@coder/ai-sdk-sandbox";

createCoderWorkspace({
  // One of these is required (TypeScript enforces it):
  workspace: "my-ws", // fixed name, or (sessionId) => `agent-${sessionId}`
  create: undefined, // create from a template; see "Creating workspaces"

  readyTimeoutMs: 300_000, // wait budget for the agent to become ready
  ports: [4000], // exposed ports; ports[0] is the bridge port
  defaultWorkingDirectory: "/home/coder", // default: resolved from $HOME, else /home/coder
  ownsLifecycle: false, // see "Lifecycle modes" below
  ensureStarted: false, // run `coder start` before attaching

  // Transport. Defaults to an ambient-login CoderCliTransport. Construct one to
  // configure it, or supply a non-CLI/test transport:
  transport: new CoderCliTransport({
    // coderBinary: 'coder', sshBinary: 'ssh',
    // url: process.env.CODER_URL, token: process.env.CODER_SESSION_TOKEN,
    // env: {}, loginShell: true, waitMode: 'no',
  }),

  // Or connect directly to Coderd with no host CLI/OpenSSH dependency:
  // transport: new CoderNativeTransport({
  //   url: process.env.CODER_URL,
  //   token: process.env.CODER_SESSION_TOKEN,
  // }),
});

生命周期模式

模式选中的行为
环绕已有的工作空间默认无 create (单位:千美元)ownsLifecycle: false(中文(简体) )stop() 财务报告和审定财务报表 destroy() 只释放主机侧资源(port-forwards);工作空间持续运行. 自然适合长生不老的工作空间.
拥有工作空间ownsLifecycle: truestop() 运行 coder stop· ; destroy() 运行 coder delete。 。 。 .
创建模式create 设定ownsLifecycle 默认为 true: 提供者创建的工作空间被删除 destroy(),以及 onFirstCreate 运行作为它的靴子钩.

创建模式安全规则 :

  • 只有提供者的工作空间 附 录 改为(明确名称, 原为 永远 删除; 只有它实际创建的 .
  • 每会场的衍生名称总是被当作拥有.
  • 设定 ownsLifecycle: false 用于“创建缺失但永远不删除”.

港口

  • 适配器将其桥从 createClaudeCode({ port }) 或者,默认情况下, sandbox.ports[0].通过 ports (默认) [4000]) (中文(简体) ).
  • getPortUrl 询问本地 TCP 前置的已配置的运输工具 返回回转 ws:// URL (中文(简体) ). CLI 运输使用 OpenSSH -L; 数据 (原始内容存档于2018-10-21) (英语). Circultive transport multers TCP sover its Coderd WebSocket.
  • 前面是回转的平话,所以 https编号 :wss 请求下决心 他们的 http编号 :ws 等同回转.

如何运作

对于桥后适配器(Claude Code, Codex), a HarnessAgent 不会跑 直接是CLI探员 它安装了小节点"桥"程序 内部 沙盒{\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}产下它 {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}和它交谈 认证的 WebSocket编辑 bridge 运行供应商 SDK 在工作空间和流事件返回主机.

这个提供商将合同映射到编码器原始器上:

合同CLI 运输本地交通
run 编号 : spawn打开SSH 结束 coder ssh --stdio通过 Coderd 代理 PTY WebSocket 的版本进程中继
readFile 编号 : writeFile 编号 : read*编号 :write*基数64 超过 SSH本地进程中继器的基数64
getPortUrl({ port, protocol })打开SSH -L中继器上的多轴 TCP 通道
createSession 编号 : resumeSession 编号 : idCLI 工作空间查询代码 v2 REST API
stop 编号 : destroycoder stop 编号 : coder delete 当生命周期拥有编码工作空间建设过渡

桥接 WebSocket 不需要通配符访问 URL: 主机运行 HarnessAgent 已经是一个代码客户端.

为什么 OpenSSH 代替 coder ssh <ws> -- cmd

coder ssh 为命令分配一个 PTY。 PTY将新行重写为 CRLF, 将 stdout 和 stderr 合并到一个流中, 不可靠地传播退出 代码:所有致命 用于程序 和桥的分解.

coder ssh自己的帮助推荐 coder config-ssh "对于需要用户 sSH的全部功能". 该提供者负责方案等同工作: 在 a 上运行真实的 OpenSSH coder ssh --stdio 代理指挥. 这样就干净了, 分离流并正确退出代码(对照活的工作空间验证).

本土接力如何保持字节清洁

Coderd的浏览器-地平线端点是一个PTY,它本身就合并了 stdout/stderr 且没有进程退出码通道. 当地交通 它只是作为载体:

  1. 它会拖住一个没有依赖性的小节点中继器.
  2. 它将 PTY 切换为生/无 Echo 模式 .
  3. 它以基数64字节有效载荷交换了新线限定帧.

中继发射命令有单独的管并打开 TCP 套接字 getPortUrl它不约束工作空间端口,也不坚持证书/文件. 每个选定的工作空间代理器都有一个中继器; transport.close() 泪下吧 下来.

为什么打开SSH -L 改为 coder port-forward

网络安全带打开 getPortUrl(...) 是关键的道路. 桥发出一个 未启动 bridge-hello wS后立即设置框架 升级。 在测试中,一个新的创造 coder port-forward 隧道没有 可靠地将第一个服务器启动的框架交付给第一个WS客户端, 而SSH本地转发则如此.

此路径被校验端到端对应真实的工作空间: 两者都是合成的 WebSocket 往返旅行( R)scripts/verify-real.ts)和完整的克洛德代码转弯 使用工具(scripts/e2e-claude.ts) (中文(简体) ).

限制和注释

  • setNetworkPolicy 未执行(接受)。 侵略受你的支配 编码器模板/部署,不是这个提供者.
  • 文件读取了整个文件的缓冲(二进制内容移动为 Base64). 罚款 拖曳大小的文件; 不用于流出非常大的文件 .
  • CoderNativeTransport 目前的目标 POSIX 工作空间 bash, (中文(简体) ), stty, (中文(简体) ), base64还有Node.js. 它的默认中继可执行文件是 node; 覆盖 relayNodeCommand 当节点生活在固定的非标准路径.
  • 必须有多个代理的工作空间 workspace.agent; 数据 本地交通拒绝猜测.
  • @ai-sdk/sandbox-just-bash 无法曝光端口并被拒绝 桥后接应器. 这个提供者的存在恰恰是为了提供该端口.
  • 要运行 Claude Code / Codex,工作空间图像必须满足 工作空间要求。 。 。 .

发展

设置和重新铺设的大门在 捐款额。 。 。 . 软件包特定命令,从 packages/sandbox数字 :

# Unit + local integration tests against fake `coder`/`ssh` executables (no deployment):
pnpm test

# End-to-end against a real workspace (needs the coder CLI + a running workspace):
pnpm verify:real my-ws

# The same contract through Coderd directly. The CLI only mints a token for
# this shell; CoderNativeTransport never invokes it:
CODER_URL=https://coder.example.com \
  CODER_SESSION_TOKEN="$(coder tokens create --name ai-sdk-sandbox)" \
  pnpm verify:native my-ws

# Create mode: creates a throwaway workspace from a template, waits for
# readiness, runs a command in it, and deletes it:
pnpm verify:create docker
当地融合测试涵盖的内容

他们进行真正的运输(辩论楼, Stdin, Base64 文件) 环行行道、溪流、港口前行生命周期和 创建/状态/预设 JSON 路径) coder编号 :ssh 可执行文件 本地运行命令. scripts/verify-real.ts 运行相同的表面,加一 真实的WebSocket -over -SSH 往返,相对实际的工作空间.

许可证

阿帕奇 - 2.0

版本与发布记录

@coder/ai-sdk-sandbox 共发布 61 个版本,首次发布于 2026/06/18;过去 12 个月发布了 61 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.4.57latest2026/11/019 天前
0.4.562026/11/019 天前
0.4.552026/10/3110 天前
0.4.542026/10/3011 天前
0.4.532026/10/3011 天前
0.4.522026/10/2912 天前

关于 @coder/ai-sdk-sandbox 的常见问题

@coder/ai-sdk-sandbox 是什么?

Vercel AI SDK v7 HarnesAgent 的编码工作空间沙盒提供者

如何安装 @coder/ai-sdk-sandbox?

在项目目录运行 npm install @coder/ai-sdk-sandbox,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@ai-sdk/harness(^1.0.0)、@ai-sdk/provider-utils(^5.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@coder/ai-sdk-sandbox 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@coder/ai-sdk-sandbox 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@coder/ai-sdk-sandbox 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@coder/ai-sdk-sandbox 可以商用吗?

@coder/ai-sdk-sandbox 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@coder/ai-sdk-sandbox 的下载量有多少?

根据 npm 官方下载统计,@coder/ai-sdk-sandbox 在 2026/10/10 – 2026/11/08 这 30 天内被下载 4,803 次,日均约 160 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@coder/ai-sdk-sandbox 还在维护吗?

最新版本 0.4.57 发布于 2026/11/01(9 天前);至今共发布 61 个版本,其中过去 12 个月发布了 61 个;首次发布于 2026/06/18。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。