diff --git a/frontend/src/app.css b/frontend/src/app.css index c28ffc6..c43e6d6 100644 --- a/frontend/src/app.css +++ b/frontend/src/app.css @@ -15,9 +15,9 @@ --color-bg-message-user: theme('colors.slate.200'); --color-bg-message-assistant: transparent; --color-text-primary: theme('colors.slate.900'); - --color-text-secondary: theme('colors.slate.600'); - --color-text-muted: theme('colors.slate.500'); - --color-text-placeholder: theme('colors.slate.400'); + --color-text-secondary: theme('colors.slate.700'); + --color-text-muted: theme('colors.slate.600'); + --color-text-placeholder: theme('colors.slate.500'); --color-border: theme('colors.slate.300'); --color-border-subtle: theme('colors.slate.200'); } diff --git a/frontend/src/lib/components/chat/ChatInput.svelte b/frontend/src/lib/components/chat/ChatInput.svelte index fb772a8..ee1ff56 100644 --- a/frontend/src/lib/components/chat/ChatInput.svelte +++ b/frontend/src/lib/components/chat/ChatInput.svelte @@ -18,14 +18,20 @@ isStreaming?: boolean; disabled?: boolean; placeholder?: string; + /** Hide the attach button in FileUpload (when shown elsewhere) */ + hideAttachButton?: boolean; + /** Bindable function to trigger file picker from parent */ + triggerFilePicker?: () => void; } - const { + let { onSend, onStop, isStreaming = false, disabled = false, - placeholder = 'Type a message...' + placeholder = 'Type a message...', + hideAttachButton = false, + triggerFilePicker = $bindable() }: Props = $props(); // Input state @@ -292,6 +298,8 @@ supportsVision={isVisionModel} {disabled} hideDropZone={true} + hideButton={hideAttachButton} + bind:triggerPicker={triggerFilePicker} />
(null); + // File picker trigger function (bound from ChatInput -> FileUpload) + let triggerFilePicker: (() => void) | undefined = $state(); + // Derived: Check if selected model supports thinking const supportsThinking = $derived.by(() => { const caps = modelsState.selectedCapabilities; @@ -843,7 +846,7 @@
- +
@@ -879,26 +882,43 @@ {/if}
- - {#if supportsThinking} - - {/if} + +
+ + + + + {#if supportsThinking} + + {/if} +
@@ -912,6 +932,8 @@ onStop={handleStopStreaming} isStreaming={chatState.isStreaming} disabled={!modelsState.selectedId} + hideAttachButton={true} + bind:triggerFilePicker /> diff --git a/frontend/src/lib/components/chat/CodeBlock.svelte b/frontend/src/lib/components/chat/CodeBlock.svelte index c250bac..f1eda46 100644 --- a/frontend/src/lib/components/chat/CodeBlock.svelte +++ b/frontend/src/lib/components/chat/CodeBlock.svelte @@ -209,10 +209,10 @@ }); -
+
{language}
@@ -249,7 +249,7 @@
-
+
{#if isLoading} -
{code}
+
{code}
{:else} {@html highlightedHtml} {/if} @@ -293,15 +293,15 @@ {#if showOutput && (isExecuting || executionResult)} -
+
- + - Output + Output {#if isExecuting} @@ -313,7 +313,7 @@ {:else if executionResult} {#if executionResult.status === 'success'} - Completed + Completed {:else} @@ -322,13 +322,13 @@ Error {/if} - {executionResult.duration}ms + {executionResult.duration}ms {/if}
-
+
{#if executionResult?.outputs.length}
{#each executionResult.outputs as output}{output.content}{/each}
{:else if !isExecuting} -

No output

+

No output

{/if}
@@ -373,11 +373,21 @@ @apply bg-transparent; } + /* Light mode scrollbar */ .code-block-content :global(pre)::-webkit-scrollbar-thumb { - @apply rounded-full bg-slate-600/50; + @apply rounded-full bg-slate-400/50; } .code-block-content :global(pre)::-webkit-scrollbar-thumb:hover { @apply bg-slate-500/70; } + + /* Dark mode scrollbar */ + :global(.dark) .code-block-content :global(pre)::-webkit-scrollbar-thumb { + @apply bg-slate-600/50; + } + + :global(.dark) .code-block-content :global(pre)::-webkit-scrollbar-thumb:hover { + @apply bg-slate-500/70; + } diff --git a/frontend/src/lib/components/chat/ContextFullModal.svelte b/frontend/src/lib/components/chat/ContextFullModal.svelte index 69b8b51..47749b2 100644 --- a/frontend/src/lib/components/chat/ContextFullModal.svelte +++ b/frontend/src/lib/components/chat/ContextFullModal.svelte @@ -35,7 +35,7 @@
-
+
@@ -44,20 +44,20 @@
-

Context Window Full

-

+

Context Window Full

+

{formatTokenCount(usage.usedTokens)} / {formatContextSize(usage.maxTokens)} tokens used

-
+

The conversation has exceeded the model's context window by {formatTokenCount(overflowAmount)} tokens.

-

+

The model cannot process more text until space is freed. Choose how to proceed:

@@ -88,7 +88,7 @@
{isSummarizing ? 'Summarizing...' : 'Summarize & Continue'}
-
+
Compress older messages into a summary to free space
@@ -102,16 +102,16 @@
{/if} - -
- - + + - - + class="h-4 w-4" + > + + + Attach files + {/if} + - - - {#if supportsVision} - Images, text files, PDFs - {:else} - Text files, PDFs (content will be included in message) - {/if} - -
+ + + {#if supportsVision} + Images, text files, PDFs + {:else} + Text files, PDFs (content will be included in message) + {/if} + +
+ {/if} {#if errorMessage} diff --git a/frontend/src/lib/components/chat/MessageContent.svelte b/frontend/src/lib/components/chat/MessageContent.svelte index 59fe0e9..9cf5875 100644 --- a/frontend/src/lib/components/chat/MessageContent.svelte +++ b/frontend/src/lib/components/chat/MessageContent.svelte @@ -394,9 +394,9 @@ {/if} diff --git a/frontend/src/lib/components/chat/MessageList.svelte b/frontend/src/lib/components/chat/MessageList.svelte index 38d7d0a..670be7d 100644 --- a/frontend/src/lib/components/chat/MessageList.svelte +++ b/frontend/src/lib/components/chat/MessageList.svelte @@ -195,7 +195,7 @@ {#if prompts.length > 0} -
+
{#each prompts as prompt} {/each} {:else} -
+
No prompts available. Create one diff --git a/frontend/src/lib/components/chat/ToolCallDisplay.svelte b/frontend/src/lib/components/chat/ToolCallDisplay.svelte index 947c3f4..56de618 100644 --- a/frontend/src/lib/components/chat/ToolCallDisplay.svelte +++ b/frontend/src/lib/components/chat/ToolCallDisplay.svelte @@ -43,7 +43,7 @@ const defaultMeta = { icon: 'โš™๏ธ', - color: 'from-slate-500 to-slate-600', + color: 'from-gray-500 to-gray-600', label: 'Tool' }; @@ -187,14 +187,14 @@ {@const isExpanded = expandedCalls.has(call.id)}
-
+
{:else} -

No conversations yet

-

Start a new chat to begin

+

No conversations yet

+

Start a new chat to begin

{/if}
{:else} @@ -47,7 +47,7 @@ {#each conversationsState.grouped as { group, conversations } (group)}
-

+

{group}

@@ -65,11 +65,11 @@ {#if conversationsState.archived.length > 0} -
+
{:else if modelsState.grouped.length === 0} -
+

No models available

Make sure Ollama is running

{:else} {#each modelsState.grouped as group (group.family)} -
+
{group.family}
@@ -140,17 +140,17 @@ diff --git a/frontend/src/lib/components/settings/ModelParametersPanel.svelte b/frontend/src/lib/components/settings/ModelParametersPanel.svelte index ac55cd6..7c20f5d 100644 --- a/frontend/src/lib/components/settings/ModelParametersPanel.svelte +++ b/frontend/src/lib/components/settings/ModelParametersPanel.svelte @@ -51,17 +51,17 @@ {#if settingsState.isPanelOpen}
-

Model Parameters

+

Model Parameters

@@ -133,7 +133,7 @@ diff --git a/frontend/src/lib/components/shared/ConfirmDialog.svelte b/frontend/src/lib/components/shared/ConfirmDialog.svelte index bb7a4d7..bec86b7 100644 --- a/frontend/src/lib/components/shared/ConfirmDialog.svelte +++ b/frontend/src/lib/components/shared/ConfirmDialog.svelte @@ -95,7 +95,7 @@
e.stopPropagation()} > @@ -155,10 +155,10 @@
-

+

{title}

-

+

{message}

@@ -166,18 +166,18 @@
-
+
diff --git a/frontend/src/lib/components/shared/ExportDialog.svelte b/frontend/src/lib/components/shared/ExportDialog.svelte index 0f19eb6..9920637 100644 --- a/frontend/src/lib/components/shared/ExportDialog.svelte +++ b/frontend/src/lib/components/shared/ExportDialog.svelte @@ -189,18 +189,18 @@
e.stopPropagation()} > -
-

+
+

Export Conversation

diff --git a/frontend/src/lib/components/shared/ImportDialog.svelte b/frontend/src/lib/components/shared/ImportDialog.svelte index b7360ef..eb4bea4 100644 --- a/frontend/src/lib/components/shared/ImportDialog.svelte +++ b/frontend/src/lib/components/shared/ImportDialog.svelte @@ -173,16 +173,16 @@ aria-labelledby="import-dialog-title" > -
+
-
-

+
+

Import Conversation

{#if isValidating}
- + - Validating file... + Validating file...
{:else if selectedFile && validationResult}
-
- +
+
-

{selectedFile.name}

-

{formatFileSize(selectedFile.size)}

+

{selectedFile.name}

+

{formatFileSize(selectedFile.size)}

-
-

Title: {validationResult.data.title}

-

Model: {validationResult.data.model}

-

Messages: {validationResult.data.messages.length}

+
+

Title: {validationResult.data.title}

+

Model: {validationResult.data.model}

+

Messages: {validationResult.data.messages.length}

{/if} @@ -351,11 +351,11 @@
-
+
diff --git a/frontend/src/lib/components/shared/MessageSkeleton.svelte b/frontend/src/lib/components/shared/MessageSkeleton.svelte index 5086ee6..3387e22 100644 --- a/frontend/src/lib/components/shared/MessageSkeleton.svelte +++ b/frontend/src/lib/components/shared/MessageSkeleton.svelte @@ -24,7 +24,7 @@
diff --git a/frontend/src/lib/components/shared/SearchModal.svelte b/frontend/src/lib/components/shared/SearchModal.svelte index 3542eda..b89e8cd 100644 --- a/frontend/src/lib/components/shared/SearchModal.svelte +++ b/frontend/src/lib/components/shared/SearchModal.svelte @@ -158,12 +158,12 @@ aria-labelledby="search-dialog-title" > -
+
-
+
{#if isSearching} - + @@ -222,21 +222,21 @@ {/if} - Esc + Esc
-
+
@@ -349,10 +349,10 @@
-
-

- Enter to select ยท - Tab to switch tabs +

+

+ Enter to select ยท + Tab to switch tabs

diff --git a/frontend/src/lib/components/shared/SettingsModal.svelte b/frontend/src/lib/components/shared/SettingsModal.svelte index e08a421..d377a27 100644 --- a/frontend/src/lib/components/shared/SettingsModal.svelte +++ b/frontend/src/lib/components/shared/SettingsModal.svelte @@ -65,18 +65,18 @@ >