From eea28d59c91d8c848cebf4307cd00f2b223bb92d Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Fri, 28 Nov 2025 18:52:13 +0000 Subject: [PATCH] fix(server): extract tool result content from SDK blocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Claude SDK returns tool_result blocks with `content` as a string containing the actual command output. Previously, handleToolResult only set output when there were file changes (entry?.files), missing all other tool outputs like shell command results. Now buildToolOutput extracts block.content and wraps it as { result: { output: content } } which the frontend parsers expect. This fixes "No additional details available" when expanding tool calls. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../server/agent/providers/claude-agent.ts | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/packages/server/src/server/agent/providers/claude-agent.ts b/packages/server/src/server/agent/providers/claude-agent.ts index f44df42a7..e4747ae85 100644 --- a/packages/server/src/server/agent/providers/claude-agent.ts +++ b/packages/server/src/server/agent/providers/claude-agent.ts @@ -1012,6 +1012,10 @@ class ClaudeAgentSession implements AgentSession { const server = entry?.server ?? block.server ?? "tool"; const tool = entry?.name ?? block.tool_name ?? "tool"; const status = block.is_error ? "failed" : "completed"; + + // Extract output from block.content (SDK always returns content as string) + const output = this.buildToolOutput(block, entry); + this.pushToolCall( { server, @@ -1021,7 +1025,7 @@ class ClaudeAgentSession implements AgentSession { displayName: this.buildToolDisplayName(entry), kind: this.getToolKind(entry?.classification), input: entry?.input, - output: !block.is_error && entry?.files?.length ? { files: entry.files } : undefined, + output, error: block.is_error ? block : undefined, }, items @@ -1031,6 +1035,29 @@ class ClaudeAgentSession implements AgentSession { } } + private buildToolOutput( + block: ClaudeContentChunk, + entry: ToolUseCacheEntry | undefined + ): Record | undefined { + if (block.is_error) { + return undefined; + } + + const result: Record = {}; + + // SDK tool_result blocks have content as a string + if (typeof block.content === "string" && block.content.length > 0) { + result.result = { output: block.content }; + } + + // Preserve file changes tracked during tool execution + if (entry?.files?.length) { + result.files = entry.files; + } + + return Object.keys(result).length > 0 ? result : undefined; + } + private mapPartialEvent(event: SDKPartialAssistantMessage["event"]): AgentTimelineItem[] { if (event.type === "content_block_start" && (event.content_block as ClaudeContentChunk | undefined)?.type === "tool_use") { const block = event.content_block as ClaudeContentChunk;