Files
orca/src/main/speech
Brennan Benson 33a8df93fc fix(speech): resume interrupted voice model downloads and surface real errors (#8775)
* fix(speech): resume interrupted voice model downloads and surface real errors

Voice model downloads that died late in the transfer (flaky networks,
scanning proxies) failed at the UI's 90% progress cap and restarted from
byte zero on every retry, so affected users could never complete any
model download (#8620 / STA-1775).

- Retry transient download failures (net::ERR_* transfer cuts, resets,
  timeouts, HTTP 5xx/429) with an HTTP Range resume from the bytes
  already on disk, restarting from the canonical URL each attempt since
  signed CDN redirect URLs expire; bounded backoff, gives up after
  repeated zero-progress attempts with a diagnosable error.
- Correct catalog sizeBytes to exact upstream asset sizes (parakeet
  v2/v3 are 482/487 MB, not 170/180; paraformer is 1,047 MB, not 115) —
  also the progress denominator when content-length is missing.
- Show the underlying failure cause in the download-error toast and log
  it in main; it was previously invisible everywhere.

All 7 pinned catalog SHA-256 hashes verified against current upstream
assets. Live-verified end to end: a transfer killed mid-body resumes
with a 206 and completes through checksum, extraction, and validation.

Fixes #8620

* fix(speech): harden resumed model downloads

* fix(speech): validate resumed download completion

* fix(speech): keep segmented download resumes progressing

* fix(speech): don't abandon a download that keeps making progress

The retry loop gave up after 8 total failures regardless of progress, so
a large model (e.g. the ~1GB Paraformer) over a network that resets every
few hundred MB was abandoned mid-download even though every attempt was
resuming and advancing — the exact 'stuck then fails' symptom, just later.

Replace the all-time failure budget and the separate advancing-segment
cap with a single rule: give up only on a genuine stall (repeated
attempts with no forward progress) or an absolute request ceiling that
bounds a pathological tiny-segment server. Any download that keeps
advancing now runs to completion.

Verified live under Electron 43: a transfer reset mid-stream on every
attempt but advancing each time previously gave up at 67% after 8
attempts; it now completes. All prior resume/cancel/timeout scenarios
still pass.
2026-07-14 17:49:13 -07:00
..