]> git.djapps.eu Git - pkg/ggml/sources/llama.cpp/blob
424c794d0baebf697ea49cacafbb74cf6e6e33ed
[pkg/ggml/sources/llama.cpp] /
1 <script lang="ts">
2 import { parseReadMediaMeta } from './parsers/read-media';
3 import ToolCallBlock from './ToolCallBlock.svelte';
4 import { ATTACHMENT_SAVED_REGEX } from '$lib/constants/agentic';
5 import { AttachmentType, MimeTypeAudio } from '$lib/enums';
6 import type { DatabaseMessageExtraAudioFile, DatabaseMessageExtraImageFile } from '$lib/types';
7 import { type AgenticSection } from '$lib/utils';
8 import { createBase64DataUrl } from '$lib/utils/data-url';
9
10 interface Props {
11 section: AgenticSection;
12 open: boolean;
13 isStreaming: boolean;
14 onToggle?: () => void;
15 }
16
17 let { isStreaming, onToggle, open, section }: Props = $props();
18
19 const readMediaMeta = $derived(parseReadMediaMeta(section));
20
21 // extractBase64Attachments swapped the data URI line for [Attachment saved: name]
22 // and moved the bytes to the message extras, so the name is the only link back
23 const mediaAttachment = $derived.by(() => {
24 const extras = section.toolResultExtras;
25
26 if (!extras || extras.length === 0) return null;
27
28 const match = section.toolResult?.match(ATTACHMENT_SAVED_REGEX);
29
30 if (!match) return null;
31
32 const attachmentName = match[1];
33
34 return (
35 extras.find(
36 (e): e is DatabaseMessageExtraImageFile | DatabaseMessageExtraAudioFile =>
37 (e.type === AttachmentType.IMAGE || e.type === AttachmentType.AUDIO) &&
38 e.name === attachmentName
39 ) ?? null
40 );
41 });
42
43 const audioMimeType = $derived(readMediaMeta?.mimeType ?? MimeTypeAudio.MP3_MPEG);
44 </script>
45
46 <ToolCallBlock {section} {open} {isStreaming} meta={readMediaMeta} {onToggle}>
47 {#snippet titleSnippet()}
48 <span class="text-muted-foreground">Read media </span>
49 <span class="font-mono">{readMediaMeta?.fileName}</span>
50 {/snippet}
51
52 {#snippet children(_meta, _ctx)}
53 {#if section.toolResult}
54 {#if !mediaAttachment}
55 <div class="rounded bg-muted/20 p-2 text-xs text-muted-foreground/70 italic">
56 Media attachment not found in message extras
57 </div>
58 {:else if mediaAttachment.type === AttachmentType.AUDIO}
59 <div class="mt-2">
60 <audio controls class="w-full rounded-lg">
61 <source
62 src={createBase64DataUrl(audioMimeType, mediaAttachment.base64Data)}
63 type={audioMimeType}
64 />
65 Your browser does not support the audio element.
66 </audio>
67 </div>
68 {:else}
69 <div class="mt-2">
70 <img
71 src={mediaAttachment.base64Url}
72 alt={readMediaMeta?.fileName ?? 'media'}
73 class="max-h-[60vh] max-w-full rounded-lg object-contain shadow-lg"
74 loading="lazy"
75 />
76 </div>
77 {/if}
78
79 {#if readMediaMeta?.sizeBytes || readMediaMeta?.mimeType}
80 <div class="mt-2 flex gap-4 text-xs text-muted-foreground">
81 {#if readMediaMeta?.sizeBytes}
82 <span>Size: {readMediaMeta.sizeBytes} bytes</span>
83 {/if}
84 {#if readMediaMeta?.mimeType}
85 <span>MIME: {readMediaMeta.mimeType}</span>
86 {/if}
87 </div>
88 {/if}
89
90 {#if readMediaMeta?.path}
91 <div class="mt-1 font-mono text-xs text-muted-foreground/60">{readMediaMeta.path}</div>
92 {/if}
93 {:else}
94 <div class="rounded bg-muted/20 p-2 text-xs text-muted-foreground/70 italic">
95 Waiting for media data...
96 </div>
97 {/if}
98 {/snippet}
99 </ToolCallBlock>