1148 Commits
Author SHA1 Message Date
SurefireStudios 968d05faea fix(sidecar): derive the generate deadline from the request's own budget
Greptile on #2109: a flat 600s default still undercuts the budget the job
was granted. generate_timeout_s adds 1s per 40 characters past a 1200-char
allowance and can be raised by env, so a long passage is granted more than
600s and a constant deadline only moves the cliff to longer inputs rather
than removing it. The comment on GENERATE_RECV_TIMEOUT_S claimed the inner
deadline "can never fire before the outer budget", which was not true for
those inputs.

_effective_recv_timeout_s(text) now takes the larger of the engine's own
value and the budget this specific request was granted, and generate()
uses it for both the first frame and the progress loop.

Only for engines that expressed no opinion. An override is a deliberate
statement about that model, and #2103 asks for "fast engines opt down" to
keep working, so a subclass that sets recv_timeout_s keeps exactly that
value — including a smaller one. Detected by walking __mro__ for a
recv_timeout_s in a subclass __dict__ rather than comparing values, so an
engine that happens to pick the same number as the floor is still honoured.

Budget probing is advisory: any failure falls back to the class floor
rather than turning a working generate into an error.

Tests: a long passage raises the deadline above the flat floor and tracks
generate_timeout_s; an opt-down engine keeps its value at any text length;
a failing probe falls back. Verified load-bearing by making the derivation
return the engine value unconditionally (the long-passage test fails on
600.0 > 600.0).
2026-09-16 14:36:19 -07:00
SurefireStudios a65a0a95af fix(sidecar): stop killing generations at the health-check ping budget
SubprocessBackend.recv_timeout_s defaulted to RECV_TIMEOUT_S (60s), the
budget for a health_check ping. Four engines never overrode it and so used
a ping's deadline as their generation deadline: confucius4-tts, dots-tts,
moss-tts-v15 and supertonic3. All four fall back to CPU off CUDA, where a
normal sentence does not finish in 60s, and the watchdog killed them
mid-synthesis.

That deadline sat 5-10x below the wall-clock budget the same job was
granted by model_manager.generate_timeout_s (300s accelerated, 600s CPU),
so the sidecar was reclaimed while its caller still considered it well
inside budget. Every engine that did override the hook chose 300s..900s,
at or above the accelerated budget; omnivoice_subprocess documents the
intent as "aligns the kill deadline with the generate budget". The 60s
default contradicted that intent for anyone who did not opt out of it.

which left the class default and the four silent engines untouched.

Default to GENERATE_RECV_TIMEOUT_S (600s, the CPU budget floor) so an
engine that expresses no opinion can no longer be cut off before its own
job budget. RECV_TIMEOUT_S stays 60s for health_check, where a ping must
stay fast. Overriding is still how an engine asks for more.

Second half: the watchdog logged "exceeded recv timeout; killing" but
generate() raised "sidecar closed pipe mid-generate", so the one fact that
explained the failure never left the backend log and reporters read it as
a crash. _last_recv_timed_out already distinguished the two for the spawn
handshake (#2026); use it here too and name the deadline, the elapsed
time and the sidecar's last stderr. Crash wording is unchanged.

Tests: a registry invariant that no SubprocessBackend can be dispatched
with a deadline under the accelerated budget, so a new engine cannot
inherit this by omission the way these four did; lockstep with
model_manager's budgets; and a wedging sidecar asserting the timeout
message. Verified fail-before/pass-after by reverting the default to 60s
(all 7 fail, naming exactly the four engines) and by forcing the crash
wording (the message test fails).

Fixes #2103
2026-09-16 14:36:09 -07:00
Palash Debnath 1fea27543b Harden release authorization and preserve demo playback across languages 2026-09-17 02:38:09 +05:30
Palash Debnath 6cb1200b4e Merge branch 'velixio_dev' into fix/linux-electron-setup-sidebar 2026-09-17 01:55:33 +05:30
Palash Debnath 50d01567d4 Keep read-only telemetry outside worker drain and shutdown gates 2026-09-17 01:55:23 +05:30
Palash Debnath 03460c89b7 Merge branch 'velixio_dev' into fix/linux-electron-setup-sidebar 2026-09-17 01:42:08 +05:30
Palash Debnath 2ee455cc1f Prevent telemetry admission while the worker is retiring 2026-09-17 01:41:59 +05:30
Palash Debnath 715bbbde70 Merge branch 'velixio_dev' into fix/linux-electron-setup-sidebar 2026-09-17 01:41:14 +05:30
Palash Debnath 9ca9f74255 Merge branch 'review/gpu-2149' into fix/linux-electron-setup-sidebar 2026-09-17 01:41:08 +05:30
Palash Debnath 8804ddac9a Own telemetry probes through shutdown and localize Electron metrics 2026-09-17 01:40:58 +05:30
Palash Debnath b67aed2794 Resolve GPU stability review privacy, localization and test isolation findings 2026-09-17 01:40:58 +05:30
Palash Debnath 2faaafa9fc Merge remote-tracking branch 'origin/main' into review/gpu-2149 2026-09-17 01:39:08 +05:30
Palash Debnath 39d66d5299 Prepare v0.5.3 for Electron and the final Tauri update 2026-09-17 01:30:17 +05:30
velixio 719ef8a698 fix(workers): harden remote telemetry 2026-09-17 01:23:37 +05:30
velixio 10d086359c feat(workers): show remote telemetry 2026-09-17 01:08:38 +05:30
LMG XENON be1be89a69 Merge branch 'main' into fix/apple-silicon-metal-docs-ci-2105 2026-09-16 19:36:08 +01:00
LMG XENON 15ef5da87d Merge branch 'debpalash:main' into fix/sidecar-recv-timeouts-2103 2026-09-16 19:34:58 +01:00
Shivendra-CoherentandClaude Opus 5 34b5eaabf1 fix(subtitles): keep cue lines that are only a number
An imported or pasted subtitle whose line is just a number — a year, a
score, a street number, a "3 / 2 / 1" countdown — was silently deleted,
and when that line was the cue's only text the whole cue disappeared.

Cue bodies are sliced from a timing line up to the next one, which
swallows the next cue's index. The parser clawed that back by popping
every trailing digit-only line, a rule that cannot tell an index from
numeric dialogue. Three shapes fell out of it:

- the last cue of a file has no next index to pop, so a closing "1999"
  was taken for one and the cue was dropped as empty;
- an index-less export has no indices at all, yet still lost its
  closing numeric line — and lost it without counting a skip, so the
  import reported itself lossless while dropping a line;
- the `while` loop popped digit lines until it hit a non-digit, eating
  a multi-line countdown cue whole.

Give back exactly the one line that was swallowed: a single line, only
when a next cue exists to own it, and only in a file that indexes its
cues at all — decided once from the preamble before the first timing
line, since a body of "42" is indistinguishable from an index on its
own. Index detection is ASCII-only, because `str.isdigit()` is also
true for Arabic-Indic and Devanagari numerals, which in a 646-language
dubbing app are dialogue rather than SubRip indices.

Affects both subtitle entry points: POST /dub/import-srt/{job_id} and
POST /dub/parse-subtitle-text.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 18:10:51 +05:30
Shivendra-CoherentandClaude Opus 5 64f74e0dd2 fix: keep the backend alive on pre-Ampere NVIDIA GPUs (#2135)
On a Tesla T4 the backend exited during the first /generate with no
traceback and no HTTP response, leaving the client with
RemoteDisconnected and every later call with ConnectionRefused. Three
separate defects combined, which is why none of the reporter's
workarounds helped.

1. torch.compile(mode="reduce-overhead") captures CUDA graphs. T4
   (sm_75) passed the existing arch gate, so capture was attempted and
   aborted the process from inside the native CUDA library — below the
   interpreter, where neither the #278 eager-fallback wrapper nor any
   except clause can see it. The compile mode is now resolved per GPU:
   Ampere (sm_80) and newer keep the cudagraph mode, older cards drop to
   the non-cudagraph "default" mode and keep their compiled Inductor
   kernels. Fails open on any probe error, so no GPU that works today
   loses the optimization. OMNIVOICE_FORCE_CUDAGRAPH=1 restores it.

2. should_torch_compile() never read TORCH_COMPILE_DISABLE. main.py sets
   it on win32, build_engine_env injected it into subprocesses, and
   docs/install/windows.md tells users to export it — but the in-process
   gate ignored it, so the reporter exported the documented variable and
   still got "torch.compile applied". The gate now honours
   TORCH_COMPILE_DISABLE / TORCHDYNAMO_DISABLE / TORCHINDUCTOR_DISABLE on
   every platform, and an env opt-out on the parent propagates to engine
   subprocesses. The settings DB path is logged alongside the toggle:
   the reporter had three omnivoice.db files and edited one the backend
   never opened.

3. Settings -> Performance -> "Disable torch.compile" was rendered
   disabled outside Windows in both the Tauri and Electron UIs, so the
   one control that would have stopped this was unreachable for the
   affected Linux user. The toggle is now live on every platform, and
   build_engine_env honours it everywhere rather than only on win32.

Also arms faulthandler before torch is imported, so a fatal native
signal writes the faulting thread's Python stack to backend_err.log
instead of the process vanishing silently. This does not prevent a
crash; it makes one diagnosable. OMNIVOICE_DISABLE_FAULTHANDLER=1 skips
it.

Tests fail before / pass after, verified by stashing the source and
running the new tests against unfixed code. The crash test kills a real
child interpreter with a real SIGSEGV and requires a named Python frame
in the output. test_torch_compile_path_gate's fixture now clears the
compile-disable env vars: main.py setdefaults them on win32, so on a
Windows runner they leaked into os.environ and decided those tests.

Not verified on real hardware — no Turing GPU available. The sm_80 floor
is inferred from the crash report and from docs/hardware-notes-tesla-t4.md,
which already flagged cudagraphs on T4 as attempted by default and never
evaluated.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 17:20:09 +05:30
Gyanu Mayank b6c4640b7d fix: Argos language names and BCP-47 tags map to ISO 639-1
Argos Translate ships pairs as zh, not Chinese. Passing the UI
label or a tag like cmn-Hans made get_translation_from_codes
return None and every subtitle stayed in the source language.

Fixes #2140
2026-09-16 08:42:35 +05:30
denemon d6b1326aae fix(dub): observe late _ping_while failures and fix locale log labels
- _ping_while retrieves failures that occur after the consumer disconnects,
  preventing "exception was never retrieved" at GC; the early-exit test
  covers this case
- stream_cut_backend_alive_local now builds the Settings → Logs → Backend
  path from each locale's actual UI labels (`settings.title`,
  `settings.logs`, `common.backend`)
- Fix incorrect section names in 15 locales, including ru, de, and zh-TW

Addresses CodeRabbit review on #2138
2026-09-16 02:38:55 +09:00
denemon 052eb1050b fix(dub): cancel wrapped work when the transcribe stream closes early
`_ping_while` runs awaited work as its own task, so a client disconnect
previously cancelled only the ping loop. Reference-text refinement could
continue running while `run_transcribe_guarded` skipped its abandon path
and the stream finalizer unloaded the ASR model underneath it.

Cancel unfinished work on early exit, matching the cancellation behavior
of the bare `await` it replaced. Do not await it in `finally`, which can
also run under `GeneratorExit`.

- **dub_core**: `_ping_while` cancels an unfinished future in `finally`,
  covering all seven call sites
- **test**: verify that `_ping_while` cancels work on `aclose()` while
  leaving completed work untouched (fail-before / pass-after)
- **CHANGELOG**: add a Highlights entry for the user-visible fix; keep
  Fixed entries under `### Fixed` per `CLAUDE.md`

Addresses Greptile P1/P2 on #2138
2026-09-16 02:30:16 +09:00
denemon 22e52c64a4 fix(dub): keep SSE streams alive through byte-silent steps (#2108)
After transcription, several minutes of backend work could produce no
SSE bytes, causing the desktop webview to close the idle connection while
the job continued and eventually completed. This also led to a misleading
reverse-proxy error on local connections.

- dub_core: keep post-transcript awaits alive with `_ping_while` (5s pings)
- dub_export: send SSE comments after 15s of stream silence
- backendCrash.ts: show deployment-aware connection-loss guidance
- Add regression tests for post-transcript pings, task-stream keepalive,
  and local-mode error messaging

Fixes #2108
2026-09-16 02:08:54 +09:00
Palash Debnath 61d52944f2 fix(dub): correct long timeline rendering and repeated ASR context 2026-09-15 20:02:18 +05:30
Palash Debnath 730c7f377c feat(dub): save custom agent translation style instructions 2026-09-15 19:10:24 +05:30
Palash Debnath 7758ccc500 fix(dub): preserve original sound outside dialogue intervals 2026-09-15 19:02:25 +05:30
Palash Debnath 0a6ea976cb fix(dub): preserve complete speech and reject silent partial output 2026-09-15 15:44:57 +05:30
LMGXENON 0c71d506ec docs: document Apple Silicon Metal build parity and drop continue-on-error (#2105)
- Drops experimental flag (continue-on-error) on macos-14 in build-omnivoice-tts.yml now that omnivoice.cpp builds cleanly with -DGGML_METAL=ON at the pinned SHA.
- Updates bin/README.md, backend/engines/omnivoice_gguf/README.md, and SPIKE-01 ADR to document verified Apple Silicon Metal acceleration.
- Corrects workflow reference in bin/README.md.
- Adds changelog credit for @martinezpl.

Closes #2105
2026-09-15 01:02:01 +01:00
LMGXENON 50cba2881c fix(engine): initialize timed_out before empty-reply check and move credit to Highlights (#2103) 2026-09-15 00:43:25 +01:00
LMGXENON 750aa2eb57 fix(engine): validate ASR timeouts, reserve outer guard grace, and enhance diagnostics (#2103) 2026-09-15 00:34:18 +01:00
LMGXENON ddb8e4dd86 fix(engine): address review findings on sidecar deadlines, ASR timeout, and changelog credit (#2103) 2026-09-15 00:22:55 +01:00
LMGXENON ba041b0723 fix(engine): report sidecar receive timeouts and raise engine deadlines (#2103)
- SubprocessBackend and SubprocessASRBackend now check _last_recv_timed_out
  when a sidecar stream closes unexpectedly, reporting an actionable timeout
  error with the deadline rather than describing a generic pipe-closed crash.
- Confucius4Backend, DotsTTSBackend, MossTTSV15Backend, and Supertonic3Backend
  now define generous recv_timeout_s properties with OMNIVOICE_* env overrides,
  preventing mid-generation termination on slower CPU/MPS devices.
- Adds regression tests in backend/tests/test_omnivoice_subprocess.py.

Closes #2103
2026-09-15 00:09:17 +01:00
Palash Debnath 141b42f7a6 fix: restore desktop integration contracts 2026-09-14 10:53:55 -07:00
Palash Debnath f832d616f7 feat(electron): add full VoiceStudio desktop app 2026-09-14 10:22:23 -07:00
kapelame c5f3355951 fix(audio): preserve the parent directory when locating ffprobe 2026-09-14 11:29:42 -04:00
kapelame 68653ca408 fix(audio): resample MLX outputs to the declared sample rate 2026-09-14 11:29:38 -04:00
moep90 df18ac177e docs: correct the Blackwell/Triton attribution behind the #278 fallback
Three comments name Blackwell sm_120 as an architecture Triton/Inductor does
not support. Measured on an sm_120 device with the pinned torch 2.8.0+cu128
and triton 3.4.0: torch.compile default and reduce-overhead (the
cudagraph_trees path #278 names), an attention module over growing sequence
lengths, and a raw Triton kernel all run, with compiled output matching eager
(maxdiff 1.19e-06 and 0.0). The app's own probe agrees — arch_unsupported
returns None, so compile is already attempted there.

The error text #278 quotes is also misattributed. "Detected that you are using
FX to symbolically trace a dynamo-optimized function" reproduces with CUDA
unavailable: Dynamo raises it whenever FX traces a compiled function,
regardless of device. It belongs in the compile-stack classifier, not in the
evidence for a missing-architecture failure.

Comments only. The fallback contract and the arch-list gate are unchanged and
still correct: the gate is generic rather than a Blackwell blocklist, and on a
build whose arch list lacks the device the described mechanism holds. Only the
example and the FX attribution are stale.

Signed-off-by: Moep90 <volleyballlive@googlemail.com>

Signed-off-by: moep90 <volleyballlive@googlemail.com>
2026-09-14 06:54:15 +02:00
moep90 42acd7d12f docs: correct the same sm_120 claim in the troubleshooting guide
Review catch: the code comments were corrected while
docs/install/troubleshooting.md still gave users the false diagnosis in two
places, which is the docs-sync rule exactly. The user-facing wording was the
stronger of the two:

  5b:   "the wheel does not contain code for the GPU" and "no setting works
        around it"
  1052: "This is a property of the pinned build, not of your driver or your
        install"

The second is actively misleading. Since torch 2.8.0+cu128 does list sm_120 in
get_arch_list(), the driver, the platform and the native init path are exactly
where the cause plausibly is, and the doc steered readers away from them.

Both sections now state that the cause is not established, that the pinned
build does contain Blackwell code, and that moving the trio to 2.9.x is the
known workaround for the users who hit it. 5b also gains a get_arch_list()
command so a reader can check their own build instead of trusting a blanket
claim. The fix steps are unchanged.

Also softens the CU128_ARCHS citation in the three comments. That list is
fixture data fed to a mocked torch, captured verbatim from the #1285 report,
so it corroborates the arch list but does not assert what the installed wheel
contains. Saying it "already asserts" overstated it.

Signed-off-by: Moep90 <volleyballlive@googlemail.com>

Signed-off-by: moep90 <volleyballlive@googlemail.com>
2026-09-14 06:37:01 +02:00
moep90 7fe80a5ab8 docs: correct the sm_120 kernel claim behind the #1931 torchaudio guard
Three comments justify the set_audio_backend() hasattr guard by asserting
that the pinned torch 2.8.0 carries no sm_120 kernels, so Blackwell owners
have no choice but to upgrade. The pinned build does carry them.

On a Blackwell GPU (capability (12, 0)) running this repo's own resolved
environment, torch 2.8.0+cu128 reports:

    arch_list   ['sm_70', 'sm_75', 'sm_80', 'sm_86', 'sm_90', 'sm_100', 'sm_120']
    capability  (12, 0)
    cuda_matmul OK

import torch succeeds and CUDA runs. pyproject.toml:282 resolves torch from
the cu128 index, and tests/test_cuda_arch_compat.py:39 already lists sm_120
in CU128_ARCHS, so the repo asserted the opposite of these comments in two
places at once.

#1931 itself reported an `import torch` access violation on Windows with an
sm_120 card, and attributed it to missing kernel support. The symptom was
real and the reporter did resolve it by moving to torch 2.9.1; the stated
mechanism is what got copied into the comments.

The guard's justification survives intact: sm_120 users did land on torch
2.9.x, which brings torchaudio 2.9, which is what removed set_audio_backend().
Only the reason changes. Also drops two related over-attributions in the same
files, where the crash was described as hitting Blackwell or RTX 50-series
machines rather than any machine on torchaudio 2.9.

Comments and one assertion message only. No behaviour change, no test logic
touched. Not re-litigating #1931's fix.

Signed-off-by: Moep90 <volleyballlive@googlemail.com>

Signed-off-by: moep90 <volleyballlive@googlemail.com>
2026-09-14 06:30:19 +02:00
moep90 23df0e80ad docs(audio): correct the torch 2.8.0 sm_120 claim in the TorchCodec comments
Both comments said #1931's cohort has no choice but to leave the torch 2.8.0
pin because it carries no sm_120 kernels. That is wrong for this repo's pin:
pyproject resolves torch==2.8.0 from the cu128 index, whose arch_list
includes sm_120 (confirmed on an sm_120 device, and already asserted by
CU128_ARCHS in tests/test_cuda_arch_compat.py).

State the forcing function that is actually verifiable instead: torch 2.8.0
publishes no aarch64 wheel, so arm64 CUDA hosts land on 2.9 with no 2.8.0
option at all. Comments only, no behaviour change.

Signed-off-by: Moep90 <volleyballlive@googlemail.com>

Signed-off-by: moep90 <volleyballlive@googlemail.com>
2026-09-14 06:22:51 +02:00
Moep90 05ee8c90b2 fix(audio): fall back to soundfile when torchaudio 2.9 routes I/O through TorchCodec
torchaudio >= 2.9 sends save()/load() through TorchCodec, which requires
FFmpeg shared libraries. Without them every generation returns 500 and every
reference-audio read (cloning, watermark, dub) raises ImportError.

Follow-up to #1931: that issue's fix guarded set_audio_backend() but left
load()/save() unprotected, so the RTX 50-series users it identified as having
no choice but to leave the torch 2.8.0 pin still hit a hard failure.

- _safe_torchaudio_save: fall back to the audited _safe_soundfile_write
- _safe_soundfile_write: optional format= passthrough (BytesIO needs it)
- load_audio: catch ImportError so its existing pydub fallback actually runs

backend="soundfile" does not avoid this; 2.9 accepts and ignores it.

Signed-off-by: Moep90 <volleyballlive@googlemail.com>
2026-09-14 06:05:49 +02:00
kevin9327andClaude Opus 5 151d58f024 fix(dub): a pasted WebVTT file maps its cues, not its markup
Dub -> Paste translation -> Load file accepts .vtt and sends timestamped
text to the lenient SRT parser, which is meant to take VTT too. Two
ordinary WebVTT files broke it:

- Cues without an hours field (00:01.000 --> 00:04.500) matched neither
  the frontend's timing detector nor the backend pattern, so the dialog
  mapped WEBVTT, the timing lines and the dialogue as plain translations,
  and the endpoint itself answered "No timed cues found".
- A cue identifier or NOTE block after a cue became part of that cue's
  text, because only digit-only index lines were trimmed.

The hours are now optional in both patterns, as dub_pipeline's yt-dlp
caption parser already allows. For WebVTT input a cue's text ends at its
first blank line, as the format specifies; SRT keeps its lenient
blank-line handling.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 08:48:05 +09:00
kevin9327andClaude Opus 5 3cd67811e5 fix(subtitles): exported cue times keep their milliseconds
The SRT/VTT formatters in dub_export and openai_compat truncated
(seconds % 1) * 1000. Most decimal times are not exact in binary (2.3 is
2.29999...), so a cue imported as 00:00:02,300 exported as 00:00:02,299:
every such cue moved a millisecond early in the /dub/srt and /dub/vtt
downloads, burned-in subtitles, and /v1/audio/transcriptions srt/vtt.

All four now call srt_parser.format_cue_timestamp, which rounds the whole
value to milliseconds once and splits it, so 59.9996 carries to
00:01:00,000 rather than printing ",1000" -- the same round-then-divmod
shape karaoke_ass._ass_time already uses.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 08:31:19 +09:00
kevin9327andClaude Opus 5 ad4b3547d4 fix(import): an undefined Windows-1252 byte no longer spoils the whole file
Review follow-up. A Windows-1252 upload with one of the five bytes cp1252
leaves undefined fell back to decoding the entire file as Latin-1, so its
curly quotes, dashes and euro signs became C1 control characters. Only
the undefined bytes now take their Latin-1 code point, which is what the
browser's windows-1252 decoder does, so readTextFile and
decode_text_upload agree byte for byte.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 08:21:52 +09:00
kevin9327andClaude Opus 5 c8c833062b fix(import): read UTF-16 and Windows-1252 subtitles and manuscripts
/dub/import-srt fell back to Latin-1 when UTF-8 failed, so a UTF-16 .srt
(Notepad's "Unicode", many subtitle editors) decoded with a NUL between
every character and was rejected as having no cues, and a Windows-1252
one turned curly quotes and dashes into C1 control characters.
/audiobook/import decoded .txt/.md with errors="ignore", silently dropping
every accent, dash and curly quote from a Windows-1252 manuscript,
returning NUL-interleaved text for a UTF-16 one, and keeping a UTF-8 BOM
at the start of the editor text.

Both now use decode_text_upload: a BOM names the encoding, valid UTF-8
stays UTF-8, and anything else is read as Windows-1252, with Latin-1 for
the bytes cp1252 leaves undefined so the decode never raises.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 08:14:46 +09:00
Palash Debnath bd9be744eb Merge remote-tracking branch 'origin/main' into fix/mcp-timeout-follows-backend
# Conflicts:
#	CHANGELOG.md
2026-09-10 16:15:59 -07:00
Palash Debnath 5ca94b7d72 Merge remote-tracking branch 'origin/main' into fix/pytorch-whisper-vram-budget
# Conflicts:
#	CHANGELOG.md
2026-09-10 15:52:34 -07:00
Palash Debnath 7247cef1b6 Merge remote-tracking branch 'origin/main' into fix/mcp-timeout-follows-backend
# Conflicts:
#	CHANGELOG.md
2026-09-10 15:52:21 -07:00
Palash Debnath e7911e3e97 fix(asr): reduced VRAM budgets only for exact OpenAI Whisper ids
Review follow-up. The budget matched model names by substring, so a custom
repo whose name contains "turbo", "small" or "base" (or a word such as
"database") got a reduced budget and could be admitted to CUDA without
enough memory. Reduced budgets now apply only to the exact OpenAI
checkpoint ids, .en variants included. Any other repository, fine-tunes
included, keeps the conservative 5.0 GB, as the engine doc says.
2026-09-10 15:33:11 -07:00
Palash Debnath d37da79b34 fix(mcp): generation waits also cover the backend's queue clock
Review follow-up. A generation first waits in the GPU pool's queue, on its
own clock (GPU_QUEUE_TIMEOUT_S, 1800 s by default), before its execution
budget starts, so a 630 s wait could still give up before the backend
returned its queue error. The generate wait now adds the queue budget.
Transcription is unchanged: run_transcribe_guarded starts its 300 s clock
at submission, so queue time already counts against it.

Parity tests pin each tool's wait above the backend's own worst case,
from ASR_TRANSCRIBE_TIMEOUT_S, GPU_QUEUE_TIMEOUT_S and generate_timeout_s
on cpu, cuda and mps. A later backend change that outgrows the MCP wait
now fails a test. A new case covers a CPU budget larger than the GPU one.
2026-09-10 15:31:14 -07:00