Skip to content

fix: v3.5.10 — engine fallback installer (#39), German AI-analysis, install heartbeat - #40

Merged
DozaVisuals merged 2 commits into
mainfrom
fix/v3.5.10-engine-fallback-install-analysis
Jun 9, 2026
Merged

DozaVisuals merged 2 commits into
mainfrom
fix/v3.5.10-engine-fallback-install-analysis

Conversation

@DozaVisuals

Copy link
Copy Markdown
Owner

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 /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 and _whisper_ready()), and keeps the project at status='uploaded' so the banner survives a reload.
  • The pre-flight guard is deliberately left English-bypassed (English may still succeed via Parakeet).
  • Frontend banner copy is now language-agnostic (English users were being told their audio was "non-English").

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 at num_predict (done_reason='length'); token-verbose languages (German ≈ 40–50% more tokens for the same verbatim quotes) overflow routinely. _repair_truncated_json was 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).

  • Rewrote _repair_truncated_json to 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.
  • Raised the analysis num_predict ceiling 4096 → 8192 so most passes never truncate.
  • Replaced the misleading error message with an honest, actionable one.
  • Guarded b-roll partials (no timecode → skip).

3. Install stuck on "Starting install…"

The installer's progress only updated on a newline boundary, so pip piped to a non-TTY and the ~1.6 GB model download could go quiet for minutes inside a blocking read, leaving the banner frozen.

  • Background heartbeat in _stream_subprocess (elapsed clock) that runs independently of the read, so the banner always moves while the worker is alive.
  • elapsed field 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.pt at 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).
  • The worker deletes the undersized partial on failure so "Try again" re-downloads cleanly.

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.

Note: the actual 3.5.10 DMG still needs the local signed/notarized build + GitHub release.

🤖 Generated with Claude Code

DozaVisuals and others added 2 commits June 9, 2026 11:30
… 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>
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
❌ Deployment failed
View logs
doza-assist ae7606c Jun 09 2026, 03:30 PM

@DozaVisuals
DozaVisuals merged commit 78b9116 into main Jun 9, 2026
2 of 3 checks passed
@DozaVisuals
DozaVisuals deleted the fix/v3.5.10-engine-fallback-install-analysis branch June 9, 2026 16:06
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