fix(dashboard,pipeline): hydrate cost/latency + barge-in gate from first audio#86
Closed
nicolotognoni wants to merge 1 commit into
Closed
fix(dashboard,pipeline): hydrate cost/latency + barge-in gate from first audio#86nicolotognoni wants to merge 1 commit into
nicolotognoni wants to merge 1 commit into
Conversation
…in gate from first audio Two bugs caught during 0.6.0 acceptance against `releases/0.6.0/typescript/matrix/outbound-cartesia-cerebras-elevenlabs.ts`: 1. **Dashboard hydrate schema mismatch**: `CallLogger.log_call_end` writes `cost`/`latency`/`duration_ms`/`telephony_provider` as top-level keys of `metadata.json`, but `MetricsStore.hydrate` looked for them under `meta.metrics.cost`/`meta.metrics.latency`. Every hydrated row landed with `metrics=null`, so cost/latency rendered as `$0.00`/`—` for all on-disk calls (only the in-flight call had real numbers). Fix synthesizes a `metrics` dict from the top-level fields when `meta.metrics` is absent while preserving any explicit `meta.metrics` payload untouched. 2. **Early barge-in self-cancellation**: cloud TTS first-byte latency is 200–700 ms; the 250 ms anti-flicker gate (no-AEC PSTN default) was anchored on `_speaking_started_at`/`speakingStartedAt` and expired BEFORE TTS produced audio. VAD then picked up background noise and self-cancelled the agent's first turn — 0 bytes emitted, line silent. Fix anchors the gate on a new `_first_audio_sent_at`/`firstAudioSentAt` set AFTER `bridge.sendAudio` / `audio_sender.send_audio` succeeds at the four pipeline emit sites (firstMessage, streaming, regular, WebSocket remote). `_can_barge_in`/`canBargeIn` returns false while the marker is null. Gate values (250 ms / 1000 ms) unchanged — only the anchor moves. Tests: - Py 1717/1717, TS 1394/1394 green; lint clean. - New regressions: `test_hydrate_lifts_top_level_cost_and_latency_into_metrics`, `test_hydrate_preserves_explicit_metrics_when_present`, `test_barge_in_suppressed_before_first_audio_emitted` (Py) + parity TS cases in `tests/dashboard-store.test.ts` and `tests/unit/stream-handler.test.ts`. - Existing `_handle_barge_in`/`handleBargeIn` tests updated to set both timestamps for the new contract.
Collaborator
Author
|
Superseded by #85 (0.6.1 release bundle). All commits from this branch ( |
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two regression-class bugs surfaced during 0.6.0 acceptance against
releases/0.6.0/typescript/matrix/outbound-cartesia-cerebras-elevenlabs.ts:cost/latency/caller/calleefor every call rebuilt from disk → all hydrated rows showed\$0.00and—.Fixes are minimal, parity-aligned (Py + TS), and fully backward-compatible.
Implementation
1.
MetricsStore.hydrateschema mismatchCallLogger.log_call_endwritescost/latency/duration_ms/telephony_provideras top-level keys ofmetadata.json. The reader looked undermeta.metrics.cost/meta.metrics.latency. New helpermetricsFromTopLevel/_metrics_from_top_levelsynthesizes ametricsdict from those top-level fields whenmeta.metricsis missing, mappinglatency.p95_ms→metrics.latency_avg.total_msso the existing UI fields populate. Explicitmeta.metrics(legacy/future shape) is preserved untouched.2. Pipeline barge-in gate anchored on actual audio emission
Cloud TTS first-byte latency is 200-700 ms; the 250 ms PSTN gate measured from
_begin_speaking/beginSpeakingexpired BEFORE TTS produced audio. New_first_audio_sent_at/firstAudioSentAtis set in_mark_first_audio_sent/markFirstAudioSentinvoked AFTERbridge.sendAudio/audio_sender.send_audiosucceeds at the four pipeline emit sites (firstMessage, streaming response, regular response, WebSocket remote)._can_barge_in/canBargeInnow returns false while the marker is null. Gate values (250 ms / 1000 ms) unchanged — only the anchor moves.Files:
libraries/python/getpatter/dashboard/store.pylibraries/python/getpatter/stream_handler.pylibraries/typescript/src/dashboard/store.tslibraries/typescript/src/stream-handler.tsBreaking change?
No — defaults preserved, all existing fields/methods unchanged. The barge-in fix is a behavioural improvement (was already documented as a "anti-flicker only" gate; the anchor change makes that contract actually hold).
Test plan
pytest tests/→ 1717 passed, 7 skippednpm test→ 1394 passed,npm run lintclean, build cleantest_hydrate_lifts_top_level_cost_and_latency_into_metrics(Py)test_hydrate_preserves_explicit_metrics_when_present(Py)test_barge_in_suppressed_before_first_audio_emitted(Py)MetricsStore.hydrate > lifts top-level cost/latency/duration into metrics(TS)MetricsStore.hydrate > preserves explicit metrics when present(TS)barge-in gate > canBargeIn() false before the first TTS chunk has hit the wire(TS)_handle_barge_in/handleBargeIntests updated to set both timestamps for the new contract.Docs updates
N/A — bug fix in internal behaviour. CHANGELOG
## Unreleasedupdated with both entries.