Skip to content

refactor: Transcriber interface + unified sttmodel catalog - #46

Merged
alohaninja merged 2 commits into
mainfrom
parakeet/01-transcriber-catalog
Aug 21, 2026
Merged

refactor: Transcriber interface + unified sttmodel catalog#46
alohaninja merged 2 commits into
mainfrom
parakeet/01-transcriber-catalog

Conversation

@alohaninja

@alohaninja alohaninja commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

Groundwork for a second speech engine. No behavior change: vox still runs whisper.cpp exactly as before.

pr46-transcriber-catalog

What this does

  1. Extracts a Transcriber interface at the pipeline boundary (internal/transcribe/transcriber.go). transcribe.Client already had the matching method signature, so this is a one-line parameter change in transcribeStage and nothing else.

  2. Replaces internal/whispermodel with internal/sttmodel, which adds two things the old package could not express:

    • An Engine dimension (whisper vs parakeet), since a second inference backend is coming in the next PR
    • Archive models (a directory of ONNX files extracted from a tar.bz2), unlike whisper's single .bin
  3. Model storage moves to ~/.local/share/vox/models/<engine>/. Existing whisper installs are found via a fallback to ~/.local/share/whisper-cpp/, and WHISPER_MODEL_DIR is still honored, so nobody re-downloads multi-gigabyte models.

Safe to merge first

This PR is intentionally separable: every test passes, whisper works identically, and no new engine is introduced. The next PR builds on this foundation.

Testing

  • All 21 packages pass (go test -race -short ./...)
  • Legacy whisper path fallback has a dedicated test
  • Archive extraction checks path traversal, size caps, staging-then-swap, and partial-extraction detection

Groundwork for a second speech engine. No behavior change: vox still runs
whisper.cpp exactly as before.

Extract a Transcriber interface at the pipeline boundary. transcribe.Client
already had the matching method signature, so this is a one-line parameter
change in transcribeStage and nothing else.

Replace internal/whispermodel with internal/sttmodel, which adds two things
the old package could not express:

  - an Engine dimension (whisper vs parakeet), since a second inference
    backend is coming
  - archive models, which extract to a directory of files rather than
    landing as a single .bin

Model storage moves to ~/.local/share/vox/models/<engine>/. Existing whisper
installs are found via a fallback to ~/.local/share/whisper-cpp/, and
WHISPER_MODEL_DIR is still honored, so nobody re-downloads a 1.5 GiB model.
ResolvePath is used wherever a path reaches whisper-server; Path is reserved
for new downloads, which always land in the canonical location.

Archive extraction stages into a temp directory and verifies every required
file before swapping into place, so a partial extraction fails at install
time with a clear error rather than at inference time with a confusing one.
Entries are checked against path traversal and a per-entry size cap.

Remove is idempotent for both model shapes so callers need not guard with
IsInstalled.
Addresses supareview findings on PR #46 (1/3 in stack):

Suggestions fixed:
- Remove now cleans temp artifacts at both resolved and canonical paths
- existsComplete returns false for archive models with empty Files slice
- Added TestRemoveAtLegacyPath to cover legacy-path deletion

Nits fixed:
- Removed duplicate os.MkdirAll calls in model_test.go
- Simplified hasher declaration, removed unused hash import
alohaninja added a commit that referenced this pull request Aug 21, 2026
Addresses supareview findings on PR #47 (2/3 in stack, base: #46):

Blockers fixed:
- Replace runWithTimeout goroutine/zombie leak with exec.CommandContext

Suggestions fixed:
- Add idle-timer lifecycle test (TestIdleTimerReleasesImpl)
- Add modelMu precondition comment on activateModel
- Rename currentWhisperModelID to currentModelID

Nits fixed:
- Add TestDecodeWAVLargeChunkSize for oversized chunk size field
alohaninja added a commit that referenced this pull request Aug 21, 2026
Addresses supareview findings on PR #47 (2/3 in stack, base: #46):

Blockers fixed:
- Replace runWithTimeout goroutine/zombie leak with exec.CommandContext

Suggestions fixed:
- Add idle-timer lifecycle test (TestIdleTimerReleasesImpl)
- Add modelMu precondition comment on activateModel
- Rename currentWhisperModelID to currentModelID

Nits fixed:
- Add TestDecodeWAVLargeChunkSize for oversized chunk size field
alohaninja added a commit that referenced this pull request Aug 21, 2026
Addresses supareview findings on PR #47 (2/3 in stack, base: #46):

Blockers fixed:
- Replace runWithTimeout goroutine/zombie leak with exec.CommandContext

Suggestions fixed:
- Add idle-timer lifecycle test (TestIdleTimerReleasesImpl)
- Add modelMu precondition comment on activateModel
- Rename currentWhisperModelID to currentModelID

Nits fixed:
- Add TestDecodeWAVLargeChunkSize for oversized chunk size field
@alohaninja
alohaninja merged commit 9e2d12a into main Aug 21, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants