Shell 与沙箱
配置 Agent 的本地命令执行、沙箱和审批流程
Shell 与沙箱
Agent 使用 @downcity/shell 执行本地命令、管理沙箱运行环境、处理交互式审批。
安装
pnpm add @downcity/shellShell
Shell 类管理命令执行和交互式审批运行时。应用层审批归属具体 Session,通过 Session API 处理。
最小示例
import { Shell } from "@downcity/shell";
import { Agent } from "@downcity/agent";
const shell = new Shell();
const agent = new Agent({
id: "demo",
path: process.cwd(),
shell,
});通过 Agent 装配时不需要传入路径;Agent 会把自己的项目根目录和运行时上下文配置给 Shell。独立使用 Shell 时可以传入 root_path。
方法
shell.dispose()— 释放 shell 资源
审批请求会在 session.subscribe((mutation) => {}) 中表现为 approval-required Tool Part。应用层从 mutation.part.approval 读取完整请求,再使用 session.resolve_approval(...) 提交用户决定;重连后可通过 session.approvals() 恢复 pending 请求。不要直接调用 Shell Runtime 的内部审批方法。
模型工具
传给 Agent 的 Shell 会提供:
| 工具 | 用途 |
|---|---|
shell_exec | 执行一次性非交互命令 |
shell_session | 管理长运行或交互式 PTY 命令 |
grep | 底层直接使用 ripgrep 搜索项目文件内容 |
find | 使用 POSIX glob 模式发现项目文件 |
read | 按行分页读取文本,并把图片注入模型输入 |
write | 创建 UTF-8 文件,或在 overwrite: true 时原子覆盖 |
edit | 使用唯一、非重叠的 old_text 精确编辑一个文件 |
read 默认最多返回 500 行,单次最多 2,000 行或 256KB。结果中的 truncated 和 next_offset 用于继续读取。write 单次最多写入 1MB,并自动创建父目录。
对于 PNG、JPEG、GIF、WebP 和 BMP 文件,read 会返回图片元数据和 data URL,Agent 再把该 data URL 作为临时 user image part 注入下一个模型 step。其他二进制文件只返回元数据。
edit 一次最多接受 10 个修改,所有修改都基于原始文件匹配并且全部成功后才写入。可以把 read.sha256 传给 edit.expected_sha256,防止覆盖并发修改。
grep 不经过 shell,直接执行 rg --json。它默认使用不区分大小写的字面量搜索;设为 literal: false 可使用正则表达式,设为 case_sensitive: true 可区分大小写,glob 用于限制候选文件。
find 接受 POSIX glob pattern,包含 dotfile、遵守 .gitignore,且不会跟随符号链接。两个搜索工具默认最多返回 200 项,max_results 最大为 2,000。
所有文件和搜索工具都固定限制在项目根目录内,并拒绝符号链接逃逸。它们不会申请 unrestricted 权限。
沙箱
Shell 命令默认使用 safe sandbox。沙箱后端会根据宿主平台自动选择:
macos-seatbelt— macOS 沙箱linux-bubblewrap— Linux 沙箱unrestricted-host— 不启用沙箱
SDK 内部的沙箱运行器负责 shell 子进程创建、平台后端调用和一次性命令执行。通常不需要直接使用。
Env
shell_exec 和 shell_session 使用当前 Session step 已生效的 Agent env 构造子进程环境。宿主可以通过 agent.setEnv(next) 或 agent.patchEnv(patch) 动态更新 configured env;已有 Session 会在下一个 step 检查点提交该修改,当前 provider 请求及其工具调用继续使用原 env。如果当前 Session turn 没有后续 step,则在下一个 Session turn 开始时提交。
safe sandbox 只会导出两类环境变量:
- shell 运行所需的最小基础变量,例如
PATH、LANG、SHELL - 当前 Agent env 中显式存在的 key
这意味着 .env、构造参数 env 和运行时 agent.patchEnv() 写入的 key 可以被 sandbox 内命令读取,但 SDK 不会把完整宿主 process.env 暴露给 sandbox。
agent.patchEnv({
GITHUB_TOKEN: token,
});
await agent.tools.shell_exec.execute(
{
cmd: 'printf "%s\\n" "$GITHUB_TOKEN"',
sandbox: "safe",
},
{ toolCallId: "example" },
);ConfigResolver
SandboxConfigResolver 根据 Agent 项目根目录生成固定的 safe sandbox 边界。
SandboxPreflight 执行沙箱前置检查,验证沙箱环境是否就绪。