Use same dialog for server errors on notebook page

This commit is contained in:
Leszek Hanusz 2026-02-02 21:29:48 +01:00
parent 11e3cd81ce
commit f041a864ed
3 changed files with 37 additions and 1 deletions

Binary file not shown.

View File

@ -5,7 +5,7 @@
import { Play, Square, Settings } from '@lucide/svelte'; import { Play, Square, Settings } from '@lucide/svelte';
import { config } from '$lib/stores/settings.svelte'; import { config } from '$lib/stores/settings.svelte';
import DialogChatSettings from '$lib/components/app/dialogs/DialogChatSettings.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 { useModelChangeValidation } from '$lib/hooks/use-model-change-validation.svelte';
import { modelsStore, modelOptions, selectedModelId } from '$lib/stores/models.svelte'; import { modelsStore, modelOptions, selectedModelId } from '$lib/stores/models.svelte';
import { isRouterMode } from '$lib/stores/server.svelte'; import { isRouterMode } from '$lib/stores/server.svelte';
@ -34,6 +34,8 @@
let isRouter = $derived(isRouterMode()); let isRouter = $derived(isRouterMode());
let errorDialog = $derived(notebookStore.error);
// Sync local input with store content // Sync local input with store content
$effect(() => { $effect(() => {
inputContent = notebookStore.content; inputContent = notebookStore.content;
@ -44,6 +46,12 @@
notebookStore.content = target.value; notebookStore.content = target.value;
} }
function handleErrorDialogOpenChange(open: boolean) {
if (!open) {
notebookStore.dismissError();
}
}
async function handleGenerate() { async function handleGenerate() {
if (!disableAutoScroll) { if (!disableAutoScroll) {
userScrolledUp = false; userScrolledUp = false;
@ -57,6 +65,7 @@
await notebookStore.generate(notebookModel); await notebookStore.generate(notebookModel);
} }
function handleStop() { function handleStop() {
notebookStore.stop(); notebookStore.stop();
} }
@ -271,4 +280,12 @@
</div> </div>
<DialogChatSettings open={settingsOpen} onOpenChange={(open) => (settingsOpen = open)} /> <DialogChatSettings open={settingsOpen} onOpenChange={(open) => (settingsOpen = open)} />
<DialogChatError
message={errorDialog?.message ?? ''}
contextInfo={errorDialog?.contextInfo}
onOpenChange={handleErrorDialogOpenChange}
open={Boolean(errorDialog)}
type={errorDialog?.type ?? 'server'}
/>
</div> </div>

View File

@ -12,11 +12,18 @@ export class NotebookStore {
predictedTokens = $state(0); predictedTokens = $state(0);
predictedMs = $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) { async generate(model?: string) {
if (this.isGenerating) return; if (this.isGenerating) return;
this.isGenerating = true; this.isGenerating = true;
this.abortController = new AbortController(); this.abortController = new AbortController();
this.error = null;
// Reset stats // Reset stats
this.promptTokens = 0; this.promptTokens = 0;
@ -59,6 +66,10 @@ export class NotebookStore {
// aborted by user // aborted by user
} else { } else {
console.error('Notebook generation error:', error); console.error('Notebook generation error:', error);
this.error = {
message: error instanceof Error ? error.message : String(error),
type: 'server'
};
} }
this.isGenerating = false; this.isGenerating = false;
} }
@ -67,10 +78,18 @@ export class NotebookStore {
); );
} catch (error) { } catch (error) {
console.error('Notebook generation failed:', error); console.error('Notebook generation failed:', error);
this.error = {
message: error instanceof Error ? error.message : String(error),
type: 'server'
};
this.isGenerating = false; this.isGenerating = false;
} }
} }
dismissError() {
this.error = null;
}
stop() { stop() {
if (this.abortController) { if (this.abortController) {
this.abortController.abort(); this.abortController.abort();