]> git.djapps.eu Git - pkg/ggml/sources/llama.cpp/commitdiff
Add optional setting for showing "Model used:" information (#16337)
authorAleksander Grygier <redacted>
Wed, 1 Oct 2025 10:08:16 +0000 (12:08 +0200)
committerGitHub <redacted>
Wed, 1 Oct 2025 10:08:16 +0000 (12:08 +0200)
* feat: Add a setting to include model name used to generate the message

* feat: UI improvements

* feat: Save model info along with the database message entry creation

* chore: Build webui static output

tools/server/public/index.html.gz
tools/server/webui/src/lib/components/app/chat/ChatMessages/ChatMessageAssistant.svelte
tools/server/webui/src/lib/components/app/chat/ChatSettings/ChatSettingsDialog.svelte
tools/server/webui/src/lib/components/app/misc/ActionButton.svelte
tools/server/webui/src/lib/constants/settings-config.ts
tools/server/webui/src/lib/stores/chat.svelte.ts
tools/server/webui/src/lib/types/database.d.ts

index a2f084f3bb106ad97c0e8d1aaf9c09c4f973a11d..3a62b93364d4c7f6658464d0b37bb56463373d25 100644 (file)
Binary files a/tools/server/public/index.html.gz and b/tools/server/public/index.html.gz differ
index 013b77cbbe4033b9f3e555929d2c773b1ed1be74..ad3ffa3792d5888959d2c0d0927d7033bc6dbffb 100644 (file)
@@ -3,12 +3,14 @@
        import { useProcessingState } from '$lib/hooks/use-processing-state.svelte';
        import { isLoading } from '$lib/stores/chat.svelte';
        import { fade } from 'svelte/transition';
-       import { Check, X } from '@lucide/svelte';
+       import { Check, Copy, Package, X } from '@lucide/svelte';
        import { Button } from '$lib/components/ui/button';
        import { Checkbox } from '$lib/components/ui/checkbox';
        import { INPUT_CLASSES } from '$lib/constants/input-classes';
        import ChatMessageActions from './ChatMessageActions.svelte';
        import Label from '$lib/components/ui/label/label.svelte';
+       import { config } from '$lib/stores/settings.svelte';
+       import { copyToClipboard } from '$lib/utils/copy';
 
        interface Props {
                class?: string;
                </div>
        {/if}
 
+       {#if config().showModelInfo && message.model}
+               <span class="mt-6 mb-4 inline-flex items-center gap-1 text-xs text-muted-foreground">
+                       <Package class="h-3.5 w-3.5" />
+
+                       <span>Model used:</span>
+
+                       <button
+                               class="inline-flex cursor-pointer items-center gap-1 rounded-sm bg-muted-foreground/15 px-1.5 py-0.75"
+                               onclick={() => copyToClipboard(message.model)}
+                       >
+                               {message.model}
+
+                               <Copy class="ml-1 h-3 w-3 " />
+                       </button>
+               </span>
+       {/if}
+
        {#if message.timestamp && !isEditing}
                <ChatMessageActions
                        role="assistant"
index 2099536d743012816f92f7ac180ce2214702ace6..d832abc2e2831c53e760e4fccf65d9d3c9d75e10 100644 (file)
                                        key: 'pdfAsImage',
                                        label: 'Parse PDF as image',
                                        type: 'checkbox'
+                               },
+                               {
+                                       key: 'showModelInfo',
+                                       label: 'Show model information',
+                                       type: 'checkbox'
                                }
                        ]
                },
index 2369a31ce128fabd16341ce3fd9f3f84e37d0ae9..11c4679a6eb1aecd97c0241a88b942f041bcad44 100644 (file)
@@ -34,7 +34,7 @@
                        {size}
                        {disabled}
                        {onclick}
-                       class="h-6 w-6 p-0 {className}"
+                       class="h-6 w-6 p-0 {className} flex"
                        aria-label={ariaLabel || tooltip}
                >
                        {@const IconComponent = icon}
index 89eff7bdbd6b9ec87d18f884c41dccc2ff0a7776..5cb22f4c34082f6f8f5ef97f33d52b908ee34918 100644 (file)
@@ -10,6 +10,7 @@ export const SETTING_CONFIG_DEFAULT: Record<string, string | number | boolean> =
        askForTitleConfirmation: false,
        pasteLongTextToFileLen: 2500,
        pdfAsImage: false,
+       showModelInfo: false,
        // make sure these default values are in sync with `common.h`
        samplers: 'top_k;typ_p;top_p;min_p;temperature',
        temperature: 0.8,
@@ -79,6 +80,7 @@ export const SETTING_CONFIG_INFO: Record<string, string> = {
        askForTitleConfirmation:
                'Ask for confirmation before automatically changing conversation title when editing the first message.',
        pdfAsImage: 'Parse PDF as image instead of text (requires vision-capable model).',
+       showModelInfo: 'Display the model name used to generate each message below the message content.',
        pyInterpreterEnabled:
                'Enable Python interpreter using Pyodide. Allows running Python code in markdown code blocks.'
 };
index d3f80611086d3106ca12b0d91102bd908fd680c7..4a6d3a8c61f602b79c2c9468583f0278d842f911 100644 (file)
@@ -353,7 +353,6 @@ class ChatStore {
 
                                await DatabaseStore.updateCurrentNode(this.activeConversation!.id, assistantMessage.id);
                                this.activeConversation!.currNode = assistantMessage.id;
-
                                await this.refreshActiveMessages();
 
                                if (onComplete) {
@@ -479,6 +478,9 @@ class ChatStore {
        private async createAssistantMessage(parentId?: string): Promise<DatabaseMessage | null> {
                if (!this.activeConversation) return null;
 
+               // Capture the current model name when creating the assistant message
+               const currentModelName = serverStore.modelName;
+
                return await DatabaseStore.createMessageBranch(
                        {
                                convId: this.activeConversation.id,
@@ -487,7 +489,8 @@ class ChatStore {
                                content: '',
                                timestamp: Date.now(),
                                thinking: '',
-                               children: []
+                               children: [],
+                               model: currentModelName || undefined
                        },
                        parentId || null
                );
@@ -1138,7 +1141,8 @@ class ChatStore {
                                                role: messageToEdit.role,
                                                content: newContent,
                                                thinking: messageToEdit.thinking || '',
-                                               children: []
+                                               children: [],
+                                               model: messageToEdit.model // Preserve original model info when branching
                                        },
                                        messageToEdit.parent!
                                );
@@ -1213,7 +1217,8 @@ class ChatStore {
                                        content: newContent,
                                        thinking: messageToEdit.thinking || '',
                                        children: [],
-                                       extra: messageToEdit.extra ? JSON.parse(JSON.stringify(messageToEdit.extra)) : undefined
+                                       extra: messageToEdit.extra ? JSON.parse(JSON.stringify(messageToEdit.extra)) : undefined,
+                                       model: messageToEdit.model // Preserve original model info when branching
                                },
                                parentId
                        );
@@ -1274,6 +1279,9 @@ class ChatStore {
                        this.isLoading = true;
                        this.currentResponse = '';
 
+                       // Capture the current model name when creating the assistant message
+                       const currentModelName = serverStore.modelName;
+
                        const newAssistantMessage = await DatabaseStore.createMessageBranch(
                                {
                                        convId: this.activeConversation.id,
@@ -1282,7 +1290,8 @@ class ChatStore {
                                        role: 'assistant',
                                        content: '',
                                        thinking: '',
-                                       children: []
+                                       children: [],
+                                       model: currentModelName || undefined
                                },
                                parentMessage.id
                        );
@@ -1329,6 +1338,9 @@ class ChatStore {
                                false
                        ) as DatabaseMessage[];
 
+                       // Capture the current model name when creating the assistant message
+                       const currentModelName = serverStore.modelName;
+
                        // Create new assistant message branch
                        const assistantMessage = await DatabaseStore.createMessageBranch(
                                {
@@ -1338,7 +1350,8 @@ class ChatStore {
                                        role: 'assistant',
                                        content: '',
                                        thinking: '',
-                                       children: []
+                                       children: [],
+                                       model: currentModelName || undefined
                                },
                                userMessageId
                        );
index e3076ef12a8aea60c7bc126b04f7501d2f7ce81a..c6e12b3cac8b3a17d3677a88927bdfbaa68b9d79 100644 (file)
@@ -52,4 +52,5 @@ export interface DatabaseMessage {
        children: string[];
        extra?: DatabaseMessageExtra[];
        timings?: ChatMessageTimings;
+       model?: string;
 }