From dc15623f6264802ac786c06885cc8116b48a2b2f Mon Sep 17 00:00:00 2001 From: Lucas Winther Date: Thu, 29 Oct 2026 23:03:27 +0100 Subject: [PATCH] WIP: uncommitted work at pause (session limit) Co-Authored-By: Claude Opus 5.5 --- tests/server-engine.md | 19 +++++++++++++++++-- tests/transcribe.test.ts | 28 ++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/tests/server-engine.md b/tests/server-engine.md index 1b238f0..782b7f7 100644 --- a/tests/server-engine.md +++ b/tests/server-engine.md @@ -21,7 +21,16 @@ FW_INTEGRATION=1 bun test tests/transcribe.test.ts ``` Runs the real sidecar end to end (spawn → ready handshake → `tiny.en` load → -transcribe → done). First run downloads ~75 MB of weights from the Hub. +transcribe → done), then the first 60 s of `tests/audio_files/en_alien.opus` +(needs `ffmpeg`) in both decoding modes (D-WS5a): `file` (faster-whisper's +`BatchedInferencePipeline` + Silero VAD, what `POST /api/transcribe` uses) and +`live` (sequential, what server-live passes use). First run downloads ~75 MB +of weights from the Hub. Point `SIDECAR_PYTHON` at a virtualenv's python if +faster-whisper isn't installed for `python3` itself. + +Without faster-whisper at all, `bun test tests/transcribe.test.ts` still runs +the real `server-py/sidecar.py` against a stub (`tests/fixtures/stub_fw`) to +check the mode routing, the one-model cache and cancel between segments. - [ ] The `real faster-whisper sidecar` describe block passes. @@ -39,7 +48,13 @@ transcribe → done). First run downloads ~75 MB of weights from the Hub. where `audio.f32` is raw float32 mono 16 kHz PCM). 5. Transcribe the same clip through the server engine. -- [ ] Segments stream in as JSON lines (not one blob at the end). +- [ ] Segments stream in as JSON lines (not one blob at the end). With the + batched pipeline (D-WS5a) they arrive in bursts — one burst per 8 + speech chunks (≈ up to 4 min of audio) — with blank heartbeat lines + every 5 s in between; on a clip under ~30 s of speech, everything + arrives as a single segment at the end. +- [ ] Cancelling a long server transcription (abort / page refresh) stops + the sidecar within one burst; the next request then starts normally. - [ ] Both transcripts agree in content (minor punctuation/casing drift between Transformers.js and faster-whisper is expected). - [ ] Signed out, the toggle is gone and `POST /api/transcribe` answers 401. diff --git a/tests/transcribe.test.ts b/tests/transcribe.test.ts index eb7cdfb..f954c92 100644 --- a/tests/transcribe.test.ts +++ b/tests/transcribe.test.ts @@ -594,4 +594,32 @@ describe.skipIf(!process.env.FW_INTEGRATION)("real faster-whisper sidecar", () = }, { timeout: 300_000 }, ); + + test( + "file mode (batched + VAD) and live mode both transcribe real speech (D-WS5a)", + async () => { + const sidecar = createSidecar(); + // First 60 s of en_alien as raw float32 16 kHz mono — what the browser uploads. + const clip = join(import.meta.dir, "audio_files/en_alien.opus"); + const pcm = + await Bun.$`ffmpeg -v error -i ${clip} -t 60 -f f32le -ac 1 -ar 16000 -`.arrayBuffer(); + const audioPath = join(await makeTempDir(), "alien.f32"); + await Bun.write(audioPath, pcm); + + for (const mode of ["file", "live"] as const) { + const segments: SidecarSegment[] = []; + const outcome = await sidecar.transcribe( + { model: "tiny.en", audioPath, language: "en", mode }, + (segment) => segments.push(segment), + ); + expect(outcome.cancelled).toBe(false); + expect(segments.length).toBeGreaterThan(0); + const text = segments.map((segment) => segment.text).join("").toLowerCase(); + expect(text).toContain("voices of the void"); + // Timestamps stay in source-audio time after VAD drops silence. + expect(segments.at(-1)!.end).toBeLessThanOrEqual(61); + } + }, + { timeout: 300_000 }, + ); });