diff --git a/src/main/ipc.ts b/src/main/ipc.ts index 4eb4997..2395161 100644 --- a/src/main/ipc.ts +++ b/src/main/ipc.ts @@ -82,15 +82,21 @@ export function setupIPC(): void { // ── Tool Calling IPC ── ipcMain.handle('tool:execute', async (_, toolName: string, args: Record) => { - 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}` }; + try { + console.log('[IPC] tool:execute', toolName, JSON.stringify(args || {}).slice(0, 200)); + switch (toolName) { + case 'read_file': return await handleReadFile(args as { path: string; encoding?: string; start_line?: number; end_line?: number }); + case 'write_file': return await handleWriteFile(args as { path: string; content: string; encoding?: string }); + case 'list_directory': return await handleListDir(args as { path: string; recursive?: boolean; max_depth?: number; include_hidden?: boolean; filter_extension?: string }); + case 'search_files': return await handleSearchFiles(args as { path: string; query: string; search_type?: string; case_sensitive?: boolean; max_results?: number; file_extensions?: string[] }); + case 'create_directory': return await handleCreateDir(args as { path: string }); + case 'delete_file': return await handleDeleteFile(args as { path: string; recursive?: boolean }); + case 'run_command': return await handleRunCommand(args as { command: string; cwd?: string; timeout?: number }); + default: return { success: false, error: `未知工具: ${toolName}` }; + } + } catch (err) { + console.error('[IPC] tool:execute 异常:', toolName, err); + return { success: false, error: (err as Error).message || '工具执行异常' }; } }); diff --git a/src/renderer/services/agent-engine.ts b/src/renderer/services/agent-engine.ts index 21f9183..77662cf 100644 --- a/src/renderer/services/agent-engine.ts +++ b/src/renderer/services/agent-engine.ts @@ -283,9 +283,16 @@ export async function runAgentLoop( try { // 工具执行超时保护 console.log('[AgentEngine] 执行工具:', call.function.name); + logInfo(`执行工具: ${call.function.name}`, JSON.stringify(call.function.arguments)); const result = await Promise.race([ - executeTool(call.function.name, call.function.arguments), - new Promise((_, reject) => + executeTool(call.function.name, call.function.arguments).then(r => { + console.log('[AgentEngine] executeTool resolve:', call.function.name, r); + return r; + }).catch(err => { + console.error('[AgentEngine] executeTool reject:', call.function.name, err); + return { success: false, error: err?.message || String(err) } as ToolResult; + }), + new Promise((_, reject) => setTimeout(() => reject(new Error('工具执行超时(30秒)')), TOOL_EXEC_TIMEOUT) ) ]); diff --git a/src/renderer/services/tool-registry.ts b/src/renderer/services/tool-registry.ts index a8dca20..73b8c51 100644 --- a/src/renderer/services/tool-registry.ts +++ b/src/renderer/services/tool-registry.ts @@ -159,10 +159,19 @@ export async function executeTool(toolName: string, args: Record((_, reject) => + setTimeout(() => reject(new Error(`工具 ${toolName} IPC 超时(25秒)`)), 25000) + ) + ]); + console.log('[ToolRegistry] 执行完成:', toolName, result); return result; } catch (err) { logError(`工具异常: ${toolName}`, (err as Error).message); + console.error('[ToolRegistry] 执行异常:', toolName, err); return { success: false, error: (err as Error).message }; } }