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 }; + }); + }
- {#each sections as section, index (index)} + {#each sectionsParsed as section, index (index)} {#if section.type === AgenticSectionType.TEXT}
@@ -144,26 +178,19 @@ {/if}
{#if section.toolResult} -
- -
{section.toolResult}
+
+ {#each section.parsedLines as line, i (i)} +
{line.text}
+ {#if line.image} + {line.image.name} + {/if} + {/each}
- - {#if message?.extra} - {@const images = message.extra.filter((e) => e.type === AttachmentType.IMAGE)} - {#if images.length > 0} -
- {#each images as image (image.name)} - {image.name} - {/each} -
- {/if} - {/if} {:else if isPending}
Waiting for result...