Created
August 12, 2026 07:12
-
-
Save danieldormann/cc10779192754366d5e50fd3fcd48348 to your computer and use it in GitHub Desktop.
Expose vexa's STT Whisper chunking to .env and increase the window
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
| diff --git a/core/meetings/modules/mixed-pipeline/src/chunked-transcriber.ts b/core/meetings/modules/mixed-pipeline/src/chunked-transcriber.ts | |
| index f37484f5..402c6784 100644 | |
| --- a/core/meetings/modules/mixed-pipeline/src/chunked-transcriber.ts | |
| +++ b/core/meetings/modules/mixed-pipeline/src/chunked-transcriber.ts | |
| @@ -51,6 +51,13 @@ import type { TranscriptionResult } from '@vexa/transcribe-whisper'; | |
| import { localAgreement } from '@vexa/transcribe-buffer'; | |
| const SAMPLE_RATE = 16000; | |
| +/** Operator-set positive-number knob. A missing, empty, or malformed value falls back to the | |
| + * built-in default: a NaN threshold would compare false everywhere and silently wedge the | |
| + * submit path, so a fat-fingered env var must never be load-bearing. */ | |
| +const envMs = (raw: string | undefined, fallback: number): number => { | |
| + const n = Number(raw); | |
| + return raw !== undefined && raw.trim() !== '' && Number.isFinite(n) && n > 0 ? n : fallback; | |
| +}; | |
| /** Near-silent spans are dropped before Whisper (desktop's DROP_RMS). */ | |
| const DROP_RMS = 0.006; | |
| /** Ring capacity — must hold a full unconfirmed window plus segmenter lag. */ | |
| @@ -88,13 +95,16 @@ const SILENCE_CLOSE_CONTEXT_MS = Number((typeof process !== 'undefined' && proce | |
| * sentence pauses, below an awkward wait. */ | |
| const CONFIRM_TTL_MS = 2500; | |
| /** Don't bother Whisper with unconfirmed windows shorter than this unless | |
| - * the turn is closing. */ | |
| -const MIN_SUBMIT_MS = 800; | |
| + * the turn is closing. Raising it buys the decoder more acoustic context per | |
| + * call (fewer, longer windows) at the cost of a later first pending — worth it | |
| + * on languages where short windows mis-decode. Tunable via BOT_MIXED_MIN_SUBMIT_MS. */ | |
| +const MIN_SUBMIT_MS = envMs(typeof process !== 'undefined' ? process.env?.BOT_MIXED_MIN_SUBMIT_MS : undefined, 800); | |
| /** Time-based resubmission cadence for the OPEN turn (the bot's | |
| * submitInterval): pending refreshes and LocalAgreement stability build at | |
| * this pace instead of waiting for the next boundary (which can be 10s away | |
| - * inside a monologue). Pending ≈ tick + RTT; confirm ≈ 2 ticks. */ | |
| -const SUBMIT_TICK_MS = 2000; | |
| + * inside a monologue). Pending ≈ tick + RTT; confirm ≈ 2 ticks — so raising it | |
| + * trades confirm latency for context. Tunable via BOT_MIXED_SUBMIT_TICK_MS. */ | |
| +const SUBMIT_TICK_MS = envMs(typeof process !== 'undefined' ? process.env?.BOT_MIXED_SUBMIT_TICK_MS : undefined, 2000); | |
| /** A short isolated active-speaker UI switch (Zoom/Teams) right after a different | |
| * published speaker is held provisional rather than stamped — without acoustic | |
| * evidence a brief tile flip is more likely a stale/echoed hint than a real, | |
| diff --git a/core/runtime/src/runtime_kernel/profiles.py b/core/runtime/src/runtime_kernel/profiles.py | |
| index 5df9cea0..479e3a66 100644 | |
| --- a/core/runtime/src/runtime_kernel/profiles.py | |
| +++ b/core/runtime/src/runtime_kernel/profiles.py | |
| @@ -105,6 +105,8 @@ def default_registry() -> ProfileRegistry: | |
| "BOT_SPEAKER_CONFIRM_THRESHOLD", | |
| "BOT_SPEAKER_MAX_BUFFER_SEC", | |
| "BOT_SPEAKER_IDLE_TIMEOUT_SEC", | |
| + "BOT_MIXED_MIN_SUBMIT_MS", | |
| + "BOT_MIXED_SUBMIT_TICK_MS", | |
| ) | |
| if os.environ.get(key, "").strip() | |
| } | |
| diff --git a/deploy/compose/.env.example b/deploy/compose/.env.example | |
| index 2f86c1ac..13019e9e 100644 | |
| --- a/deploy/compose/.env.example | |
| +++ b/deploy/compose/.env.example | |
| @@ -122,6 +122,11 @@ BOT_SPEAKER_SUBMIT_INTERVAL_SEC= | |
| BOT_SPEAKER_CONFIRM_THRESHOLD= | |
| BOT_SPEAKER_MAX_BUFFER_SEC= | |
| BOT_SPEAKER_IDLE_TIMEOUT_SEC= | |
| +# Mixed lane (Zoom/Teams/Jitsi) STT windowing. Defaults 800 / 2000 ms. Raise both to give the | |
| +# decoder more acoustic context per Whisper call — fewer, longer windows decode short words more | |
| +# reliably (notably in German), at the cost of a later pending (≈ tick) and confirm (≈ 2 ticks). | |
| +BOT_MIXED_MIN_SUBMIT_MS= | |
| +BOT_MIXED_SUBMIT_TICK_MS= | |
| # Self-hosted Jitsi hostnames (comma-separated, e.g. calls.example.org) recognized when parsing | |
| # pasted meeting links AND calendar (ICS) links. meet.jit.si and hosts naming "jitsi" are always | |
| # recognized; hosts with a "meet" label (meet.example.org, eu.meet.example.org) are recognized in | |
| diff --git a/deploy/compose/docker-compose.yml b/deploy/compose/docker-compose.yml | |
| index 50f4a763..49b0cf3b 100644 | |
| --- a/deploy/compose/docker-compose.yml | |
| +++ b/deploy/compose/docker-compose.yml | |
| @@ -148,6 +148,8 @@ services: | |
| - BOT_SPEAKER_CONFIRM_THRESHOLD=${BOT_SPEAKER_CONFIRM_THRESHOLD:-} | |
| - BOT_SPEAKER_MAX_BUFFER_SEC=${BOT_SPEAKER_MAX_BUFFER_SEC:-} | |
| - BOT_SPEAKER_IDLE_TIMEOUT_SEC=${BOT_SPEAKER_IDLE_TIMEOUT_SEC:-} | |
| + - BOT_MIXED_MIN_SUBMIT_MS=${BOT_MIXED_MIN_SUBMIT_MS:-} | |
| + - BOT_MIXED_SUBMIT_TICK_MS=${BOT_MIXED_SUBMIT_TICK_MS:-} | |
| - VEXA_AGENT_SRC_MOUNT=${VEXA_AGENT_SRC_MOUNT:-} | |
| - REDIS_URL=redis://redis:6379/0 | |
| # The Runtime brokers model credentials into spawned agents. Subscription credentials may be |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment