diff --git a/tools/server/webui/src/lib/components/app/chat/ChatMessages/ChatMessageAgenticContent.svelte b/tools/server/webui/src/lib/components/app/chat/ChatMessages/ChatMessageAgenticContent.svelte index 49d1a62c80..f1810412ff 100644 --- a/tools/server/webui/src/lib/components/app/chat/ChatMessages/ChatMessageAgenticContent.svelte +++ b/tools/server/webui/src/lib/components/app/chat/ChatMessages/ChatMessageAgenticContent.svelte @@ -9,7 +9,7 @@ import { AgenticSectionType, AttachmentType } from '$lib/enums'; import { formatJsonPretty } from '$lib/utils'; import { parseAgenticContent, type AgenticSection } from '$lib/utils/agentic'; - import type { DatabaseMessage } from '$lib/types/database'; + import type { DatabaseMessage, DatabaseMessageExtraImageFile } from '$lib/types/database'; interface Props { /** Optional database message for context */ @@ -28,6 +28,16 @@ const showToolCallInProgress = $derived(config().showToolCallInProgress as boolean); const showThoughtInProgress = $derived(config().showThoughtInProgress as boolean); + // Parse toolResults with images only when sections or message.extra change + const sectionsParsed = $derived( + sections.map((section) => ({ + ...section, + parsedLines: section.toolResult + ? parseToolResultWithImages(section.toolResult, message?.extra) + : [] + })) + ); + function getDefaultExpanded(section: AgenticSection): boolean { if ( section.type === AgenticSectionType.TOOL_CALL_PENDING || @@ -56,10 +66,34 @@ expandedStates[index] = !currentState; } + + type ToolResultLine = { + text: string; + image?: DatabaseMessageExtraImageFile; + }; + + function parseToolResultWithImages( + toolResult: string, + extras?: DatabaseMessage['extra'] + ): ToolResultLine[] { + const lines = toolResult.split('\n'); + return lines.map((line) => { + const match = line.match(/\[Attachment saved: ([^\]]+)\]/); + if (!match || !extras) return { text: line }; + + const attachmentName = match[1]; + const image = extras.find( + (e): e is DatabaseMessageExtraImageFile => + e.type === AttachmentType.IMAGE && e.name === attachmentName + ); + + return { text: line, image }; + }); + }
{section.toolResult}
+