一、sandboxed_write 工具
1.1 工具概述
功能 :沙盒中写入文件
核心特性:
- 通过 bridge 写入隔离文件系统
- 自动创建父目录
- 支持沙盒根目录限制
- 参数标准化包装
1.2 创建函数
位置:第 115006 行
javascript
function createSandboxedWriteTool(params) {
return wrapToolParamNormalization(createWriteTool(params.root, {
operations: createSandboxWriteOperations(params)
}), CLAUDE_PARAM_GROUPS.write);
}
1.3 沙盒写入操作
位置:第 115068 行
javascript
function createSandboxWriteOperations(params) {
return {
// 1. 创建目录
mkdir: async (dir) => {
await params.bridge.mkdirp({
filePath: dir,
cwd: params.root
});
},
// 2. 写入文件
writeFile: async (absolutePath, content) => {
await params.bridge.writeFile({
filePath: absolutePath,
cwd: params.root,
data: content
});
}
};
}
1.4 包装链
createWriteTool (外部库)
↓ (使用沙盒操作)
wrapToolParamNormalization (参数标准化)
↓ (CLAUDE_PARAM_GROUPS.write)
最终工具
1.5 参数标准化
javascript
const CLAUDE_PARAM_GROUPS = {
write: [
{
keys: ["path", "file_path", "filePath", "file"],
label: "path alias"
},
{
keys: ["content"],
label: "content"
}
]
};
const CLAUDE_PARAM_ALIASES = [
{ original: "path", alias: "file_path" },
{ original: "path", alias: "filePath" },
{ original: "path", alias: "file" }
];
1.6 执行流程图
sandboxed_write 工具调用
↓
1. 参数标准化
├─ path/file_path/filePath/file → path
└─ content → content
↓
2. 验证必填参数
↓
3. 沙盒桥接写入
├─ bridge.mkdirp(创建父目录)
└─ bridge.writeFile(写入文件)
↓
4. 返回结果
1.7 返回结果格式
成功:
json
{
"content": [{
"type": "text",
"text": "Successfully wrote 123 bytes to sandbox:src/main.js"
}],
"details": {
"path": "src/main.js",
"bytesWritten": 123,
"sandbox": true
}
}
二、sandboxed_edit 工具
2.1 工具概述
功能 :沙盒中编辑文件
核心特性:
- 通过 bridge 访问隔离文件系统
- 支持编辑失败恢复
- 支持参数别名
- 精确文本替换
2.2 创建函数
位置:第 115009 行
javascript
function createSandboxedEditTool(params) {
return wrapToolParamNormalization(
wrapEditToolWithRecovery(createEditTool(params.root, {
operations: createSandboxEditOperations(params)
}), {
root: params.root,
readFile: async (absolutePath) => (await params.bridge.readFile({
filePath: absolutePath,
cwd: params.root
})).toString("utf8")
}),
CLAUDE_PARAM_GROUPS.edit
);
}
2.3 沙盒编辑操作
位置:第 115077 行
javascript
function createSandboxEditOperations(params) {
return {
// 1. 读取文件
readFile: (absolutePath) => params.bridge.readFile({
filePath: absolutePath,
cwd: params.root
}),
// 2. 写入文件
writeFile: (absolutePath, content) => params.bridge.writeFile({
filePath: absolutePath,
cwd: params.root,
data: content
}),
// 3. 访问检查
access: async (absolutePath) => {
if (!await params.bridge.stat({
filePath: absolutePath,
cwd: params.root
})) {
throw createFsAccessError("ENOENT", absolutePath);
}
}
};
}
2.4 编辑恢复包装
位置:第 114462 行
javascript
function wrapEditToolWithRecovery(base, options) {
return {
...base,
execute: async (toolCallId, params, signal, onUpdate) => {
// 1. 读取参数
const { pathParam, oldText, newText } = readEditToolParams(params);
// 2. 解析绝对路径
const absolutePath = typeof pathParam === "string" ?
resolveEditPath(options.root, pathParam) : void 0;
// 3. 读取原始内容
let originalContent;
if (absolutePath && newText !== void 0) {
try {
originalContent = await options.readFile(absolutePath);
} catch {}
}
// 4. 执行编辑
try {
return await base.execute(toolCallId, params, signal, onUpdate);
} catch (err) {
// 5. 编辑失败处理
if (!absolutePath) throw err;
let currentContent;
try {
currentContent = await options.readFile(absolutePath);
} catch {}
// 6. 判断编辑是否已应用
if (typeof currentContent === "string" && newText !== void 0) {
if (didEditLikelyApply({
originalContent,
currentContent,
oldText,
newText
})) {
return buildEditSuccessResult(pathParam ?? absolutePath);
}
}
// 7. 添加不匹配提示
if (typeof currentContent === "string" &&
err instanceof Error &&
shouldAddMismatchHint(err)) {
throw appendMismatchHint(err, currentContent);
}
throw err;
}
}
};
}
2.5 参数标准化
javascript
const CLAUDE_PARAM_GROUPS = {
edit: [
{
keys: ["path", "file_path", "filePath", "file"],
label: "path alias"
},
{
keys: ["oldText", "old_string", "old_text", "oldString"],
label: "oldText alias"
},
{
keys: ["newText", "new_string", "new_text", "newString"],
label: "newText alias",
allowEmpty: true
}
]
};
const CLAUDE_PARAM_ALIASES = [
// path 别名
{ original: "path", alias: "file_path" },
{ original: "path", alias: "filePath" },
{ original: "path", alias: "file" },
// oldText 别名
{ original: "oldText", alias: "old_string" },
{ original: "oldText", alias: "old_text" },
{ original: "oldText", alias: "oldString" },
// newText 别名
{ original: "newText", alias: "new_string" },
{ original: "newText", alias: "new_text" },
{ original: "newText", alias: "newString" }
];
2.6 执行流程图
sandboxed_edit 工具调用
↓
1. 参数标准化
├─ path 别名处理
├─ oldText 别名处理
└─ newText 别名处理
↓
2. 验证必填参数
↓
3. 读取原始内容
↓
4. 执行编辑(精确替换)
↓
5. 编辑失败处理
├─ 读取当前内容
├─ 判断是否部分成功
└─ 添加不匹配提示
↓
6. 返回结果
三、关键机制对比
3.1 功能定位
| 特性 | sandboxed_write | sandboxed_edit |
|---|---|---|
| 用途 | 创建/覆盖文件 | 精确修改文件 |
| 写操作 | 覆盖写入 | 精确替换 |
| 恢复机制 | 不支持 | 支持 |
3.2 参数支持
| 特性 | sandboxed_write | sandboxed_edit |
|---|---|---|
| 参数别名 | 4 个(path) | 9 个(path/oldText/newText) |
| 必填参数 | path, content | path, oldText |
| 可选参数 | 无 | newText(可为空) |
3.3 安全限制
| 限制类型 | sandboxed_write | sandboxed_edit |
|---|---|---|
| 沙盒根目录 | root 限制 | root 限制 |
| 桥接访问 | 必需 | 必需 |
| 路径边界 | bridge 路径 | bridge 路径 |
四、沙盒工具系列总结
4.1 三个沙盒工具
| 工具 | 功能 | 桥接操作 |
|---|---|---|
| sandboxed_read | 读取文件 | bridge.readFile, bridge.stat, detectMime |
| sandboxed_write | 写入文件 | bridge.mkdirp, bridge.writeFile |
| sandboxed_edit | 编辑文件 | bridge.readFile, bridge.writeFile, bridge.stat |
4.2 共同特点
- 通过
bridge访问隔离文件系统 - 不能直接访问 host 文件系统
- 用于容器/Docker/沙盒环境
- 支持
modelContextWindowTokens限制 - 支持图片 sanitization
4.3 使用场景
沙盒模式启用时:
├─ 读取文件 → sandboxed_read
├─ 写入文件 → sandboxed_write
└─ 编辑文件 → sandboxed_edit
非沙盒模式时:
├─ 读取文件 → read
├─ 写入文件 → write
└─ 编辑文件 → edit
五、使用示例
5.1 sandboxed_write 工具调用
用户 :在沙盒中创建文件
大模型返回:
json
{
"tool_call": {
"name": "sandboxed_write",
"arguments": {
"path": "src/main.js",
"content": "console.log(\"Hello\");"
}
}
}
执行结果:
json
{
"content": [{
"type": "text",
"text": "Successfully wrote 27 bytes to sandbox:src/main.js"
}],
"details": {
"path": "src/main.js",
"bytesWritten": 27,
"sandbox": true
}
}
5.2 sandboxed_edit 工具调用
用户 :修改沙盒中的文件
大模型返回:
json
{
"tool_call": {
"name": "sandboxed_edit",
"arguments": {
"path": "src/main.js",
"oldText": "console.log(\"Hello\");",
"newText": "console.log(\"Hello, World!\");"
}
}
}
执行结果:
json
{
"content": [{
"type": "text",
"text": "Successfully edited sandbox:src/main.js"
}],
"details": {
"path": "src/main.js",
"sandbox": true
}
}