fix(progress): separate model warmup state
Build & Push Docker Image / test (push) Successful in 11s
Build & Push Docker Image / build-and-push (push) Successful in 42s

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-05-12 00:52:33 +02:00
co-authored by Copilot
parent 929c482497
commit f70cefc5e9
9 changed files with 194 additions and 72 deletions
+52
View File
@@ -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<JobStatus, string> = {
pending: 'Pending',
downloading: 'Downloading',
preparing: 'Preparing',
warming_model: 'Loading model',
transcribing: 'Transcribing',
processing: 'Processing',
done: 'Done',
failed: 'Failed',
cancelled: 'Cancelled'
};
const STATUS_COLORS: Record<JobStatus, string> = {
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<Job, 'status' | 'progress' | 'segmentsJson'>,
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;
}
+5 -2
View File
@@ -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(
+10 -1
View File
@@ -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;