feat: model-on-demand lifecycle — retry on 503, live status pill, warming indicator
- whisper.ts: add getModelStatus(); fix submitJob() to retry on 503 using
Retry-After header instead of throwing; optional onModelWaiting callback
lets the pipeline surface model state to the UI during the wait
- pipeline.ts: pass onModelWaiting callback → emits model_warming SSE event
so the job detail page can show 'Warming up model…' while waiting
- types.ts: add ModelStateTag union and ModelStatus interface
- api/model/status: GET route proxies whisper /model/status (falls back to
{state:'unloaded'} if whisper unreachable)
- api/model/events: GET route relays whisper SSE stream to the browser;
AbortController tied to request.signal cleans up on disconnect
- layout.svelte: status pill is now live — initial fetch + EventSource on
/api/model/events; dot colour + label reflect real model state with a
pulsing animation while loading or waiting_for_gpu
- jobs/[id]/+page.svelte: handle model_warming event type → show a yellow
'Warming up model…' sub-label with spinner inside the progress card
- whisper.test.ts: update submitJob mocks to status:202 to match real API
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -129,7 +129,9 @@ async function runJob(
|
||||
emitProgress(jobId, { type: 'status', status: 'transcribing' });
|
||||
|
||||
const webhookUrl = `${WEBHOOK_BASE_URL}/api/webhook/${jobId}`;
|
||||
const whisperJobId = await submitJob(wavPath, webhookUrl, language);
|
||||
const whisperJobId = await submitJob(wavPath, webhookUrl, language, (state, retryAfterSecs) => {
|
||||
emitProgress(jobId, { type: 'model_warming', state, retryAfterSecs });
|
||||
});
|
||||
updateJob({ id: jobId, whisperJobId });
|
||||
|
||||
// ── 5. Open SSE for live progress (non-blocking relay) ───────────────
|
||||
|
||||
Reference in New Issue
Block a user