]> git.djapps.eu Git - pkg/ggml/sources/llama.cpp/blob
47954032117a3cb87b7c093d91c9f5f98b378937
[pkg/ggml/sources/llama.cpp] /
1 <script lang="ts">
2 import { Plus, File, MessageSquare, Zap, FolderOpen } from '@lucide/svelte';
3 import * as DropdownMenu from '$lib/components/ui/dropdown-menu';
4 import * as Tooltip from '$lib/components/ui/tooltip';
5 import { buttonVariants } from '$lib/components/ui/button';
6 import { cn } from '$lib/components/ui/utils';
7 import {
8 ATTACHMENT_FILE_ITEMS,
9 ATTACHMENT_TOOLTIP_TEXT,
10 TOOLTIP_DELAY_DURATION
11 } from '$lib/constants';
12 import {
13 ChatFormActionAddToolsSubmenu,
14 ChatFormActionAddMcpServersSubmenu
15 } from '$lib/components/app';
16 import { useAttachmentMenu } from '$lib/hooks/use-attachment-menu.svelte';
17
18 interface Props {
19 class?: string;
20 disabled?: boolean;
21 hasAudioModality?: boolean;
22 hasVideoModality?: boolean;
23 hasVisionModality?: boolean;
24 hasMcpPromptsSupport?: boolean;
25 hasMcpResourcesSupport?: boolean;
26 onFileUpload?: () => void;
27 onSystemPromptClick?: () => void;
28 onMcpPromptClick?: () => void;
29 onMcpSettingsClick?: () => void;
30 onMcpResourcesClick?: () => void;
31 }
32
33 let {
34 class: className = '',
35 disabled = false,
36 hasAudioModality = false,
37 hasVideoModality = false,
38 hasVisionModality = false,
39 hasMcpPromptsSupport = false,
40 hasMcpResourcesSupport = false,
41 onFileUpload,
42 onSystemPromptClick,
43 onMcpPromptClick,
44 onMcpSettingsClick,
45 onMcpResourcesClick
46 }: Props = $props();
47
48 let dropdownOpen = $state(false);
49
50 function handleMcpSettingsClick() {
51 dropdownOpen = false;
52 onMcpSettingsClick?.();
53 }
54
55 const attachmentMenu = useAttachmentMenu(
56 () => ({
57 hasVisionModality,
58 hasAudioModality,
59 hasVideoModality,
60 hasMcpPromptsSupport,
61 hasMcpResourcesSupport
62 }),
63 () => ({ onFileUpload, onSystemPromptClick, onMcpPromptClick, onMcpResourcesClick }),
64 () => {
65 dropdownOpen = false;
66 }
67 );
68 </script>
69
70 <div class="flex items-center gap-1 {className}">
71 <DropdownMenu.Root bind:open={dropdownOpen}>
72 <Tooltip.Root>
73 <Tooltip.Trigger>
74 {#snippet child({ props })}
75 <DropdownMenu.Trigger
76 {...props}
77 class={cn(
78 buttonVariants({ variant: 'secondary' }),
79 'file-upload-button h-8 w-8 cursor-pointer rounded-full p-0'
80 )}
81 {disabled}
82 >
83 <span class="sr-only">{ATTACHMENT_TOOLTIP_TEXT}</span>
84
85 <Plus class="h-4 w-4" />
86 </DropdownMenu.Trigger>
87 {/snippet}
88 </Tooltip.Trigger>
89
90 <Tooltip.Content>
91 <p>{ATTACHMENT_TOOLTIP_TEXT}</p>
92 </Tooltip.Content>
93 </Tooltip.Root>
94
95 <DropdownMenu.Content align="start" class="w-48">
96 <DropdownMenu.Sub>
97 <DropdownMenu.SubTrigger class="flex cursor-pointer items-center gap-2">
98 <File class="h-4 w-4" />
99
100 <span>Add files</span>
101 </DropdownMenu.SubTrigger>
102
103 <DropdownMenu.SubContent class="w-48">
104 {#each ATTACHMENT_FILE_ITEMS as item (item.id)}
105 {@const enabled = attachmentMenu.isItemEnabled(item.enabledWhen)}
106 {#if enabled}
107 <DropdownMenu.Item
108 class="{item.class ?? ''} flex cursor-pointer items-center gap-2"
109 onclick={() => attachmentMenu.callbacks[item.action]()}
110 >
111 <item.icon class="h-4 w-4" />
112
113 <span>{item.label}</span>
114 </DropdownMenu.Item>
115 {:else if item.disabledTooltip}
116 <Tooltip.Root delayDuration={TOOLTIP_DELAY_DURATION}>
117 <Tooltip.Trigger tabindex={-1}>
118 {#snippet child({ props })}
119 <div {...props} class="cursor-default">
120 <DropdownMenu.Item
121 class="{item.class ?? ''} flex items-center gap-2"
122 disabled
123 >
124 <item.icon class="h-4 w-4" />
125
126 <span>{item.label}</span>
127 </DropdownMenu.Item>
128 </div>
129 {/snippet}
130 </Tooltip.Trigger>
131
132 <Tooltip.Content side="right">
133 <p>{item.disabledTooltip}</p>
134 </Tooltip.Content>
135 </Tooltip.Root>
136 {/if}
137 {/each}
138 </DropdownMenu.SubContent>
139 </DropdownMenu.Sub>
140
141 <DropdownMenu.Item
142 class="flex cursor-pointer items-center gap-2"
143 onclick={onSystemPromptClick}
144 >
145 <MessageSquare class="h-4 w-4" />
146
147 <span>System Message</span>
148 </DropdownMenu.Item>
149
150 <ChatFormActionAddToolsSubmenu />
151
152 <ChatFormActionAddMcpServersSubmenu onMcpSettingsClick={handleMcpSettingsClick} />
153
154 {#if hasMcpPromptsSupport}
155 <DropdownMenu.Separator />
156
157 <DropdownMenu.Item
158 class="flex cursor-pointer items-center gap-2"
159 onclick={onMcpPromptClick}
160 >
161 <Zap class="h-4 w-4" />
162
163 <span>MCP Prompt</span>
164 </DropdownMenu.Item>
165 {/if}
166
167 {#if hasMcpResourcesSupport}
168 <DropdownMenu.Item
169 class="flex cursor-pointer items-center gap-2"
170 onclick={onMcpResourcesClick}
171 >
172 <FolderOpen class="h-4 w-4" />
173
174 <span>MCP Resources</span>
175 </DropdownMenu.Item>
176 {/if}
177 </DropdownMenu.Content>
178 </DropdownMenu.Root>
179 </div>