]> git.djapps.eu Git - pkg/ggml/sources/llama.cpp/blob
f7115b817127e6f65d6d8c7961ef7177b0457876
[pkg/ggml/sources/llama.cpp] /
1 <script lang="ts">
2 import { Plus } from '@lucide/svelte';
3 import { Button } from '$lib/components/ui/button';
4 import * as Tooltip from '$lib/components/ui/tooltip';
5 import * as Sheet from '$lib/components/ui/sheet';
6 import { TOOLTIP_DELAY_DURATION } from '$lib/constants';
7 import {
8 ATTACHMENT_FILE_ITEMS,
9 ATTACHMENT_EXTRA_ITEMS,
10 ATTACHMENT_MCP_ITEMS,
11 ATTACHMENT_TOOLTIP_TEXT
12 } from '$lib/constants/attachment-menu';
13 import { ChatFormActionToolsSubmenu, ChatFormActionMcpServersSubmenu } from '$lib/components/app';
14 import { useAttachmentMenu } from '$lib/hooks/use-attachment-menu.svelte';
15 import { AttachmentMenuItemId } from '$lib/enums';
16
17 interface Props {
18 class?: string;
19 disabled?: boolean;
20 hasAudioModality?: boolean;
21 hasVisionModality?: boolean;
22 hasMcpPromptsSupport?: boolean;
23 hasMcpResourcesSupport?: boolean;
24 onFileUpload?: () => void;
25 onSystemPromptClick?: () => void;
26 onMcpPromptClick?: () => void;
27 onMcpSettingsClick?: () => void;
28 onMcpResourcesClick?: () => void;
29 }
30
31 let {
32 class: className = '',
33 disabled = false,
34 hasAudioModality = false,
35 hasVisionModality = false,
36 hasMcpPromptsSupport = false,
37 hasMcpResourcesSupport = false,
38 onFileUpload,
39 onSystemPromptClick,
40 onMcpPromptClick,
41 onMcpSettingsClick,
42 onMcpResourcesClick
43 }: Props = $props();
44
45 let sheetOpen = $state(false);
46
47 const attachmentMenu = useAttachmentMenu(
48 () => ({ hasVisionModality, hasAudioModality, hasMcpPromptsSupport, hasMcpResourcesSupport }),
49 () => ({ onFileUpload, onSystemPromptClick, onMcpPromptClick, onMcpResourcesClick }),
50 () => {
51 sheetOpen = false;
52 }
53 );
54
55 function handleMcpSettingsClick() {
56 sheetOpen = false;
57 onMcpSettingsClick?.();
58 }
59
60 const sheetItemClass =
61 'flex w-full items-center gap-3 rounded-md px-3 py-2.5 text-left text-sm transition-colors hover:bg-accent active:bg-accent disabled:cursor-not-allowed disabled:opacity-50';
62 </script>
63
64 <div class="flex items-center gap-1 {className}">
65 <Sheet.Root bind:open={sheetOpen}>
66 <Button
67 class="file-upload-button h-8 w-8 rounded-full p-0"
68 {disabled}
69 variant="secondary"
70 type="button"
71 onclick={() => (sheetOpen = true)}
72 >
73 <span class="sr-only">{ATTACHMENT_TOOLTIP_TEXT}</span>
74
75 <Plus class="h-4 w-4" />
76 </Button>
77
78 <Sheet.Content side="bottom" class="max-h-[85vh] gap-0 overflow-y-auto">
79 <Sheet.Header>
80 <Sheet.Title>Add to chat</Sheet.Title>
81
82 <Sheet.Description class="sr-only">
83 Add files, system prompt or configure MCP servers
84 </Sheet.Description>
85 </Sheet.Header>
86
87 <div class="flex flex-col gap-1 px-1.5 pb-2">
88 {#each ATTACHMENT_FILE_ITEMS as item (item.id)}
89 {@const enabled = attachmentMenu.isItemEnabled(item.enabledWhen)}
90 {#if enabled}
91 <button
92 type="button"
93 class={sheetItemClass}
94 onclick={() => attachmentMenu.callbacks[item.action]()}
95 >
96 <item.icon class="h-4 w-4 shrink-0" />
97
98 <span>{item.label}</span>
99 </button>
100 {:else if item.disabledTooltip}
101 <Tooltip.Root delayDuration={TOOLTIP_DELAY_DURATION}>
102 <Tooltip.Trigger>
103 <button type="button" class={sheetItemClass} disabled>
104 <item.icon class="h-4 w-4 shrink-0" />
105
106 <span>{item.label}</span>
107 </button>
108 </Tooltip.Trigger>
109
110 <Tooltip.Content side="right">
111 <p>{item.disabledTooltip}</p>
112 </Tooltip.Content>
113 </Tooltip.Root>
114 {/if}
115 {/each}
116
117 {#if !attachmentMenu.isItemEnabled('hasVisionModality')}
118 {@const pdfItem = ATTACHMENT_FILE_ITEMS.find((i) => i.id === AttachmentMenuItemId.PDF)}
119 {#if pdfItem}
120 <Tooltip.Root delayDuration={TOOLTIP_DELAY_DURATION}>
121 <Tooltip.Trigger>
122 <button
123 type="button"
124 class={sheetItemClass}
125 onclick={() => attachmentMenu.callbacks[pdfItem.action]()}
126 >
127 <pdfItem.icon class="h-4 w-4 shrink-0" />
128
129 <span>{pdfItem.label}</span>
130 </button>
131 </Tooltip.Trigger>
132
133 <Tooltip.Content side="right">
134 <p>PDFs will be converted to text. Image-based PDFs may not work properly.</p>
135 </Tooltip.Content>
136 </Tooltip.Root>
137 {/if}
138 {/if}
139
140 {#each ATTACHMENT_EXTRA_ITEMS as item (item.id)}
141 {#if item.id === AttachmentMenuItemId.SYSTEM_MESSAGE}
142 <Tooltip.Root delayDuration={TOOLTIP_DELAY_DURATION}>
143 <Tooltip.Trigger>
144 <button
145 type="button"
146 class={sheetItemClass}
147 onclick={() => attachmentMenu.callbacks[item.action]()}
148 >
149 <item.icon class="h-4 w-4 shrink-0" />
150
151 <span>{item.label}</span>
152 </button>
153 </Tooltip.Trigger>
154
155 <Tooltip.Content side="right">
156 <p>{attachmentMenu.getSystemMessageTooltip()}</p>
157 </Tooltip.Content>
158 </Tooltip.Root>
159 {/if}
160 {/each}
161
162 <div class="my-2 border-t"></div>
163
164 <ChatFormActionToolsSubmenu />
165
166 <ChatFormActionMcpServersSubmenu onMcpSettingsClick={handleMcpSettingsClick} />
167
168 {#each ATTACHMENT_MCP_ITEMS as item (item.id)}
169 {#if attachmentMenu.isItemVisible(item.visibleWhen)}
170 <button
171 type="button"
172 class={sheetItemClass}
173 onclick={() => attachmentMenu.callbacks[item.action]()}
174 >
175 <item.icon class="h-4 w-4 shrink-0" />
176
177 <span>{item.label}</span>
178 </button>
179 {/if}
180 {/each}
181 </div>
182 </Sheet.Content>
183 </Sheet.Root>
184 </div>