diff --git a/.gitignore b/.gitignore
index bb122d6924..561f7aabe6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -136,5 +136,6 @@ poetry.toml
# IDE
/*.code-workspace
/.windsurf/
+/.agent/
# emscripten
a.out.*
diff --git a/tools/server/public/index.html.gz b/tools/server/public/index.html.gz
index 30de1ebaf8..c104b1ca05 100644
Binary files a/tools/server/public/index.html.gz and b/tools/server/public/index.html.gz differ
diff --git a/tools/server/webui/src/lib/components/app/chat/ChatSidebar/ChatSidebar.svelte b/tools/server/webui/src/lib/components/app/chat/ChatSidebar/ChatSidebar.svelte
index ac9ae8ae6c..aa0c27f6d3 100644
--- a/tools/server/webui/src/lib/components/app/chat/ChatSidebar/ChatSidebar.svelte
+++ b/tools/server/webui/src/lib/components/app/chat/ChatSidebar/ChatSidebar.svelte
@@ -118,17 +118,6 @@
-
-
{#if (filteredConversations.length > 0 && isSearchModeActive) || !isSearchModeActive}
diff --git a/tools/server/webui/src/lib/components/app/chat/ChatSidebar/ChatSidebarActions.svelte b/tools/server/webui/src/lib/components/app/chat/ChatSidebar/ChatSidebarActions.svelte
index 30d1f9d4b7..931255c665 100644
--- a/tools/server/webui/src/lib/components/app/chat/ChatSidebar/ChatSidebarActions.svelte
+++ b/tools/server/webui/src/lib/components/app/chat/ChatSidebar/ChatSidebarActions.svelte
@@ -1,5 +1,5 @@
@@ -55,43 +112,55 @@
value={inputContent}
oninput={handleInput}
class="h-full min-h-[500px] w-full resize-none rounded-xl border-none bg-muted p-4 text-base focus-visible:ring-0 md:p-6"
- placeholder="Enter your prompt here..."
+ placeholder="Enter your text here..."
/>
-
+ {#snippet generateButton(props = {})}
+
+ {/snippet}
-
+ {#if generateTooltip}
+
+
+ {@render generateButton()}
+
+
+
+ {generateTooltip}
+
+
+ {:else}
+ {@render generateButton()}
+ {/if}
+
+
-
-
(settingsOpen = open)} />
- (modelInfoOpen = open)} />
diff --git a/tools/server/webui/src/lib/stores/notebook.svelte.ts b/tools/server/webui/src/lib/stores/notebook.svelte.ts
index 5179857d7d..ff542abf60 100644
--- a/tools/server/webui/src/lib/stores/notebook.svelte.ts
+++ b/tools/server/webui/src/lib/stores/notebook.svelte.ts
@@ -2,70 +2,74 @@ import { ChatService } from '$lib/services/chat';
import { config } from '$lib/stores/settings.svelte';
export class NotebookStore {
- content = $state('');
- isGenerating = $state(false);
- abortController: AbortController | null = null;
+ content = $state('');
+ isGenerating = $state(false);
+ abortController: AbortController | null = null;
- // Statistics
- promptTokens = $state(0);
- promptMs = $state(0);
- predictedTokens = $state(0);
- predictedMs = $state(0);
+ // Statistics
+ promptTokens = $state(0);
+ promptMs = $state(0);
+ predictedTokens = $state(0);
+ predictedMs = $state(0);
- async generate(model?: string) {
- if (this.isGenerating) return;
+ async generate(model?: string) {
+ if (this.isGenerating) return;
- this.isGenerating = true;
- this.abortController = new AbortController();
+ this.isGenerating = true;
+ this.abortController = new AbortController();
- // Reset stats
- this.promptTokens = 0;
- this.promptMs = 0;
- this.predictedTokens = 0;
- this.predictedMs = 0;
+ // Reset stats
+ this.promptTokens = 0;
+ this.promptMs = 0;
+ this.predictedTokens = 0;
+ this.predictedMs = 0;
- try {
- const currentConfig = config();
- await ChatService.sendCompletion(
- this.content,
- {
- ...currentConfig,
- model,
- stream: true,
- onChunk: (chunk) => {
- this.content += chunk;
- },
- onTimings: (timings) => {
- if (timings) {
- if (timings.prompt_n) this.promptTokens = timings.prompt_n;
- if (timings.prompt_ms) this.promptMs = timings.prompt_ms;
- if (timings.predicted_n) this.predictedTokens = timings.predicted_n;
- if (timings.predicted_ms) this.predictedMs = timings.predicted_ms;
- }
- },
- onComplete: () => {
- this.isGenerating = false;
- },
- onError: (error) => {
- console.error('Notebook generation error:', error);
- this.isGenerating = false;
- }
- },
- this.abortController.signal
- );
- } catch (error) {
- console.error('Notebook generation failed:', error);
- this.isGenerating = false;
- }
- }
+ try {
+ const currentConfig = config();
+ await ChatService.sendCompletion(
+ this.content,
+ {
+ ...currentConfig,
+ model: model ?? currentConfig.model,
+ stream: true,
+ onChunk: (chunk) => {
+ this.content += chunk;
+ },
+ onTimings: (timings) => {
+ if (timings) {
+ if (timings.prompt_n) this.promptTokens = timings.prompt_n;
+ if (timings.prompt_ms) this.promptMs = timings.prompt_ms;
+ if (timings.predicted_n) this.predictedTokens = timings.predicted_n;
+ if (timings.predicted_ms) this.predictedMs = timings.predicted_ms;
+ }
+ },
+ onComplete: () => {
+ this.isGenerating = false;
+ },
+ onError: (error) => {
+ if (error instanceof Error && error.name === 'AbortError') {
+ // aborted by user
+ } else {
+ console.error('Notebook generation error:', error);
+ }
+ this.isGenerating = false;
+ }
+ },
+ this.abortController.signal
+ );
+ } catch (error) {
+ console.error('Notebook generation failed:', error);
+ this.isGenerating = false;
+ }
+ }
- stop() {
- if (this.abortController) {
- this.abortController.abort();
- this.abortController = null;
- }
- this.isGenerating = false;
- }
+ stop() {
+ if (this.abortController) {
+ this.abortController.abort();
+ this.abortController = null;
+ }
+ this.isGenerating = false;
+ }
}
export const notebookStore = new NotebookStore();
diff --git a/tools/server/webui/src/lib/types/api.d.ts b/tools/server/webui/src/lib/types/api.d.ts
index 7e036be156..46eb72501a 100644
--- a/tools/server/webui/src/lib/types/api.d.ts
+++ b/tools/server/webui/src/lib/types/api.d.ts
@@ -23,12 +23,12 @@ export interface ApiContextSizeError {
export interface ApiErrorResponse {
error:
- | ApiContextSizeError
- | {
- code: number;
- message: string;
- type?: string;
- };
+ | ApiContextSizeError
+ | {
+ code: number;
+ message: string;
+ type?: string;
+ };
}
export interface ApiChatMessageData {