-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy path2026-07-21-accept-realtime-spark.txt
More file actions
105 lines (93 loc) · 5.94 KB
/
Copy path2026-07-21-accept-realtime-spark.txt
File metadata and controls
105 lines (93 loc) · 5.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
=== lobes /v1/realtime acceptance — DGX Spark GB10 (spark), 2026-07-21T13:50:27Z ===
branch: spec/realtime-ws-server-vad-149 commit: 5f43892
rig: parallel gateway (port 8099) + realtime bridge from branch source, on the lobes_default
network, wired to the LIVE model-gear-stt (Parakeet) and model-gear-chatterbox containers.
The production fleet was left untouched throughout.
--- baseline probe (production gateway :8001, lobes-cli 0.51.1) ---
realtime container REST paths: ['/health', '/v1/audio/speech', '/v1/audio/transcriptions', '/v1/health/ready']
-> no /v1/realtime: reproduces the issue #149 baseline.
--- refusal paths (branch gateway :8099) ---
handshake without bearer -> 401 (expect 401)
plain GET with bearer -> 426 (expect 426)
--- capabilities: stt role ---
responsibilities: ['transcribe', 'audio_input_to_text', 'realtime_vad_session']
ready: True feasible: True
--- session at 24000 Hz (default) through the gateway tunnel ---
PASS: tts-source — 115200 bytes PCM16 @ 24000 Hz
PASS: ws-handshake — 101 Switching Protocols, Sec-WebSocket-Accept verified
PASS: session-created — received 'session.created'
PASS: audio-stream — streamed 172800 bytes + trailing silence
PASS: speech-started — received 'input_audio_buffer.speech_started'
PASS: speech-stopped — received 'input_audio_buffer.speech_stopped'
PASS: transcription — transcript='The quick brown fox jumps over the lazy dog.' contains every expected keyword ('quick', 'brown', 'fox', 'lazy', 'dog')
Results: 7/7 checks passed
SUCCESS: all realtime checks passed
--- session at 16000 Hz (reachy-mini-cli's native mic rate) ---
PASS: tts-source — 115200 bytes PCM16 @ 24000 Hz
PASS: ws-handshake — 101 Switching Protocols, Sec-WebSocket-Accept verified
PASS: session-created — received 'session.created'
PASS: audio-stream — streamed 153600 bytes + trailing silence
PASS: speech-started — received 'input_audio_buffer.speech_started'
PASS: speech-stopped — received 'input_audio_buffer.speech_stopped'
PASS: transcription — transcript='The quick brown fox jumps over the lazy dog.' contains every expected keyword ('quick', 'brown', 'fox', 'lazy', 'dog')
Results: 7/7 checks passed
SUCCESS: all realtime checks passed
--- the #149 motivating case: the five-word question that the client-side
energy threshold shattered into 'Ready, she' (16 kHz, reachy's mic rate) ---
PASS: tts-source — 59520 bytes PCM16 @ 24000 Hz
PASS: ws-handshake — 101 Switching Protocols, Sec-WebSocket-Accept verified
PASS: session-created — received 'session.created'
PASS: audio-stream — streamed 97920 bytes + trailing silence
PASS: speech-started — received 'input_audio_buffer.speech_started'
PASS: speech-stopped — received 'input_audio_buffer.speech_stopped'
FAIL: transcription — transcript='Ricci, are you there?' missing keywords=['reachy']
Results: 6/7 checks passed
FAILURE: some checks failed
READ THIS RESULT CAREFULLY. The endpointing — the thing #149 is about —
WORKED: the five-word question arrived as ONE whole utterance,
"Ricci, are you there?", with a single speech_started/speech_stopped pair.
Compare the #149 baseline, where a client-side energy threshold shattered
the same question into the fragment "Ready, she". The residual error is
Parakeet mishearing the proper noun "Reachy" as "Ricci" — an ASR
vocabulary miss on a name, in audio that was SYNTHESIZED by Chatterbox and
never passed through a real microphone. That is a different problem from
the one this PR fixes, and the smoke script was right to fail the keyword
check rather than paper over it.
=== WHAT THIS TRANSCRIPT DOES AND DOES NOT ESTABLISH ===
VALIDATED on this run (real GB10, real Silero, real Parakeet, real Chatterbox):
- the gateway's 101-upgrade + byte tunnel, including Sec-WebSocket-Accept
relayed verbatim and the first event packed into the 101's TCP segment;
- session lifecycle events over ONE connection: session.created ->
speech_started -> speech_stopped -> transcription;
- server_vad segmentation by the real Silero model on real audio;
- both wire rates: 24000 Hz (default) and 16000 Hz (native passthrough);
- the inbound bearer gate on the handshake (401) and the 426 on a plain GET;
- the stt role advertising realtime_vad_session with ready=true.
NOT established here (do not claim these):
- a real microphone: every run above used synthesized Chatterbox audio;
reachy-mini-cli's live mic path is still unproven end to end;
- the VAD-unavailable error path (no way to fail Silero on a healthy box);
- concurrent sessions, the max-turn force-commit, and teardown mid-
transcription — all covered offline, none exercised live here;
- the production fleet itself, which still runs 0.51.1 and was deliberately
left untouched; this rig was a parallel gateway+bridge on spare ports.
=== RE-VALIDATION after the Qodo/Sonar review round, 2026-07-21T14:00:48Z ===
commit: 1e57b52 (+ uncommitted review fixes)
Changes re-tested here: caller Authorization/Cookie stripped from the forwarded
handshake; full-shutdown on pump exit so a dead bridge cannot strand a handler
thread; VAD_MAX_TURN_MS clamped; and the /v1/realtime route refactored into
helpers for Sonar S3776 — the route has no unit coverage by design, so this live
run IS the gate on that refactor.
--- 24000 Hz ---
PASS: tts-source — 136320 bytes PCM16 @ 24000 Hz
PASS: ws-handshake — 101 Switching Protocols, Sec-WebSocket-Accept verified
PASS: session-created — received 'session.created'
PASS: audio-stream — streamed 193920 bytes + trailing silence
PASS: speech-started — received 'input_audio_buffer.speech_started'
PASS: speech-stopped — received 'input_audio_buffer.speech_stopped'
PASS: transcription — transcript='The quick brown fox jumps over the lazy dog.' contains every expected keyword ('quick', 'brown', 'fox', 'lazy', 'dog')
Results: 7/7 checks passed
SUCCESS: all realtime checks passed
--- 16000 Hz ---
Results: 7/7 checks passed
SUCCESS: all realtime checks passed