diff --git a/tools/server/public/index.html.gz b/tools/server/public/index.html.gz
index 0e460373fd..f516db853a 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/notebook/NotebookScreen.svelte b/tools/server/webui/src/lib/components/app/notebook/NotebookScreen.svelte
index 40027c1f31..8c5c7e8b1d 100644
--- a/tools/server/webui/src/lib/components/app/notebook/NotebookScreen.svelte
+++ b/tools/server/webui/src/lib/components/app/notebook/NotebookScreen.svelte
@@ -5,7 +5,7 @@
import { Play, Square, Settings } from '@lucide/svelte';
import { config } from '$lib/stores/settings.svelte';
import DialogChatSettings from '$lib/components/app/dialogs/DialogChatSettings.svelte';
- import { ModelsSelector, ChatMessageStatistics } from '$lib/components/app';
+ import { ModelsSelector, ChatMessageStatistics, DialogChatError } from '$lib/components/app';
import { useModelChangeValidation } from '$lib/hooks/use-model-change-validation.svelte';
import { modelsStore, modelOptions, selectedModelId } from '$lib/stores/models.svelte';
import { isRouterMode } from '$lib/stores/server.svelte';
@@ -34,6 +34,8 @@
let isRouter = $derived(isRouterMode());
+ let errorDialog = $derived(notebookStore.error);
+
// Sync local input with store content
$effect(() => {
inputContent = notebookStore.content;
@@ -44,6 +46,12 @@
notebookStore.content = target.value;
}
+ function handleErrorDialogOpenChange(open: boolean) {
+ if (!open) {
+ notebookStore.dismissError();
+ }
+ }
+
async function handleGenerate() {
if (!disableAutoScroll) {
userScrolledUp = false;
@@ -57,6 +65,7 @@
await notebookStore.generate(notebookModel);
}
+
function handleStop() {
notebookStore.stop();
}
@@ -271,4 +280,12 @@
(settingsOpen = open)} />
+
+
diff --git a/tools/server/webui/src/lib/stores/notebook.svelte.ts b/tools/server/webui/src/lib/stores/notebook.svelte.ts
index 4ae1dc3b72..a4849aa61e 100644
--- a/tools/server/webui/src/lib/stores/notebook.svelte.ts
+++ b/tools/server/webui/src/lib/stores/notebook.svelte.ts
@@ -12,11 +12,18 @@ export class NotebookStore {
predictedTokens = $state(0);
predictedMs = $state(0);
+ error = $state<{
+ message: string;
+ type: 'timeout' | 'server';
+ contextInfo?: { n_prompt_tokens: number; n_ctx: number };
+ } | null>(null);
+
async generate(model?: string) {
if (this.isGenerating) return;
this.isGenerating = true;
this.abortController = new AbortController();
+ this.error = null;
// Reset stats
this.promptTokens = 0;
@@ -59,6 +66,10 @@ export class NotebookStore {
// aborted by user
} else {
console.error('Notebook generation error:', error);
+ this.error = {
+ message: error instanceof Error ? error.message : String(error),
+ type: 'server'
+ };
}
this.isGenerating = false;
}
@@ -67,10 +78,18 @@ export class NotebookStore {
);
} catch (error) {
console.error('Notebook generation failed:', error);
+ this.error = {
+ message: error instanceof Error ? error.message : String(error),
+ type: 'server'
+ };
this.isGenerating = false;
}
}
+ dismissError() {
+ this.error = null;
+ }
+
stop() {
if (this.abortController) {
this.abortController.abort();