feat: v3.0 Tool Calling — AI 本地文件操作系统

新增文件:
- src/main/tool-security.ts: 路径白名单/黑名单、命令安全检查
- src/main/tool-handlers.ts: 7个工具实现(read/write/list/search/create/delete/run)
- src/renderer/services/tool-registry.ts: 工具注册调度中心
- src/renderer/services/agent-engine.ts: Agent Loop 流式多轮工具调用引擎
- src/renderer/components/tool-confirm-modal.ts: 高风险操作确认对话框

修改文件:
- types.d.ts: 新增 ToolCall/ToolResult/ToolCallRecord 等类型
- ollama.ts: chatStream 支持 tools 参数
- ipc.ts: 新增 tool:execute/getConfig/setAllowedDirs IPC
- preload.ts: 暴露 tool API
- chat-area.ts: 渲染工具调用卡片
- input-area.ts: 集成 Agent Loop 引擎
- settings-modal.ts: 工具调用开关设置
- index.html: 工具调用设置面板 + 确认对话框 HTML
- style.css: 工具调用卡片、确认对话框样式
- main.ts: 初始化工具调用配置
This commit is contained in:
thzxx
2026-04-06 13:29:43 +08:00
parent 0a1397771e
commit 5bfb137a8a
15 changed files with 1609 additions and 6 deletions
+33
View File
@@ -7,6 +7,16 @@ import * as fs from 'fs';
import * as path from 'path';
import { mainWindow } from './main.js';
import { showNotification } from './utils.js';
import {
handleReadFile,
handleWriteFile,
handleListDir,
handleSearchFiles,
handleCreateDir,
handleDeleteFile,
handleRunCommand
} from './tool-handlers.js';
import { getAllowedDirs, getBlockedDirs, setAllowedDirs } from './tool-security.js';
export function setupIPC(): void {
ipcMain.handle('dialog:openFile', async (_, options?: { filters?: Array<{ name: string; extensions: string[] }> }) => {
@@ -69,4 +79,27 @@ export function setupIPC(): void {
shell.openExternal(url);
}
});
// ── Tool Calling IPC ──
ipcMain.handle('tool:execute', async (_, toolName: string, args: Record<string, unknown>) => {
switch (toolName) {
case 'read_file': return handleReadFile(args as { path: string; encoding?: string; start_line?: number; end_line?: number });
case 'write_file': return handleWriteFile(args as { path: string; content: string; encoding?: string });
case 'list_directory': return handleListDir(args as { path: string; recursive?: boolean; max_depth?: number; include_hidden?: boolean; filter_extension?: string });
case 'search_files': return handleSearchFiles(args as { path: string; query: string; search_type?: string; case_sensitive?: boolean; max_results?: number; file_extensions?: string[] });
case 'create_directory': return handleCreateDir(args as { path: string });
case 'delete_file': return handleDeleteFile(args as { path: string; recursive?: boolean });
case 'run_command': return handleRunCommand(args as { command: string; cwd?: string; timeout?: number });
default: return { success: false, error: `未知工具: ${toolName}` };
}
});
ipcMain.handle('tool:getConfig', () => ({
allowedDirs: getAllowedDirs(),
blockedDirs: getBlockedDirs()
}));
ipcMain.handle('tool:setAllowedDirs', (_, dirs: string[]) => {
setAllowedDirs(dirs);
});
}