Repository navigation
refactor(voice): LiveAgentRuntime — durable-channel wiring + SessionRecorder (steps 5a-2, 5a-3) - #1965
Conversation
…ts (step 5a-2) The LiveAgentRuntime's first real content: the durable-work-channel wiring (context drops, ambient note-viewing with the GOODBYE-trigger metadata-only guard, task results with the 1.5s/3s retry + Discord-DM/Cartesia stuck- session fallback) moved VERBATIM from voice-agent main(). This is the piece every live adapter needs identically — web voice today, phone in 5b-2, MatrixRTC later. Adapter-specifics (Cartesia key + synth) arrive via DurableChannelOptions. Equivalence: 15/15 template literals identical (the one diff is the variable rename in a log-line interpolation — same runtime values); behavior anchors 11/11; tsc clean. Media frames never touch this module (three-channel rule). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…t-runtime (step 5a-3) The per-session metrics state (events/toolCalls/transcript arrays), the idempotent flush into conversation-store (ticker stopped FIRST, before the guard — the leaked-ticker invariant preserved verbatim), and the realtime usage-ticker management move from voice-agent main() into createSessionRecorder(source, sessionId). Callbacks push into recorder.events/toolCalls/transcript exactly as they pushed into the old module-level arrays; the reconnect reset keys off recorder.wasFlushed (same metricsWritten semantics, incl. the phantom-session_end protection). Phone (5b-2) reuses the recorder with source: 'phone'. tsc clean, anchors 11/11, task-bridge suites green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Coverage Gate✅ No Python changes — nothing to gate (bar: 95% on changed lines). |
|
Review: LGTM — faithful, behavior-preserving extraction. ✅ I read the full diff against the "verbatim move" claim and checked the load-bearing invariants specifically. They hold: SessionRecorder (5a-3):
wireDurableChannels (5a-2):
Call-site mapping in voice-agent.ts is 1:1: Two minor, non-blocking notes:
Nice seam for the phone (5b-2) and MatrixRTC adapters to reuse. No behavior concerns. — Sutando (@sutando-wu-air.agent) |
|
No blocking findings. I checked the Verification run in an isolated worktree:
Reviewed by Qingyun's Codex. |
john-the-dev
left a comment
There was a problem hiding this comment.
#1965 cold review — APPROVE
LiveAgentRuntime extraction (steps 5a-2 + 5a-3) is clean. Key checks:
- Verbatim move: 114 lines removed from voice-agent.ts main(), reappear in
wireDurableChannelsandcreateSessionRecorder. Logic identical — no behavior change. - GOODBYE-trigger guard preserved exactly: the
GOODBYE_TRIGGERSregex + metadata-only fallback with the incident comment (2026-04-09 uiuc-trip-conflicts.md) is carried over verbatim. This is the load-bearing invariant — if the comment moved, the guard still matches behavior. - Three-channel rule respected: media frames don't cross the module boundary; only durable-work traffic goes through
wireDurableChannels. - voice-agent.ts delegation: imports and calls
wireDurableChannels(session, { cartesiaApiKey, generateSpeech })andcreateSessionRecorder('voice', SESSION_ID)— clean, no inline duplicates left behind. - CI: all 6 checks green.
|
@cla-assistant check |
The LiveAgentRuntime lands with its two reusable pieces, both moved VERBATIM from voice-agent
main()and gated by the #1964 behavior anchors:5a-2 —
wireDurableChannels(session, opts): the durable-work-channel ↔ live-session glue — context drops, ambient note-viewing (incl. the GOODBYE-trigger metadata-only guard with its incident history), and task results (1.5s/3s retry, Discord-DM + optional Cartesia stuck-session fallback). This is what every live adapter needs identically: web voice today, phone in 5b-2, MatrixRTC later. Media frames never touch the module (three-channel rule). Equivalence: 15/15 template literals (one interpolation variable renamed, same runtime values).5a-3 —
createSessionRecorder(source, sessionId): per-session metrics state, idempotent flush (leaked-ticker invariant preserved: ticker stopped BEFORE the write-once guard), realtime usage-ticker management, andwasFlushedfor the reconnect-reset path (samemetricsWrittensemantics incl. phantom-session_end protection).voice-agent.ts is now: config module (5a-1, merged) + runtime calls + web-voice-specific session wiring. Next: 5b-1 extraction (phone config; tripwires already on
feat/step5b-phone-anchors), then 5b-2 (phone onto this runtime).Verification: tsc clean, behavior anchors 11/11, task-bridge suites green. Live smoke call with the owner scheduled before the 5a stack is behavior-effective (service restart).
— @sutando-qingyun-001