From 8bbde047b53c526e8b0f15d6d00606dab7fc8f76 Mon Sep 17 00:00:00 2001 From: Ajax Davis Date: Mon, 12 Jan 2026 03:08:57 +1000 Subject: [PATCH] fix: improve error visibility for agent tool execution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add structured logging for tool calls, results, and errors - Log tool call initiation with input parameters - Distinguish between success and error tool results - Include isError flag in SSE tool_result events - Improve error logging with stack traces and context 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../conversation/[conversationId]/route.ts | 36 ++++++++++++++++++- .../src/lib/ai-agent/tool-executor-agent.ts | 11 +++++- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/apps/web/src/app/api/agents/[id]/conversation/[conversationId]/route.ts b/apps/web/src/app/api/agents/[id]/conversation/[conversationId]/route.ts index 19c493d..89cc1b7 100644 --- a/apps/web/src/app/api/agents/[id]/conversation/[conversationId]/route.ts +++ b/apps/web/src/app/api/agents/[id]/conversation/[conversationId]/route.ts @@ -287,6 +287,14 @@ export async function POST(request: NextRequest, context: RouteContext): Promise // Stream tool calls as they come in and capture their inputs if (chunk.type === 'tool-call') { const input = 'args' in chunk ? chunk.args : chunk.input; + + // Log tool call for debugging + console.log('[Agent] Tool call initiated:', { + toolName: chunk.toolName, + toolCallId: chunk.toolCallId, + input: JSON.stringify(input).slice(0, 500), + }); + // Store tool call with input for later persistence toolCallsMap.set(chunk.toolCallId, { toolCallId: chunk.toolCallId, @@ -320,9 +328,29 @@ export async function POST(request: NextRequest, context: RouteContext): Promise // Send tool results via SSE but don't save yet (save after assistant message for correct order) if (toolResults && toolResults.length > 0) { for (const tr of toolResults) { + // Check if this is an error result (AI SDK wraps errors in the output) + const isError = + tr.output && typeof tr.output === 'object' && 'error' in tr.output; + + // Log tool results for debugging + if (isError) { + console.error('[Agent] Tool execution failed:', { + toolName: tr.toolName, + toolCallId: tr.toolCallId, + error: tr.output, + }); + } else { + console.log('[Agent] Tool execution success:', { + toolName: tr.toolName, + toolCallId: tr.toolCallId, + outputPreview: JSON.stringify(tr.output).slice(0, 200), + }); + } + sendEvent('tool_result', { toolCallId: tr.toolCallId, output: tr.output, + isError, }); // Collect tool results to save after assistant message @@ -412,7 +440,13 @@ export async function POST(request: NextRequest, context: RouteContext): Promise executionTimeMs, }); } catch (error) { - console.error('Agent conversation error:', error); + // Log detailed error for debugging + console.error('[Agent] Conversation stream error:', { + error: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined, + agentId: agent.id, + conversationId: conversation.id, + }); sendEvent('error', { message: error instanceof Error ? error.message : 'Unknown error', }); diff --git a/apps/web/src/lib/ai-agent/tool-executor-agent.ts b/apps/web/src/lib/ai-agent/tool-executor-agent.ts index e161092..d002151 100644 --- a/apps/web/src/lib/ai-agent/tool-executor-agent.ts +++ b/apps/web/src/lib/ai-agent/tool-executor-agent.ts @@ -144,10 +144,19 @@ export function createToolDefinition( }); if (!result.success) { + // Log detailed error for debugging + console.error('[Tool execute] FAILED:', sanitizedName, { + error: result.error, + executionTimeMs: result.executionTimeMs, + params: JSON.stringify(params).slice(0, 200), + }); throw new Error(result.error || 'Package execution failed'); } - console.log('[Tool execute] Result:', result.output); + console.log('[Tool execute] Success:', sanitizedName, { + executionTimeMs: result.executionTimeMs, + outputPreview: JSON.stringify(result.output).slice(0, 200), + }); return result.output; }, };