From 29b80b1905987093dc7ffb7b26b1f55f0183e7d5 Mon Sep 17 00:00:00 2001 From: vadymtrunov Date: Sun, 15 Feb 2026 11:43:43 +0100 Subject: [PATCH] fix: parse serialized JSON content in subagent Task results Subagent (Task/Explore) results were rendered as raw JSON `[{"type":"text","text":"..."}]` with literal `\n` instead of formatted markdown. The root cause was that the API sometimes returns content blocks as a serialized JSON string rather than a parsed array. The existing `Array.isArray()` check missed this case and fell through to `String()`, displaying raw JSON. Now the Task tool result handler tries to JSON.parse string content before checking for array structure, matching the pattern already used by exit_plan_mode. Co-Authored-By: Claude Opus 4.6 --- .../chat/tools/configs/toolConfigs.ts | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/components/chat/tools/configs/toolConfigs.ts b/src/components/chat/tools/configs/toolConfigs.ts index 8fe1608..994f0df 100644 --- a/src/components/chat/tools/configs/toolConfigs.ts +++ b/src/components/chat/tools/configs/toolConfigs.ts @@ -436,16 +436,28 @@ export const TOOL_CONFIGS: Record = { getContentProps: (result) => { // Handle agent results which may have complex structure if (result && result.content) { + let content = result.content; + // If content is a JSON string, try to parse it (agent results may arrive serialized) + if (typeof content === 'string') { + try { + const parsed = JSON.parse(content); + if (Array.isArray(parsed)) { + content = parsed; + } + } catch { + // Not JSON — use as-is + return { content }; + } + } // If content is an array (typical for agent responses with multiple text blocks) - if (Array.isArray(result.content)) { - const textContent = result.content + if (Array.isArray(content)) { + const textContent = content .filter((item: any) => item.type === 'text') .map((item: any) => item.text) .join('\n\n'); return { content: textContent || 'No response text' }; } - // If content is already a string - return { content: String(result.content) }; + return { content: String(content) }; } // Fallback to string representation return { content: String(result || 'No response') };