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