From 6ecb64f80224e1eaf314d82d1b04b108081b6030 Mon Sep 17 00:00:00 2001 From: vikingowl Date: Thu, 1 Jan 2026 07:32:26 +0100 Subject: [PATCH] feat: styled search results in tool call dropdown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Parse search results into structured data with SearchResultItem type - Render expanded results as clickable cards with: - Numbered rank badges - Linked titles (open in new tab) - Truncated URLs - Snippets when available - Fallback to raw text for non-search results - Proper light/dark mode styling 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../components/chat/ToolCallDisplay.svelte | 53 +++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/frontend/src/lib/components/chat/ToolCallDisplay.svelte b/frontend/src/lib/components/chat/ToolCallDisplay.svelte index 86dd9c6..e66d37a 100644 --- a/frontend/src/lib/components/chat/ToolCallDisplay.svelte +++ b/frontend/src/lib/components/chat/ToolCallDisplay.svelte @@ -90,10 +90,27 @@ return labels[key] || key; } + /** Search result item */ + interface SearchResultItem { + rank: number; + title: string; + url: string; + snippet: string; + } + + /** Parsed result with structured data */ + interface ParsedResult { + type: 'search' | 'location' | 'fetch' | 'json' | 'text' | 'empty'; + summary: string; + full: string; + searchResults?: SearchResultItem[]; + query?: string; + } + /** * Parse result content (could be JSON or plain text) */ - function parseResult(result: string | undefined): { type: string; summary: string; full: string } { + function parseResult(result: string | undefined): ParsedResult { if (!result) return { type: 'empty', summary: 'No result', full: '' }; try { @@ -105,7 +122,9 @@ return { type: 'search', summary: `Found ${count} results for "${json.query}"`, - full: result + full: result, + searchResults: json.results as SearchResultItem[], + query: json.query }; } @@ -295,7 +314,35 @@ {#if isResultExpanded && hasResult && parsed.full}
-
{parsed.full.length > 10000 ? parsed.full.substring(0, 10000) + '\n\n... (truncated)' : parsed.full}
+ {#if parsed.type === 'search' && parsed.searchResults} + + + {:else} + +
{parsed.full.length > 10000 ? parsed.full.substring(0, 10000) + '\n\n... (truncated)' : parsed.full}
+ {/if}
{/if}