2 // Fall-through renderer for tool calls without a dedicated block.
3 // Renders section.toolArgs / section.toolResult directly using the
4 // shared chrome shell.
6 import ToolCallBlock from './ToolCallBlock.svelte';
7 import { Loader2 } from '@lucide/svelte';
8 import { MarkdownContent, SyntaxHighlightedCode } from '$lib/components/app';
9 import { MAX_HEIGHT_CODE_BLOCK } from '$lib/constants';
10 import { getBuiltinToolUi } from '$lib/constants/built-in-tools';
11 import { FileTypeText, ToolResultKind } from '$lib/enums';
12 import type { DatabaseMessageExtra } from '$lib/types';
17 parseToolResultWithImages
21 section: AgenticSection;
24 attachments?: DatabaseMessageExtra[];
25 onToggle?: () => void;
28 let { attachments, isStreaming, onToggle, open, section }: Props = $props();
30 const title = $derived(getBuiltinToolUi(section.toolName)?.label ?? section.toolName ?? '');
31 const outputKind = $derived(classifyToolResult(section.toolResult));
32 const parsedLines = $derived(
33 section.toolResult ? parseToolResultWithImages(section.toolResult, attachments) : []
37 <ToolCallBlock {section} {open} {isStreaming} meta={null} {title} {onToggle}>
38 {#snippet children(_meta, ctx)}
39 {#if ctx.isStreamingCall}
40 <div class="mb-2 flex items-center gap-2 text-xs text-muted-foreground/70">
43 <Loader2 class="h-3 w-3 animate-spin" />
46 {#if section.toolArgs}
47 <SyntaxHighlightedCode
48 code={formatJsonPretty(section.toolArgs)}
49 language={FileTypeText.JSON}
50 maxHeight={MAX_HEIGHT_CODE_BLOCK}
51 streaming={ctx.isCodeStreaming}
53 {:else if ctx.isStreaming}
54 <div class="rounded bg-muted/20 p-2 text-xs text-muted-foreground/70 italic">
55 Receiving arguments...
59 class="rounded bg-yellow-500/10 p-2 text-xs text-yellow-600 italic dark:text-yellow-400"
61 Response was truncated
65 {@const showInput = Boolean(section.toolArgs)}
67 <div class="mb-1.5 flex items-center gap-2 text-xs text-muted-foreground/70">
70 <SyntaxHighlightedCode
71 code={formatJsonPretty(section.toolArgs ?? '')}
72 language={FileTypeText.JSON}
73 maxHeight={MAX_HEIGHT_CODE_BLOCK}
74 streaming={ctx.isCodeStreaming}
79 ? 'mt-4 mb-1.5 flex items-center gap-2 text-xs text-muted-foreground/70'
80 : 'mb-1.5 flex items-center gap-2 text-xs text-muted-foreground/70'}
84 <Loader2 class="h-3 w-3 animate-spin" />
88 <div class="rounded bg-muted/20 p-2 text-xs text-muted-foreground/70 italic">
91 {:else if section.toolResult}
92 {#if outputKind === ToolResultKind.JSON}
93 <SyntaxHighlightedCode
94 code={formatJsonPretty(section.toolResult)}
95 language={FileTypeText.JSON}
96 maxHeight={MAX_HEIGHT_CODE_BLOCK}
98 {:else if outputKind === ToolResultKind.MARKDOWN}
99 <MarkdownContent content={section.toolResult} {attachments} />
101 <div class="overflow-auto">
102 {#each parsedLines as line, i (i)}
103 <div class="font-mono text-[11px] leading-relaxed whitespace-pre-wrap">
108 src={line.image.base64Url}
109 alt={line.image.name}
110 class="mt-2 mb-2 h-auto max-w-full rounded-lg"
118 <div class="rounded bg-muted/20 p-2 text-xs text-muted-foreground/70 italic">No output</div>