Skip to content

Commit 52aa1c7

Browse files
committed
feat: enhance read_file tool with extended parameters and improve security handling
- Extended read_file tool parameters to include file_path, offset, and limit for more granular file access - Updated tool call conversions between Gemini and OpenAI formats to use new parameter structure - Modified security configuration to use exclude list instead of blocklist for better control - Updated documentation and examples to reflect new parameter naming and security model - Adjusted JSON parsing demo scenarios to demonstrate new tool parameter structure
1 parent fb3f962 commit 52aa1c7

20 files changed

Lines changed: 1204 additions & 2161 deletions

src/pages/ContentConverterAnimation.tsx

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -155,15 +155,31 @@ convertGeminiToolsToOpenAI(tools: Tool[]): ChatCompletionTool[] {
155155
functionDeclarations: [{
156156
name: 'read_file',
157157
description: '读取文件内容',
158-
parameters: { type: 'object', properties: { path: { type: 'string' } } }
158+
parameters: {
159+
type: 'object',
160+
properties: {
161+
file_path: { type: 'string' },
162+
offset: { type: 'number' },
163+
limit: { type: 'number' },
164+
},
165+
required: ['file_path'],
166+
}
159167
}]
160168
},
161169
openaiTool: {
162170
type: 'function',
163171
function: {
164172
name: 'read_file',
165173
description: '读取文件内容',
166-
parameters: { type: 'object', properties: { path: { type: 'string' } } }
174+
parameters: {
175+
type: 'object',
176+
properties: {
177+
file_path: { type: 'string' },
178+
offset: { type: 'number' },
179+
limit: { type: 'number' },
180+
},
181+
required: ['file_path'],
182+
}
167183
}
168184
}
169185
},
@@ -212,7 +228,7 @@ private convertContent(content: Content): ChatCompletionMessageParam {
212228
role: 'model',
213229
parts: [
214230
{ text: '我来读取这个文件' },
215-
{ functionCall: { name: 'read_file', args: { path: 'index.ts' } } }
231+
{ functionCall: { name: 'read_file', args: { file_path: 'index.ts', offset: 0, limit: 200 } } }
216232
]
217233
},
218234
openaiMessage: {
@@ -221,7 +237,7 @@ private convertContent(content: Content): ChatCompletionMessageParam {
221237
tool_calls: [{
222238
id: 'call_xxx',
223239
type: 'function',
224-
function: { name: 'read_file', arguments: '{"path":"index.ts"}' }
240+
function: { name: 'read_file', arguments: '{"file_path":"index.ts","offset":0,"limit":200}' }
225241
}]
226242
}
227243
},
@@ -253,14 +269,14 @@ private buildToolCallMessage(
253269
}
254270
255271
// 关键转换:
256-
// Gemini: { name: "read", args: { path: "x.ts" } }
257-
// OpenAI: { name: "read", arguments: '{"path":"x.ts"}' }
272+
// Gemini: { name: "read", args: { file_path: "x.ts" } }
273+
// OpenAI: { name: "read", arguments: '{"file_path":"x.ts"}' }
258274
// ^^^^^^^^^ 字符串化!`,
259275
visualData: {
260276
gemini: {
261277
functionCall: {
262278
name: 'read_file',
263-
args: { path: 'index.ts', encoding: 'utf-8' }
279+
args: { file_path: 'index.ts', offset: 0, limit: 200 }
264280
}
265281
},
266282
openai: {
@@ -269,7 +285,7 @@ private buildToolCallMessage(
269285
type: 'function',
270286
function: {
271287
name: 'read_file',
272-
arguments: '{"path":"index.ts","encoding":"utf-8"}'
288+
arguments: '{"file_path":"index.ts","offset":0,"limit":200}'
273289
}
274290
}]
275291
}

src/pages/ContentGeneratorDetails.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ private tryRepairAndParse(buffer: string): Record<string, unknown> | null {
553553
</div>
554554
<div className="bg-black/30 rounded p-3">
555555
<div className="text-xs text-gray-400 mb-1">解析结果</div>
556-
<code className="text-sm">{`{ completed: true, args: { path: "/src/app.ts" } }`}</code>
556+
<code className="text-sm">{`{ completed: true, args: { file_path: "/src/app.ts" } }`}</code>
557557
</div>
558558
</div>
559559
</HighlightBox>

src/pages/FormatConverterAnimation.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ export function convertOpenAIChunkToGemini(
460460
functionCall: {
461461
id: "call_abc123",
462462
name: "read_file",
463-
args: { path: "/package.json" }
463+
args: { file_path: "/package.json" }
464464
}
465465
}],
466466
role: "model"
@@ -519,7 +519,7 @@ function mapUsageMetadata(usage: OpenAI.CompletionUsage) {
519519
functionCall: {
520520
id: "call_abc123",
521521
name: "read_file",
522-
args: { path: "/package.json" }
522+
args: { file_path: "/package.json" }
523523
}
524524
}
525525
],

src/pages/FunctionResponseAnimation.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ function HistoryInjection({ phase }: { phase: BuildPhase }) {
442442
<div className="p-2 bg-[var(--cyber-blue)]/10 rounded border border-[var(--cyber-blue-dim)]">
443443
<div className="text-[var(--cyber-blue)] mb-1">role: "model"</div>
444444
<div className="text-[var(--text-muted)]">
445-
functionCall: read_file({'{'}path: "/package.json"{'}'})
445+
functionCall: read_file({'{'}file_path: "/package.json"{'}'})
446446
</div>
447447
</div>
448448

src/pages/IDEDiffProtocol.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export function IDEDiffProtocol() {
3030

3131
// Diff View 完整交互流程
3232
const diffFlowChart = `flowchart TD
33-
tool([AI 调用<br/>write_file/edit])
33+
tool([AI 调用<br/>write_file/replace])
3434
check_ide{IDE 已连接<br/>且支持 Diff?}
3535
acquire_mutex[获取 diffMutex<br/>单 Diff 锁]
3636
send_open[MCP: openDiff<br/>filePath, newContent]
@@ -425,7 +425,7 @@ this.client.setNotificationHandler(
425425
<div className="bg-gray-800/50 rounded-lg p-4">
426426
<h4 className="font-semibold text-cyan-400 mb-3">触发条件</h4>
427427
<ul className="text-sm text-gray-300 space-y-1">
428-
<li>• AI 调用 <code className="text-cyan-300">write_file</code><code className="text-cyan-300">edit</code> 工具</li>
428+
<li>• AI 调用 <code className="text-cyan-300">write_file</code><code className="text-cyan-300">replace</code> 工具</li>
429429
<li>• IDE 集成已启用(<code className="text-cyan-300">/ide enable</code></li>
430430
<li>• VS Code 插件已安装并连接成功</li>
431431
<li>• 工作区路径匹配 CLI 运行目录</li>

src/pages/LoopDetection.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -981,7 +981,7 @@ Turn 5: Read({ file_path: "/project/src/config.ts " }) // 加空格
981981
模糊匹配:归一化后全部相同 -> 触发检测!
982982
983983
归一化结果:
984-
Turn 1-5: { toolName: "Read", normalizedArgs: { path: "config.ts", offset: "NUMBER" } }
984+
Turn 1-5: { toolName: "Read", normalizedArgs: { file_path: "config.ts", offset: "NUMBER" } }
985985
*/`}
986986
language="typescript"
987987
title="模糊匹配检测"

src/pages/LoopDetectionAnimation.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ private hashToolCall(toolCall: ToolCall): string {
170170
visualData: {
171171
toolCall: {
172172
name: 'read_file',
173-
arguments: { path: '/src/index.ts' }
173+
arguments: { file_path: '/src/index.ts' }
174174
},
175175
hash: 'a3f2b8c1e9d04567'
176176
},

src/pages/LoopDetectionEngineAnimation.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,13 @@ type DetectionLayer = 'tool' | 'content' | 'llm';
4040

4141
const SAMPLE_TOOL_CALLS: Omit<ToolCall, 'hash' | 'timestamp'>[] = [
4242
{ id: 't1', name: 'Read', args: '{"file_path": "/src/app.ts"}' },
43-
{ id: 't2', name: 'Edit', args: '{"file_path": "/src/app.ts", "old": "a", "new": "b"}' },
43+
{ id: 't2', name: 'Edit', args: '{"file_path": "/src/app.ts", "old_string": "a", "new_string": "b"}' },
4444
{ id: 't3', name: 'Read', args: '{"file_path": "/src/app.ts"}' },
45-
{ id: 't4', name: 'Edit', args: '{"file_path": "/src/app.ts", "old": "a", "new": "b"}' },
45+
{ id: 't4', name: 'Edit', args: '{"file_path": "/src/app.ts", "old_string": "a", "new_string": "b"}' },
4646
{ id: 't5', name: 'Read', args: '{"file_path": "/src/app.ts"}' },
47-
{ id: 't6', name: 'Edit', args: '{"file_path": "/src/app.ts", "old": "a", "new": "b"}' },
48-
{ id: 't7', name: 'Edit', args: '{"file_path": "/src/app.ts", "old": "a", "new": "b"}' },
49-
{ id: 't8', name: 'Edit', args: '{"file_path": "/src/app.ts", "old": "a", "new": "b"}' },
47+
{ id: 't6', name: 'Edit', args: '{"file_path": "/src/app.ts", "old_string": "a", "new_string": "b"}' },
48+
{ id: 't7', name: 'Edit', args: '{"file_path": "/src/app.ts", "old_string": "a", "new_string": "b"}' },
49+
{ id: 't8', name: 'Edit', args: '{"file_path": "/src/app.ts", "old_string": "a", "new_string": "b"}' },
5050
];
5151

5252
const SAMPLE_CONTENT = "The function calculates. The function calculates. The function calculates. The function calculates. The function calculates. The function calculates. The function calculates. The function calculates. The function calculates. The function calculates. The function calculates. ";

0 commit comments

Comments
 (0)