Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
b9e159b
Remove SDK keepalive from DeepgramClientOptions (#5870)
beastoin Mar 21, 2026
39c4b21
Add _dg_dead flag to GatedDeepgramSocket (#5870)
beastoin Mar 21, 2026
44367cf
Detect dead DG connection in flush_stt_buffer (#5870)
beastoin Mar 21, 2026
877ce8a
Add tests for DG dead connection detection (#5870)
beastoin Mar 21, 2026
6fbe03d
Fix nonlocal scoping for dg_socket in flush_stt_buffer (#5870)
beastoin Mar 21, 2026
695b2e5
Add flush_stt_buffer dead-socket integration test (#5870)
beastoin Mar 21, 2026
4acf48f
Add keepalive option guard test to prevent SDK regression (#5870)
beastoin Mar 21, 2026
a8e9c62
Extract SafeDeepgramSocket from GatedDeepgramSocket for universal dea…
beastoin Mar 21, 2026
1c66f8f
Wrap DG connection with SafeDeepgramSocket in process_audio_dg (#5870)
beastoin Mar 21, 2026
85a6e60
Remove hasattr guard — is_connection_dead now always available (#5870)
beastoin Mar 21, 2026
fd47a00
Update tests for SafeDeepgramSocket + GatedDeepgramSocket layering (#…
beastoin Mar 21, 2026
3996c74
Fix streaming test module mock to not clobber vad_gate (#5870)
beastoin Mar 21, 2026
c3d6b77
Move SafeDeepgramSocket from vad_gate.py to streaming.py (#5870)
beastoin Mar 21, 2026
a871dd8
Remove SafeDeepgramSocket from vad_gate.py, use marker check (#5870)
beastoin Mar 21, 2026
4665cd6
Update test import: SafeDeepgramSocket now in streaming module (#5870)
beastoin Mar 21, 2026
816511d
Add keep_alive() to GatedDeepgramSocket for speech profile idle windo…
beastoin Mar 22, 2026
f0748a1
Send keepalive to main DG socket during speech profile stabilization …
beastoin Mar 22, 2026
39ddd50
Extract SafeDeepgramSocket to lightweight safe_socket.py module (#5870)
beastoin Mar 22, 2026
73715e5
Import SafeDeepgramSocket from safe_socket.py, re-export for compat (…
beastoin Mar 22, 2026
c572bf2
Update test import: SafeDeepgramSocket from safe_socket module (#5870)
beastoin Mar 22, 2026
0e1f359
Add GatedDeepgramSocket.keep_alive() and finalize/finish delegation t…
beastoin Mar 22, 2026
27f48dc
Add process_audio_dg wrapping and stabilization keepalive tests (#5870)
beastoin Mar 22, 2026
65d0bde
Refactor SafeDeepgramSocket to own auto-keepalive via background thre…
beastoin Mar 23, 2026
f73ad59
Remove keepalive logic from GatedDeepgramSocket — owned by SafeDeepgr…
beastoin Mar 23, 2026
16a6e75
Simplify speech profile stabilization — auto-keepalive handles idle (…
beastoin Mar 23, 2026
22a0cd5
Re-export KeepaliveConfig from streaming module (#5870)
beastoin Mar 23, 2026
1313be4
Update tests for auto-keepalive architecture — remove gate keepalive …
beastoin Mar 23, 2026
cbaace9
Replace stabilization keepalive tests with auto-keepalive tests (#5870)
beastoin Mar 23, 2026
3ddef83
Make finish() idempotent — guard against double-close (#5870)
beastoin Mar 23, 2026
e57e8b4
Add finish idempotency + keepalive exception tests (#5870)
beastoin Mar 23, 2026
ce5f801
Increase auto-keepalive test sleep margins for CI stability (#5870)
beastoin Mar 23, 2026
3f26f0c
Fix dead-socket check dropping profile audio during speech phase (#5870)
beastoin Mar 23, 2026
95b84e2
Increase auto-keepalive test sleep margins in test_vad_gate.py (#5870)
beastoin Mar 23, 2026
26d180d
Add coverage for thread safety, boundaries, and profile routing (#5870)
beastoin Mar 23, 2026
eb5f851
Strengthen concurrency test: assert keepalive fires during contention…
beastoin Mar 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion backend/routers/transcribe.py
Original file line number Diff line number Diff line change
Expand Up @@ -1139,6 +1139,8 @@ async def deepgram_socket_send(data):
)

# Stabilization delay before switching to main socket
# SafeDeepgramSocket's auto-keepalive thread keeps the main DG socket
# alive during this idle window — no manual keepalive needed (#5870)
if is_active():
logger.info(
f"Speech profile sent, waiting {SPEECH_PROFILE_STABILIZE_DELAY}s for stabilization {uid} {session_id}"
Expand Down Expand Up @@ -2290,7 +2292,7 @@ async def receive_data(dg_socket, dg_profile_socket, soniox_sock, soniox_profile
stt_buffer_flush_size = int(sample_rate * 2 * 0.03) # 30ms at 16-bit mono (e.g., 6400 bytes at 16kHz)

async def flush_stt_buffer(force: bool = False):
nonlocal stt_audio_buffer, soniox_profile_socket, deepgram_profile_socket, dg_usage_ms_pending
nonlocal stt_audio_buffer, soniox_profile_socket, deepgram_profile_socket, dg_usage_ms_pending, dg_socket

if not stt_audio_buffer:
return
Expand All @@ -2303,6 +2305,12 @@ async def flush_stt_buffer(force: bool = False):
# Use event-based routing instead of time-based
profile_complete = speech_profile_complete.is_set()

# Check if DG connection died (keepalive or send failure) (#5870)
# Separated from routing so profile socket still receives audio if main dies.
if dg_socket is not None and dg_socket.is_connection_dead:
logger.error('DG connection died mid-session uid=%s session=%s', uid, session_id)
dg_socket = None # Stop sending to dead connection

if dg_socket is not None:
if profile_complete or not deepgram_profile_socket:
# DG budget gate: skip sending if restricted user's daily budget is exhausted (#5746)
Expand Down Expand Up @@ -2336,6 +2344,9 @@ async def close_dg_profile():
spawn(close_dg_profile())
else:
deepgram_profile_socket.send(chunk)
elif deepgram_profile_socket and not profile_complete:
# Main socket dead but profile socket still alive — keep routing (#5870)
deepgram_profile_socket.send(chunk)

if soniox_sock is not None and not fair_use_dg_budget_exhausted:
if profile_complete or not soniox_profile_socket:
Expand Down
Loading
Loading