@cogitator-ai/sandbox

中文文档
0.10.4发布于 2026/10/29MITTypeScriptES Module近 30 天下载 9221

用于 Cogitator 代理的 Sandbox 执行( Docker, WASM, 以及 E2B, Daytona 和 Vercel Sandbox 上的远程工作空间)

中文使用文档
文档目录38 节
  1. 安装
  2. 快速启动
  3. 特征
  4. 沙盒管理器
  5. 倒置和初始化
  6. 找到 Docker 守护进程
  7. 可用性检查
  8. 关闭
  9. Docker 执行器
  10. 安全特性
  11. 集装箱池
  12. 集合选项
  13. 嵌入工作空间
  14. 远程工作空间
  15. WASM 执行器
  16. OS 沙盒
  17. 原生执行器
  18. 执行请求
  19. 取消执行
  20. 执行结果
  21. 资源限制
  22. 内存
  23. CPU 软件
  24. 进程限制
  25. 网络配置
  26. 音量山数
  27. 工具函数
  28. 解析内存
  29. CPU 到 NanoCPUs
  30. 类型参考
  31. 与 Cogitator 合并
  32. 实例
  33. 运行 Python 代码
  34. 运行节点.js代码
  35. 运行 shell 命令
  36. 处理超时
  37. 检查退出代码
  38. 许可证

@cogitator-ai/ sandbox (英语)

安全地执行沙盒 科吉塔特特工。 在孤立的多克容器,WASM模块,操作系统的自有沙盒(MacOS上的Seatbelt,Linux上的bigwrap)或本土倒置后加上资源限制,网络隔离,和超时执行,并在多克容器或E2B,代托纳或Vercel Sandbox上的云沙盒中给代理商一个工作空间.

安装

pnpm add @cogitator-ai/sandbox

# Optional peer dependencies
pnpm add dockerode       # For Docker sandbox
pnpm add @extism/extism  # For WASM sandbox
pnpm add e2b             # For E2BWorkspace (2.28.1 or later)
pnpm add @daytona/sdk    # For DaytonaWorkspace
pnpm add @vercel/sandbox # For VercelSandboxWorkspace

快速启动

import { SandboxManager } from '@cogitator-ai/sandbox';

const manager = new SandboxManager();
await manager.initialize();

const result = await manager.execute(
  { command: ['python', '-c', 'print("Hello!")'] },
  { type: 'docker', image: 'python:3.11-alpine' }
);

if (result.success) {
  console.log(result.data.stdout); // "Hello!"
} else {
  console.error(result.error);
}

execute() 返回 a SandboxResult数字 : { success: true, data } 或者说 { success: false, error }。退出非零的命令仍然成功;检查 data.exitCode。 。 。 .

特征

  • 嵌入沙盒 - 集装箱完全隔离,能力下降
  • 原子弹沙盒 - 以极端主义为动力的Web大会执行
  • OS 沙盒 - Seatbelt (macOS) 或 bigwrap (Linux) 下的本地命令: 只在工作空间中写, 到处读, 但你否认什么, 网络只能通过一个代理来检查每个主机, 即 sandbox claude 代码的设置
  • 原生倒计时 - 无法使用 Docker 工具时可选主机执行(allowNativeFallback(中文(简体) )
  • 集装箱池 - 每一次处决都要有一个新的、预先启动的容器
  • 嵌入工作空间 - 每个代理工作空间有一个长寿命容器,安装项目,在主机上保管文件
  • 远程工作空间 - E2B、Daytona或Vercel沙盒中整个工作空间,每个供应商都有相同的行为
  • 守护进程发现 - 发现多克像 docker CLI: 爱丽丝 DOCKER_HOST,上下文,多克桌面, OrbStack, Colima, Rancher, 无根
  • 资源限制 - 内存、CPU、PID限制
  • 网络隔离 - 默认禁用
  • 超时执行 - 杀出逃进程
  • 安保强化 - 没有特权升级,所有能力下降

沙盒管理器

这个 SandboxManager 管好执行后端和每个请求的路径 type 名称.

import { SandboxManager } from '@cogitator-ai/sandbox';

const manager = new SandboxManager({
  allowNativeFallback: false,
  pool: {
    maxSize: 10,
    idleTimeoutMs: 120_000,
  },
  defaults: {
    timeout: 30_000,
    resources: {
      memory: '256MB',
      cpus: 1,
    },
    network: { mode: 'none' },
  },
});

await manager.initialize();

const result = await manager.execute(
  {
    command: ['node', '-e', 'console.log(2+2)'],
    timeout: 5000,
    env: { NODE_ENV: 'production' },
    cwd: '/workspace',
  },
  {
    type: 'docker',
    image: 'node:20-alpine',
  }
);

if (result.success) {
  console.log('Output:', result.data.stdout);
  console.log('Exit code:', result.data.exitCode);
  console.log('Duration:', result.data.duration, 'ms');
}

倒置和初始化

initialize() (a) 具有同等能力并能安全地同时打电话; execute() 自动调用.

经理退后一次:a docker 当 Docker 不可用时, 请通过本地执行器在主机上运行, 并且 无隔离,第一个这样的调用记录会发出警告. allowNativeFallback: false 拒绝这些请求 { success: false, error } 相反,它默认 true管理者 defaults 也适用于倒计时执行。 A 类 wasm 请求永不后退:没有 @extism/extism 失败 WASM sandbox unavailable: install @extism/extism to run WASM tools。一个 os 要求永远不要退缩 无论是什么 allowNativeFallback 说:在没有操作系统沙盒的机器上,它因原因失败(除非它的政策设定) failIfUnavailable: false,参见 OS 沙盒) (中文(简体) ).

找到 Docker 守护进程

与 docker.socketPath 或者说 docker.host (+ 数) port执行者在那里连接。 否则,它试图,按顺序,第一个答案是:

  1. DOCKER_HOST 当设置( 手交给多克罗德, 没有别的尝试)
  2. 当前 Docker 语境的终点(DOCKER_CONTEXT,则 currentContext 内 $DOCKER_CONFIG/config.json默认值 ~/.docker(中文(简体) )
  3. 存在于 /var/run/docker.sock, (中文(简体) ), ~/.docker/run/docker.sock (鼠标桌面), ~/.orbstack/run/docker.sock (OrbStack), (英语:OrbStack), ~/.colima/default/docker.sock 财务报告和审定财务报表 ~/.colima/docker.sock (科利马), ~/.rd/docker.sock (朗彻桌面)和 $XDG_RUNTIME_DIR/docker.sock (无根多克)
  4. Dockerode 的默认值, 当不存在上述任何一种时

可用性检查

const dockerAvailable = await manager.isDockerAvailable();
const wasmAvailable = await manager.isWasmAvailable();
const osAvailable = await manager.isOsAvailable();

console.log('Docker:', dockerAvailable);
console.log('WASM:', wasmAvailable);

关闭

await manager.shutdown();

Docker 执行器

集装箱完全隔离 安全性强化.

import { DockerSandboxExecutor } from '@cogitator-ai/sandbox';

const docker = new DockerSandboxExecutor({
  docker: {
    socketPath: '/var/run/docker.sock',
  },
  pool: {
    maxSize: 5,
    idleTimeoutMs: 60_000,
  },
});

const connectResult = await docker.connect();
if (!connectResult.success) {
  console.error('Docker not available:', connectResult.error);
}

const result = await docker.execute(
  {
    command: ['python', '-c', 'print("Hello!")'],
    stdin: 'input data',
    timeout: 10_000,
    cwd: '/app',
    env: { MY_VAR: 'value' },
  },
  {
    type: 'docker',
    image: 'python:3.11-alpine',
    timeout: 30_000,
    resources: {
      memory: '512MB',
      cpus: 2,
      pidsLimit: 50,
    },
    network: {
      mode: 'none',
    },
    mounts: [{ source: '/tmp/data', target: '/data', readOnly: true }],
    env: { GLOBAL_VAR: 'value' },
    workdir: '/workspace',
    user: 'nobody',
  }
);

await docker.disconnect();

安全特性

此主机配置创建了嵌入容器 :

设置数值
NetworkModenetwork.mode默认值 'none' (无网络)
CapDrop['ALL'] (每个能力下降)
SecurityOpt['no-new-privileges']
PidsLimitresources.pidsLimit默认值 100
根 FS 系统可写( 非可画)
工作目录/workspace
标签ai.cogitator.sandbox=true
  • command 以 argv 数组执行( 无 shell); 使用 ['sh', '-c', '...'] 用于外壳语法.
  • 输出由帧分解框架(分出网络块的帧被重新组装)并封顶为每流50000字节.
  • 每一次处决都有一个容器,以前没有放过任何东西(见 集装箱池);超时容器总是被销毁.
  • network.dns 适用于新集装箱. network.allowedHosts 被拒绝, 因为 Docker 无法强制执行 Egress 允许列表 —— 使用 mode: 'none' 或专用网络.
  • 集装箱贴上标签 ai.cogitator.sandbox=true (单位:千美元)SANDBOX_CONTAINER_LABEL),因此,崩溃过程的剩余部分可以通过 docker rm -f $(docker ps -aq --filter label=ai.cogitator.sandbox)。 。 。 .

集装箱池

集装箱在处决前开始。 默认一个已放行的容器被销毁,而一个设置相同的新容器在其位置上启动,所以下一个执行会得到一个温暖的容器,在运行或用户之间不会结转任何内容.

import { ContainerPool } from '@cogitator-ai/sandbox';

const pool = new ContainerPool(dockerClient, {
  maxSize: 10,
  idleTimeoutMs: 60_000,
});

const container = await pool.acquire('python:3.11-alpine', {
  memory: 256 * 1024 * 1024,
  cpus: 1,
  networkMode: 'none',
  mounts: [],
});

await pool.release(container);

await pool.destroyAll();

一个容器只服务于设置相同的请求(图像,资源,网络模式,DNS,挂载和用户),因此一个使用主机挂载或网络访问所创建的容器从未被交给请求隔离的请求. release(container, { corrupted: true }) 总是破坏容器. destroyAll() 移除每个容器并关闭游泳池。 闲置-清理计时器不能使节点.js进程保持活性.

集合选项

选项类型默认说明
maxSizenumber5最大闲置和变暖容器;除此之外没有备用装置
idleTimeoutMsnumber60000销毁闲置容器的时间
reuseContainersbooleanfalse将放行的容器按原样运回池中:速度更快,但留下的枪弹在下一个枪弹上可以看见,从任何运行或用户那里

传出与 pool 改为 SandboxManager, (中文(简体) ), DockerSandboxExecutor 或者说 new Cogitator({ sandbox: { pool } })。 。 。 .


嵌入工作空间

DockerWorkspace 是一个 工作空间 命令在一个长寿命容器中运行: start()),在命令之间保留,删除 dispose()。主机工作空间的根(a) LocalWorkspace 从 @cogitator-ai/core装入 /workspace,通过主机工作空间及其路径守护(下面的路径)读取并写入文件 /workspace 被映射为根, remove 财务报告和审定财务报表 rename 在没有连结连接到主机的容器中运行,命令运行 docker exec 在匹配目录中。 一个快照会还原容器里的东西 然后主机会写出改变的东西 然后被拒绝 BUSY 当命令运行在容器或主机上时.

import { Agent, LocalWorkspace, workspaceTools } from '@cogitator-ai/core';
import { DockerWorkspace } from '@cogitator-ai/sandbox';

const workspace = new DockerWorkspace({
  host: new LocalWorkspace({ root: './project' }),
  image: 'node:24-alpine',
  resources: { memory: '4GB', cpus: 4 },
});
try {
  const agent = new Agent({
    name: 'coder',
    instructions: '...',
    tools: workspaceTools(),
    workspace,
  });
  await cog.run(agent, { input: 'Run the tests and fix what fails' });
} finally {
  await workspace.dispose();
}

容器有Docker执行器的安全默认值,即输入程序,限制为2GB、2 CPU和512进程,除非 resources 设置其它, 除非 network.mode 允许它,并在Linux上运行命令作为您的 uid 和 gid 。 每个命令领导自己的进程组: 超时或中止信号组( SIGTERM, 然后是 SIGKILLL) killGrace页:1 env -i 包括各种流程,容器继续运行。 一个要求 setsid 离开组直到 dispose()。图像需要 sh。开始去除该机器已消失的过程所留下的同根容器。 没有多克,第一个命令失败 WorkspaceError 代码 UNAVAILABLE,多克 API 失败作为代码 IO。 。 。 . dispose() 还处理主机工作空间.

远程工作空间

E2BWorkspace, (中文(简体) ), DaytonaWorkspace 财务报告和审定财务报表 VercelSandboxWorkspace 为: 工作空间 其文件和命令活在一个云沙盒中:在第一次使用时创建(或由id或name重用),在 dispose()。每个用户都需要其供应商的SDK、可选的同伴依赖关系以及证书:

工作空间软件包全权证书默认根
E2BWorkspacee2bE2B_API_KEY/home/user
DaytonaWorkspace@daytona/sdkDAYTONA_API_KEY (单位:千美元)DAYTONA_API_URL, (中文(简体) ), DAYTONA_TARGET(中文(简体) )/home/daytona
VercelSandboxWorkspace@vercel/sandboxVercel的OIDC标志,或 VERCEL_TOKEN, (中文(简体) ), VERCEL_TEAM_ID, (中文(简体) ), VERCEL_PROJECT_ID/vercel/sandbox
import { Agent, workspaceTools } from '@cogitator-ai/core';
import { E2BWorkspace } from '@cogitator-ai/sandbox';

const workspace = new E2BWorkspace({ root: 'project', lifetime: 30 * 60_000 });
try {
  const agent = new Agent({
    name: 'coder',
    instructions: '...',
    tools: workspaceTools(),
    workspace,
  });
  await cog.run(agent, { input: 'Clone the repo and make its tests pass' });
} finally {
  await workspace.dispose();
}

三个都是 RemoteShellWorkspace 超过一个小驱动程序(创建或连接,读取并写入字节,运行一个程序,发布),其他一切作为沙盒中的 shell 脚本运行,所以行为相同:

  • 路径在根上正常化,并在沙盒中解决 realpath -m,从根部取出一个连结 拒绝与 OUTSIDE_ROOT
  • 将沙盒的临时目录上传到新文件,一步一步地移动到文件上,保持其模式,在沙盒的临时目录中读取私人副本,从不写出根, maxFileBytes 双盖
  • list, (中文(简体) ), remove (把垃圾放进去) .cogitator/trash和 rename 跟着 LocalWorkspace 规则和拒绝 BUSY 当命令运行或保存背景进程时
  • 运行在下面的命令 setsid 在他们自己的流程组中,有不可原谅的标记行(指使符出现在 stdin上):超时返回124并杀死该组, background: 'keep' 离开背景进程直到 dispose()
  • snapshot(), (中文(简体) ), restore(), (中文(简体) ), listSnapshots() 财务报告和审定财务报表 deleteSnapshot() 将焦油档案保存在 .cogitator/snapshots 在沙盒内, .cogitator, (中文(简体) ), node_modules 财务报告和审定财务报表 .git 总是被排除在外, 文件结束 maxFileBytes (10个小米B)跳出并列出于 skipped,不保留UTF-8名称,以及 maxSnapshotBytes (1 GiB) 拒绝更大的一个 TOO_LARGE。 。 。 . restore(id, { dryRun }) 保存在快照大小限制上保存排除条目和文件的目录,并报告内容 restored, (中文(简体) ), deleted 财务报告和审定财务报表 kept,与本地工作空间相同的API 备案检查站
  • 最多读取一个字节 maxFileBytes 在下载之前, 列表会被排序, 切到 limit 缩入 glob 在沙盒中,还有一个打印超过 maxStreamBytes (64 MiB)被停止,因为SDKs将全部输出保存在内存中
  • E2B和Vercel沙盒得到一个 lifetime (30分)工作空间在使用时向后推

onDispose 选择什么 dispose() 与沙盒连接 : destroy (对被创造者), stop (Daytona和Vercel,文件存续)或 keep (由 id 或 name 给出的默认, stop 一个叫Vercel的沙盒。 图像需要 sh, GNU creautils, findutils 和 tar, 以及 util- linux setsid,如同提供者的默认图像 start() 名称 缺少。 没有SDK或证书 第一次操作失败 WorkspaceError 代码 UNAVAILABLE。 。 。 . e2b 需要2.28.1或以后,从2.59起,它需要22.19节点或以后。 启动自己的届会的过程(setsid)逃出群杀并活到沙盒去. DaytonaWorkspace 通过 env 在一个私人目录的短命文件中,因此代托纳对命令行的记录从没有持有过这些值.

通过执行来带来另一个提供者 RemoteShellDriver 并传递给 new RemoteShellWorkspace({ driver })。 。 。 . shellQuote 财务报告和审定财务报表 shellCommand 从argv上建立安全壳线.

WASM 执行器

通过Extism执行WebAssembly模块. 每个插件在自己的工人线程中运行,因此超时终止了运行的模块而不是阻挡事件循环. 每个模块 / WASI / 允许主机组合(最多 cacheSize);同时执行时使用单独的插件例.

import { WasmSandboxExecutor } from '@cogitator-ai/sandbox';

const wasm = new WasmSandboxExecutor({
  wasm: {
    cacheSize: 10,
    wasi: true,
  },
});

await wasm.connect();

const result = await wasm.execute(
  {
    command: ['process'],
    stdin: JSON.stringify({ data: 'input' }),
  },
  {
    type: 'wasm',
    wasmModule: 'https://example.com/plugin.wasm',
    wasmFunction: 'run',
    wasi: true,
    timeout: 5000,
  }
);

await wasm.disconnect();
  • wasmModule 需要一个 http(s) URL, 文件路径或软件包路径 :
    • 绝对路径或起始路径 . 相对于工作目录读取
    • 其它文件首先作为相对于工作目录的文件进行尝试,然后像您应用程序的导入那样解决(例如) @cogitator-ai/wasm-tools/wasm/calc.wasm:从工作目录,然后从条目脚本目录,然后从 @cogitator-ai/sandbox (涵盖 NODE_PATH 和升起的装置。 这与 pnpm 的严格布局配合, 沙盒包无法看到您的依赖性 .
    • 当模块载运一个导出路径帮助软件包时,例如 getWasmPath() 从 @cogitator-ai/wasm-tools,通过绝对路径来完全跳过分辨率.
  • wasmModule, (中文(简体) ), functionName 财务报告和审定财务报表 wasi 当请求配置省略时,则使用执行器选项.
  • network.allowedHosts 已转发到 Extism 的 HTTP 允许列表( 当空时) network.mode 实值 'none') (中文(简体) ).
  • memoryPages (default 256 = 16 MB) 封装了模块自己的内存:它的内存部分在模块加载前获得最大值,所以 memory.grow 通过它失败在模块内,需要更多启动的模块被拒绝。 Extism对插件输入,输出和 vars 的内存获得相同的限制. 执行者从 URL 中获取模块, 因此上限也适用于它们 .

OS 沙盒

OsSandbox 在操作系统的沙盒内运行本地命令,其中有克洛德密码的沙盒巴什工具的语义:Seatbelt(sandbox-exec 在macOS, 气泡包装(bwrap在Linux上。 Linux 也需要 socat数字 : apt-get install bubblewrap socat给一个 LocalWorkspace 联 合 国 @cogitator-ai/core,并且每个工作空间运行的命令(run_command经历它:

import { LocalWorkspace, loadSandboxPolicy, workspaceTools } from '@cogitator-ai/core';
import { OsSandbox } from '@cogitator-ai/sandbox';

const { policy } = await loadSandboxPolicy('./project'); // the `sandbox` section of .claude/settings.json
const sandbox = new OsSandbox({ policy });
const workspace = new LocalWorkspace({ root: './project', exec: { sandbox } });
await workspace.start(); // fails with SANDBOX_UNAVAILABLE when the sandbox cannot run here

一个沙盒命令能达到什么:

访问默认换一个
写作仅此命令的工作空间根和一个临时目录(TMPDIR(中文(简体) )filesystem.allowWrite, (中文(简体) ), filesystem.denyWrite
读取任何地方, 证书文件, 如 ~/.ssh 包含filesystem.denyRead, (中文(简体) ), filesystem.allowRead, (中文(简体) ), credentials.files
网络除沙盒的代理外, 没有路由, 在列出主机之前, 不允许任何内容 network.allowedDomains, (中文(简体) ), network.deniedDomains, (中文(简体) ), onUnknownHost
信封工作空间通过什么( 默认没有 API 密钥)credentials.envVars
  • 文件系统. 较窄的规则获胜: allowRead 更宽 denyRead 重新打开该部分, a denyRead 更宽 allowRead 仍然坚守。 一个 allowRead 仅通过符号链接到达被否定区域时被忽略,文件 denyRead 或者说 credentials.files 带有另一个硬链接的名字无法发射,因为其所列名字被拒绝。 写否定总是胜过许可 道路是绝对的, ~/ 对于主目录,或相对于工作空间根. *, (中文(简体) ), ?, (中文(简体) ), ** 财务报告和审定财务报表 [...] 在 macOS 的每个列表和 Linux 的读取列表中工作,一个后缀 /** 到处都是.
  • 防护道. 即使在可写入目录中,命令也不能写入克劳德代码和Cogitator的设置、钩子、技能、代理、命令和插件(在根和上方的所有目录中,以及 ~/.claude, (中文(简体) ), ~/.cogitator, (中文(简体) ), ~/.claude.json),整个 .cogitator 根的目录(它的垃圾和快照), .mcp.json,贝壳启动文件, .gitconfig, (中文(简体) ), .gitmodules, (中文(简体) ), .vscode, (中文(简体) ), .idea,该寄存器的 git 目录中运行或遵循的文件(hooks, (中文(简体) ), config, (中文(简体) ), commondir, (中文(简体) ), config.worktree,是连接工作树的主要寄存处,也是连接工作树和子模块的主要寄存处,根的 .git 条目本身( 无命令替换为 gitdir: 内部仍然写着它自己的文件) HEAD 在根部,所以没有命令将根变成一个赤裸的寄存器, 它的配置会从沙盒外读取。 被保护路径的同义链接也保护了目标,一个有多个硬链接的被保护文件会使发射失败. 仅 filesystem.disabled 把他们抬起来, 剩下的文件系统隔离.
  • 腾讯网. 命令获得 HTTP_PROXY, (中文(简体) ), HTTPS_PROXY 财务报告和审定财务报表 ALL_PROXY (SOCKS5)指向一个只服务于这个命令的代理. 一个主机 deniedDomains 名字被拒绝,一个 allowedDomains 名称通过( n)github.com 只有那个宿主, *.npmjs.org 它的子域, * 每个主机, IPv4 和括号内的 IPv6 地址, 每个地址都有可选 :port),任何其他主机则由调用决定 onUnknownHost (一跑电传到它的许可作为一个 WebFetch(domain:...) 电话,否则沙盒是自己的 onUnknownHost,其他拒绝. strictAllowlist 拒绝未知主机而不询问 。 仅决定回回回,链接-局部,云元数据端点或此机地址的宿主名被拒绝, localhost 列表地址本身(127.0.0.1:3000)以名称到达本地服务器。 UDP, QUIC 和 ICMP 不离开, 忽略代理变量的工具( plan) ssh,大多数数据库驱动程序)无法连接.
  • 每个命令主机. exec(command, { allowedDomains }) (和 run_command是因为 allowedDomains) 单独打开命令的主机,当它运行时,它不列出的主机则被拒绝而不询问. deniedDomains 仍然赢,一个 strictAllowlist 政策拒绝这样的呼吁.
  • 违反规定. 代理拒绝什么,文件访问系统拒绝(Operation not permitted, (中文(简体) ), Read-only file system页:1 result.sandbox.violations,还有消毒 <sandbox_violations> 块附在其 stderr上,所以模型会看到它为什么失败. ignoreViolations 压制预期的({ "*": ["/etc/hosts"] }) (中文(简体) ). 网络违规来自代理,文件违规是咨询(从命令本身的错误读取,它控制),a <sandbox_violations> 标记命令指纹本身已失效.
  • Linux 筑巢. 命令在一秒钟内运行 bwrap 在第一个,与 --disable-userns (bulble wrap 0.8.0及后)和一分接滤波器(x86 64,arm64)拒绝新建命名空间,挂载,io uring和Unix套接字,包含数据gram套接字对(任何) allowUnixSockets 条目或 allowAllUnixSockets 打开全部,过滤器无法将路径区分开来),所以它无法从它自己的命名空间中取消只读绑定 。 seccomp过滤器是需要的,作为避免命令出现在路径名Unix sockets上的唯一东西:没有它,沙盒是没有的,除非 allowAllUnixSockets 设置, 当 --disable-userns 一个人可以.
  • 取出沙盒外来. excludedCommands (内容: Bash(...) 规则,例如: docker *当线条的每个命令都匹配而线条没有方向调整时, 运行未保存框, cd从变量中替换或程序. dangerouslyDisableSandbox 只有在政策设定时才打开 allowUnsandboxed (违约不实,否则被忽略). 都经过正常的许可流,结果说 sandboxed: false 与缘由.
  • 无所取取. failIfUnavailable (默认为真)拒绝开始,带有 SANDBOX_UNAVAILABLE 命名出错: 无 sandbox-exec,没有 bwrap 或者说 socat,用户名空间被屏蔽(一个容器,Ubuntu的AppArmor限制). 与 false 命令以警告方式解开框,每个结果都这么说(unsandboxedReason: 'unavailable') (中文(简体) ). 没有任何沉默的后退.
  • 权限. 内部运行的命令跳过它需要的批准( )autoAllow,默认为真 ): run_command自己和一个赤裸裸的 Bash 问规则。 拒绝规则,要求规则有规律(Bash(git push *), (中文(简体) ), rm 财务报告和审定财务报表 rmdir 以一条关键的道路盟誓, ~, (中文(简体) ), /, (中文(简体) ), .git)和计划模式仍然适用,并使用 VAR=x 玡, eval, (中文(简体) ), make X=y, (中文(简体) ), source, (中文(简体) ), alias, (中文(简体) ), export, (中文(简体) ), set -a 或 shell reading stdin通过正常的流出,以及命令给自己的主机取名. 仅 run_command 联 合 国 workspaceTools() 在沙盒工作空间运行是自动分配的,绝不是核心 exec 工具.

OsSandbox.probe() 说沙盒是否在这里运行, OsSandbox.create(options) 返回已启动的, dispose() 关闭仍在运行的命令的代理并删除其目录。 这个 os 类型 SandboxManager 在它下运行一个执行程序({ type: 'os', workdir, os: policy },工作目录其可写根),总是与 failIfUnavailable: true。 。 。 .

不覆盖,说实话: 外壳 rm 删除为好( 垃圾为 delete_file 工具的,见 @cogitator-ai/core),处理在背景中运行的命令叶会丢失网络及其 TMPDIR 一旦它退出(并在Linux上随它停止),文件被从命令的错误中读取,而不是从系统日志中读取,Linux在命令启动时否认路径通配符(一个后来制作的文件没有覆盖),Linux保护一个连接目录后面的路径,链接引出,而不是在链接中,在根下方的git寄存器保留了它们的钩子可写,没有检查TLS,所以一个允许的域携带任何到它的东西.


原生执行器

直接执行而不隔离(倒回模式).

import { NativeSandboxExecutor } from '@cogitator-ai/sandbox';

const native = new NativeSandboxExecutor();
await native.connect();

const result = await native.execute(
  {
    command: ['ls', '-la'],
    cwd: '/tmp',
    env: { LC_ALL: 'C' },
    timeout: 5000,
  },
  { type: 'native' }
);

if (result.success) console.log(result.data.stdout);

警告: 本地处决没有孤立。 仅在无法使用 Docker 时使用 .

  • 单元素命令( A)['ls -la | wc -l'])运行于系统 shell;较长的命令直接以精确的 argv(无 shell)执行,就像 Docker.
  • stdin 已连接到进程.
  • 仅 PATH, (中文(简体) ), HOME,临时目录、语言和Windows系统变量从主机环境继承; 机密 process.env 没有传递到执行代码。 明确通过 env。 。 。 .
  • 超时时, 整个进程组都会被杀死(SIGKILL)并立即以退出代码返回结果 124。 。 。 .
  • 输出上限为每流有5万字节,而过程仍然被排出.

执行请求

interface SandboxExecutionRequest {
  command: string[];
  stdin?: string;
  timeout?: number;
  cwd?: string;
  env?: Record<string, string>;
  signal?: AbortSignal;
}

取消执行

中止 signal 立即停止执行:原生执行器杀死进程组,多克执行器结束执行并取出其容器(一个中止的容器永远不会被再利用),而WASM执行器关闭了插件,它结束它的工人. 结果是无法命名原因,并且已经中止的信号不会运行。 所以取消一个运行会停止它的沙箱工具.

const controller = new AbortController();
setTimeout(() => controller.abort(new Error('user cancelled')), 1000);

const result = await manager.execute(
  { command: ['sleep', '30'], signal: controller.signal },
  { type: 'docker', image: 'alpine:3.19' }
);
// { success: false, error: 'Execution aborted: user cancelled' }

执行结果

interface SandboxExecutionResult {
  stdout: string;
  stderr: string;
  exitCode: number;
  timedOut: boolean;
  duration: number;
  truncated?: boolean;
}

资源限制

内存

const result = await manager.execute(request, {
  type: 'docker',
  image: 'alpine',
  resources: {
    memory: '256MB',
  },
});

支持的格式 : '256B', (中文(简体) ), '256KB', (中文(简体) ), '256MB', (中文(简体) ), '1GB', (中文(简体) ), '1TB'鼠标样式 '512m' 编号 : '2g' 二进制 '1GiB' (所有二进制倍数,大小写不敏感). 0或负内存和CPU限制被拒绝,而不是默默地运行无限.

CPU 软件

SandboxConfig 以类型导出( e)import type { SandboxConfig } from '@cogitator-ai/sandbox') (中文(简体) ).

const config: SandboxConfig = {
  type: 'docker',
  image: 'alpine',
  resources: {
    cpus: 0.5,
    cpuShares: 512,
  },
};

进程限制

const config: SandboxConfig = {
  type: 'docker',
  image: 'alpine',
  resources: {
    pidsLimit: 50,
  },
};

网络配置

const config: SandboxConfig = {
  type: 'docker',
  image: 'alpine',
  network: {
    mode: 'none',
  },
};

网络模式 :

  • 'none' - 没有网络访问(默认,最安全)
  • 'bridge' - 多克桥网
  • 'host' - 主机网络(不推荐)

音量山数

将主机目录挂入容器 :

const config: SandboxConfig = {
  type: 'docker',
  image: 'alpine',
  mounts: [
    { source: '/host/data', target: '/data', readOnly: true },
    { source: '/host/output', target: '/output', readOnly: false },
  ],
};

工具函数

解析内存

import { parseMemory } from '@cogitator-ai/sandbox';

parseMemory('256MB');
parseMemory('1GB');
parseMemory('512KB');

CPU 到 NanoCPUs

import { cpusToNanoCpus } from '@cogitator-ai/sandbox';

cpusToNanoCpus(0.5);
cpusToNanoCpus(2);

类型参考

import type {
  SandboxType,
  SandboxConfig,
  SandboxResourceLimits,
  SandboxNetworkConfig,
  SandboxMount,
  SandboxExecutionRequest,
  SandboxExecutionResult,
  SandboxManagerConfig,
  SandboxPoolConfig,
  SandboxDockerConfig,
  SandboxResult,
  OsSandboxPolicy,
  OsSandboxKind,
  OsSandboxAvailability,
  SandboxViolation,
  SandboxHostRequest,
  SandboxHostDecider,
} from '@cogitator-ai/sandbox';

与 Cogitator 合并

在代理中使用沙盒工具 :

import { Cogitator, tool } from '@cogitator-ai/core';
import { z } from 'zod';

const shellTool = tool({
  name: 'run_shell',
  description: 'Execute shell commands safely',
  parameters: z.object({
    command: z.string(),
  }),
  sandbox: {
    type: 'docker',
    image: 'ubuntu:22.04',
    resources: { memory: '256MB' },
    network: { mode: 'none' },
  },
  timeout: 30000,
  execute: async ({ command }) => command,
});

const cog = new Cogitator({
  sandbox: {
    pool: { maxSize: 5 },
    allowNativeFallback: false,
  },
});

运行时间开始 a SandboxManager 从 new Cogitator({ sandbox }) 第一个沙箱工具呼叫。 对于一个Docker工具,它不叫 execute: 沙盒运行工具的 command 参数 sh -c (可选) cwd 编号 : env 参数)和输出成为工具结果. 一个WASM工具得到了它的论据,因为JSON在stdin上,它的JSON stdout是结果. 当 Docker 不可用时—— 或此软件包丢失或启动失败—— 一个 Docker 工具运行 execute 在主机上卸下一个警告,除非 sandbox.allowNativeFallback: false 将调用变成工具错误。 一个 WASM 工具在 Extism 缺失时失败, 并运行它自己的 execute 仅当此软件包丢失或启动失败时。 见 沙盒 在网站上.


实例

运行 Python 代码

const result = await manager.execute(
  {
    command: [
      'python',
      '-c',
      `
import json
data = {"sum": 2 + 2}
print(json.dumps(data))
    `,
    ],
  },
  {
    type: 'docker',
    image: 'python:3.11-alpine',
    timeout: 10_000,
  }
);

if (result.success) {
  const output = JSON.parse(result.data.stdout);
  console.log(output.sum);
}

运行节点.js代码

const result = await manager.execute(
  {
    command: ['node', '-e', 'console.log(JSON.stringify({result: 42}))'],
  },
  {
    type: 'docker',
    image: 'node:20-alpine',
    resources: { memory: '128MB' },
  }
);

运行 shell 命令

const result = await manager.execute(
  {
    command: ['sh', '-c', 'ls -la /workspace && pwd'],
    cwd: '/workspace',
  },
  {
    type: 'docker',
    image: 'alpine:3.19',
  }
);

处理超时

const result = await manager.execute(
  { command: ['sleep', '60'] },
  { type: 'docker', image: 'alpine', timeout: 5000 }
);

if (result.success && result.data.timedOut) {
  console.log('Command timed out');
}

检查退出代码

const result = await manager.execute(
  { command: ['sh', '-c', 'exit 42'] },
  { type: 'docker', image: 'alpine' }
);

if (result.success) console.log('Exit code:', result.data.exitCode);

许可证

麻省理工学院

版本与发布记录

@cogitator-ai/sandbox 共发布 96 个版本,首次发布于 2025/12/31;过去 12 个月发布了 96 个版本。

版本发布日期距今
0.10.4latest2026/10/2912 天前
0.10.32026/10/2912 天前
0.10.22026/10/2912 天前
0.10.12026/10/2912 天前
0.10.02026/10/2812 天前
0.9.22026/10/2813 天前

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

@cogitator-ai/sandbox 是什么?

用于 Cogitator 代理的 Sandbox 执行( Docker, WASM, 以及 E2B, Daytona 和 Vercel Sandbox 上的远程工作空间)

如何安装 @cogitator-ai/sandbox?

在项目目录运行 npm install @cogitator-ai/sandbox,或使用 pnpm add / yarn add / bun add。

@cogitator-ai/sandbox 支持 TypeScript 吗?

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

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

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

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

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

@cogitator-ai/sandbox 可以商用吗?

@cogitator-ai/sandbox 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

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

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

@cogitator-ai/sandbox 还在维护吗?

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