From f70cefc5e94780a6e4b946eaa98807780d5a702e Mon Sep 17 00:00:00 2001 From: Giancarmine Salucci Date: Tue, 12 May 2026 00:52:33 +0200 Subject: [PATCH] fix(progress): separate model warmup state Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/lib/job-progress.ts | 52 +++++++++++++++++ src/lib/server/pipeline.ts | 7 ++- src/lib/types.ts | 11 +++- src/routes/+page.svelte | 8 ++- src/routes/api/jobs/[id]/+server.ts | 2 +- src/routes/jobs/+page.svelte | 46 ++++++--------- src/routes/jobs/[id]/+page.svelte | 89 +++++++++++++++++------------ src/tests/db.test.ts | 2 +- src/tests/job-progress.test.ts | 49 ++++++++++++++++ 9 files changed, 194 insertions(+), 72 deletions(-) create mode 100644 src/lib/job-progress.ts create mode 100644 src/tests/job-progress.test.ts diff --git a/src/lib/job-progress.ts b/src/lib/job-progress.ts new file mode 100644 index 0000000..d499f73 --- /dev/null +++ b/src/lib/job-progress.ts @@ -0,0 +1,52 @@ +import type { Job, JobStatus } from '$lib/types.js'; + +export const TERMINAL_JOB_STATUSES: readonly JobStatus[] = ['done', 'failed', 'cancelled']; + +const STATUS_LABELS: Record = { + pending: 'Pending', + downloading: 'Downloading', + preparing: 'Preparing', + warming_model: 'Loading model', + transcribing: 'Transcribing', + processing: 'Processing', + done: 'Done', + failed: 'Failed', + cancelled: 'Cancelled' +}; + +const STATUS_COLORS: Record = { + done: '#cdf24e', + failed: '#ff6b6b', + cancelled: 'rgba(232,233,236,0.3)', + processing: '#76daa2', + transcribing: '#80c7f7', + warming_model: '#76daa2', + preparing: '#fbc94b', + downloading: '#a78bfa', + pending: 'rgba(232,233,236,0.4)' +}; + +export function isTerminalJobStatus(status: JobStatus): boolean { + return TERMINAL_JOB_STATUSES.includes(status); +} + +export function getJobStatusLabel(status: JobStatus): string { + return STATUS_LABELS[status]; +} + +export function getJobStatusColor(status: JobStatus): string { + return STATUS_COLORS[status]; +} + +export function getDisplayJobProgress( + job: Pick, + options: { hasTranscript?: boolean } = {} +): number { + const progress = Math.max(0, Math.min(100, Math.round(job.progress))); + + if (job.status === 'warming_model') return Math.min(progress, 15); + if (!isTerminalJobStatus(job.status)) return Math.min(progress, 99); + if (job.status === 'done' && !options.hasTranscript) return Math.min(progress, 99); + + return progress; +} diff --git a/src/lib/server/pipeline.ts b/src/lib/server/pipeline.ts index 1e8f58f..f8384a5 100644 --- a/src/lib/server/pipeline.ts +++ b/src/lib/server/pipeline.ts @@ -124,13 +124,16 @@ async function runJob( // ── 4. Submit to whisper with webhook ──────────────────────────────── setJobStatus(jobId, 'transcribing', 10); - emitProgress(jobId, { type: 'status', status: 'transcribing' }); + emitProgress(jobId, { type: 'status', status: 'transcribing', progress: 10 }); const webhookUrl = `${WEBHOOK_BASE_URL}/api/webhook/${jobId}`; const whisperJobId = await submitJob(wavPath, webhookUrl, language, (state, retryAfterSecs) => { - emitProgress(jobId, { type: 'model_warming', state, retryAfterSecs }); + setJobStatus(jobId, 'warming_model', 10); + emitProgress(jobId, { type: 'model_warming', status: 'warming_model', state, retryAfterSecs, progress: 10 }); }); updateJob({ id: jobId, whisperJobId }); + setJobStatus(jobId, 'transcribing', 10); + emitProgress(jobId, { type: 'status', status: 'transcribing', progress: 10 }); // ── 5. Open SSE for live progress (non-blocking relay) ─────────────── streamJob( diff --git a/src/lib/types.ts b/src/lib/types.ts index a646182..532e4c8 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -12,7 +12,16 @@ export interface ModelStatus { vram_total_mb?: number; } -export type JobStatus = 'pending' | 'downloading' | 'preparing' | 'transcribing' | 'processing' | 'done' | 'failed' | 'cancelled'; +export type JobStatus = + | 'pending' + | 'downloading' + | 'preparing' + | 'warming_model' + | 'transcribing' + | 'processing' + | 'done' + | 'failed' + | 'cancelled'; export interface Segment { index: number; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 29d5974..cf1bdb3 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,6 +1,7 @@