fix: v3.5.10 — engine fallback installer (#39), German AI-analysis, install heartbeat - #40
Merged
Merged
Conversation
… engine Three reliability fixes surfaced after v3.5.9 (GitHub #39 + Reddit reports): #39 — "No transcription engine found": English jobs try Parakeet first, and when it crashes/fails on a file (the issue #23 Metal-crash class on certain MXF/AVC and some mp4 inputs) they fall back to Whisper, which isn't bundled on a fresh DMG. That dead-ended with a bare "pip install" 500 and no in-app installer. The /transcribe except handler now offers the same on-demand Whisper installer for ANY language once every engine is exhausted (gated on the "No transcription engine found" signal + _whisper_ready), keeping the project renderable so the banner survives a reload. Banner copy is now language-agnostic so English users aren't told their audio is "non-English". AI Analysis "produced no results" on German/long interviews: Ollama truncates format='json' output at num_predict (done_reason='length'); verbose languages (German ~40-50% more tokens) overflow routinely. _repair_truncated_json left a dangling key/value and produced invalid JSON, discarding even the complete leading items, so all categories came back empty. Rewrote it to rewind to the last fully-formed element of the deepest still-open container and close the rest, so every complete item survives. Also raised the analysis num_predict ceiling 4096 -> 8192 to avoid most truncation, replaced the misleading "restart the model" message, and guarded b-roll partials. Install stuck on "Starting install...": the installer's progress only updated on a newline boundary, so pip-to-a-non-TTY and the ~1.6 GB model download could go quiet for minutes inside a blocking read and leave the banner frozen. Added a background heartbeat (elapsed clock) independent of the read, an elapsed field on the status poll, and resilient frontend polling that surfaces lost server contact instead of freezing. Hardening (audit): _whisper_model_cached now rejects a truncated large-v3-turbo .pt on size so an interrupted download isn't reported as "ready", and the worker deletes the partial on failure so "Try again" re-downloads cleanly. Tests: English no-engine -> installer (and non-engine errors still 500), model size-floor, install heartbeat, and full _repair_truncated_json coverage. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ❌ Deployment failed View logs |
doza-assist | ae7606c | Jun 09 2026, 03:30 PM |
This was referenced Jun 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reliability fixes for the issues that surfaced right after v3.5.9 — the open GitHub issue #39 plus the two follow-ups from the Reddit thread (install hang, AI-analysis empty results). Root-caused with a multi-agent investigation + adversarial verification; ships only the load-bearing fixes (a couple of initially-proposed changes were dropped after verification flagged one as a regression and one as targeting an unreachable path).
1. #39 — "No transcription engine found" (the open issue)
English jobs try Parakeet first. When Parakeet crashes/fails on a file (the issue #23 Metal-crash class — certain MXF/AVC and some mp4 inputs), it falls back to WhisperX/Whisper, which isn't bundled on a fresh DMG. That dead-ended with a bare
pip install …500 and no in-app installer — the same dead-end class as #36, but for English.app.py/transcribeexcept handler now offers the same on-demand Whisper installer for any language once every engine is exhausted (gated on theNo transcription engine foundsignal and_whisper_ready()), and keeps the project atstatus='uploaded'so the banner survives a reload.Once the user installs Whisper once, future Parakeet crashes silently fall back to it — no more dead-end.
2. AI Analysis "produced no results" on German / long interviews
Ollama (
format='json') truncates output atnum_predict(done_reason='length'); token-verbose languages (German ≈ 40–50% more tokens for the same verbatim quotes) overflow routinely._repair_truncated_jsonwas closing braces at the raw cut point, leaving a dangling key/value → invalid JSON → the whole reply (including its complete leading items) was discarded → all categories empty → the misleading "the model may need to be restarted" message (a restart never helped)._repair_truncated_jsonto rewind to the last fully-formed element of the deepest still-open container and close the rest — every complete item survives, only the half-written trailing one is dropped. Idempotent on valid JSON.num_predictceiling 4096 → 8192 so most passes never truncate.3. Install stuck on "Starting install…"
The installer's progress only updated on a newline boundary, so
pippiped to a non-TTY and the ~1.6 GB model download could go quiet for minutes inside a blocking read, leaving the banner frozen._stream_subprocess(elapsed clock) that runs independently of the read, so the banner always moves while the worker is alive.elapsedfield on the status poll; frontend shows it and surfaces "lost contact" after repeated poll failures instead of freezing silently.4. Hardening (from the completeness audit)
An interrupted model download leaves a truncated
large-v3-turbo.ptat the final path, which the filename-only check reported as "ready" (re-introducing the #13/#36 silent-redownload symptom)._whisper_model_cached()now requires a full-size file (≥1.5 GB floor).Tests
tests/test_whisper_install_guard.py: English no-engine → installer; non-engine English errors still 500; model size-floor rejects truncated.pt; install heartbeat fires during a quiet child.tests/test_json_repair.py(new): all canonical truncation shapes parse, complete items survive, nested arrays preserved, valid JSON untouched, end-to-end through_parse_json_response.All new/extended tests pass. The 18 pre-existing failures on
main(chat-prompt / editorial-DNA suites) are unrelated to this change and reproduce on the base branch.🤖 Generated with Claude Code