Skip to content

fix(onboarding): Parakeet model download — real progress, integrity verification, corrupt-cache repair - #246

Merged
initcore0 merged 1 commit into
mainfrom
claude/parakeet-model-onboarding-b684fe
Aug 4, 2026
Merged

fix(onboarding): Parakeet model download — real progress, integrity verification, corrupt-cache repair#246
initcore0 merged 1 commit into
mainfrom
claude/parakeet-model-onboarding-b684fe

Conversation

@initcore0

Copy link
Copy Markdown
Owner

Problem (field report, fresh Mac)

Menu bar: "Model unavailable — Unable to load model: file:///Users/…/FluidAudio/Models/parakeet-unified-en-0.6b/parakeet_unified_encoder_st…" — permanently, on every launch.

Root cause chain:

  1. A torn/interrupted first-run download leaves the encoder .mlmodelc directory present but incomplete.
  2. FluidAudio's download gate is a single-file fileExists check on that directory → the download is skipped forever.
  3. MLModel.load throws; the raw CoreML error (with the file:// path) leaked verbatim into the menu bar.
  4. App-side "installed" meant "repo folder exists", so onboarding showed a green "Your speech model is ready" at the same time — and its Retry card was unreachable. No progress was shown during the download either (the app called FluidAudio's no-arg overloads; the pinned 0.15.5 exposes a byte-granular ProgressHandler on every entry point we use).

Fix

  • ParakeetModelIntegrity (core, unit-tested) — per-variant required-file manifests (unified tiers incl. the per-tier encoder suffix, EOU) + a generic coremldata.bin-per-.mlmodelc rule for the multilingual layout. Installed = verified complete everywhere (prefetch, readiness tracker, onboarding, Models pane).
  • Real download progressProgressHandler threaded through ParakeetBridge → engine readiness (throttled to whole percents) → menu-bar percentage, onboarding determinate bar + percent caption, Models-pane status row. The CoreML compile phase reports as .loading ("Optimizing the model for your Mac…").
  • Corrupt-cache auto-repair — a load failure with files present purges the variant's repo folder and redownloads once, inside the single-flight load task (covers the launch prefetch and the lazy first-dictation load). Cancellation (variant switch) passes through untyped so it can never trigger a purge.
  • Honest failure state — typed ParakeetBridgeError (download vs load) maps every failure to user copy; no file:// in the UI. parakeetPrefetchFailed now fires whenever the still-current engine failed (present-but-corrupt included), and onboarding precedence is flipped: failure outranks bytes-on-disk (Retry card instead of the green lie).
  • Settings → Models — verified per-variant badges, live download/compile/failure status, and an explicit Redownload Model repair button.

Tests

  • New ParakeetModelIntegrityTests (manifests, torn-bundle detection, tier-encoder mismatch, generic multilingual rule, verdict→badge mapping, no-file-URL copy guard).
  • OnboardingModelStatusTests: failure-beats-installed (fails without the fix), real-fraction pass-through, zero-progress-stays-indeterminate.
  • swift test: 2700 tests green. ./build.sh (full) and scripts/dev-app.sh (lean) both build.

Not covered by automation: the engine repair path itself (FluidAudio is app-only, outside swift test) — needs a live pass: delete coremldata.bin from the encoder bundle under ~/Library/Application Support/FluidAudio/Models/parakeet-unified-en-0.6b/ and relaunch; the app should purge, redownload with a visible percentage, and land Ready.

🤖 Generated with Claude Code

…erification, corrupt-cache repair

A fresh install could land in a permanently stuck state: a torn first-run
download leaves the FluidAudio repo folder present, FluidAudio's single-file
presence gate then skips the download forever, and MLModel.load fails on every
launch with a raw 'Unable to load model: file://…' in the menu bar — while
onboarding showed a green 'Your speech model is ready' (folder-presence ==
installed) and offered no repair.

- ParakeetModelIntegrity (core, tested): per-variant required-file manifests
  (unified tiers incl. per-tier encoder suffix, EOU) + generic mlmodelc
  coremldata.bin rule for the multilingual layout. 'Installed' now means
  verified complete everywhere (AppState, tracker, onboarding, Models pane).
- Real download progress: FluidAudio 0.15.5's ProgressHandler threaded through
  ParakeetBridge → engine readiness (throttled per whole percent) → menu bar
  percentage, onboarding determinate bar + percent caption, Models pane status.
  Compile phase reported as .loading ('Optimizing the model for your Mac…').
- Corrupt-cache auto-repair: a load failure with files present purges the
  variant's repo folder and redownloads once, inside the single-flight load
  task. Typed ParakeetBridgeError (download vs load; cancellation passes
  through untouched) maps failures to user copy — no more file:// URLs in UI.
- Honest failure flag: prefetch failure now reported whenever the engine is
  still current (present-but-corrupt included); onboarding precedence flipped
  so a failure outranks bytes-on-disk (failed card + Retry, not a green lie).
- Settings → Models: per-variant verified badges, live download/compile/failure
  status row, and an explicit 'Redownload Model' repair button.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@initcore0
initcore0 merged commit 0c1848c into main Aug 4, 2026
11 checks passed
initcore0 added a commit that referenced this pull request Aug 4, 2026
…ch TDT v3 and CTC biasing models (#247)

PR #246 closed the torn-cache trap (FluidAudio's presence-only download gate
skips redownload over a torn cache forever) for the STREAMING variants only.
The batch path had both gaps:

- ParakeetBridge.loadBatch now threads FluidAudio's ProgressHandler through
  (same ParakeetLoadPhase seam as loadStreamSession) and rethrows as the typed
  ParakeetBridgeError, cancellation passing through untyped.
- ParakeetFileEngine.loadTaskOnMain gets the purge-and-redownload-once repair
  inside the single-flight load task: a .load failure with the
  parakeet-tdt-0.6b-v3 repo folder present purges it and retries once.
  Download errors and cancellation never purge. Real download percentages +
  verified-completeness-based initial status flow to onWorkerStatus.
- ParakeetVocabularyBiaser.ensureLoaded gets the same repair for the CTC-WS
  model (parakeet-ctc-110m-coreml), still fail-open; a cancelled transcription
  no longer latches loadFailed. The manifest also requires tokenizer.json,
  which FluidAudio's own gate never checks (models load, tokenization fails).
- ParakeetModelIntegrity: batch + CTC repo manifests and an explicit-manifest
  verdict overload (core, tested); FluidAudioModelsLocator repo-folder verdict
  helper; ParakeetProgressThrottle shared by both engines.

Co-authored-by: Claude <noreply@anthropic.com>
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.

1 participant