feat: add Turn Success Rate metric across evals, realtime, leaderboard#68
Conversation
Turn Success Rate (TSR) is the quality/resilience axis that complements latency. Latency excludes no-response runs (a missing response has no latency); TSR *includes* them as failed turns — so a network-impairment failure shows up as a low success rate instead of vanishing. TSR is opportunity-weighted: every thing the agent was asked to do (respond / stop on interrupt / don't false-barge) is one scored opportunity, and TSR is the fraction it got right. No per-dimension priority — each turn counts once. Computed from the counters computePerCaseAndRates already accumulates; null when no evaluable turns. - daemon (chunking.ts): turn_success_rate in ComputedRates + formula; vox-agentd wires it into EvalResult / defaults / rate pickup. - schema + migration 0021: nullable turn_success_rate column (v22). - complete route stores it; storage tier select + daily-bucket avg; formatMetricsResults exposes it. - leaderboard: TSR column + sort + folded into the composite score. New weights (end-user experience; noise > naturalness since real-world background noise is constant): Response 25 / TSR 25 / Interrupt 15 / Noise 15 / Network 10 / Naturalness 10. - job detail: "Rates" card renamed "Turn Success Rate" — composite headline + Response/Interrupt/False-Barge-in breakdown. - realtime: Turn Success Rate summary card. api-v1 leaderboard exposes it. - tests: opportunity-weighted formula (0.9 fixture, no-response→0, empty→null); api complete-flow stores + asserts TSR. Note: network/noise are conceptually the core metrics measured under adverse conditions — a future Core-vs-Resilience restructure (separate condition-evals) is deferred; this keeps the flat 6-metric composite. 🤖 Built with SMT <smt@agora.build>
🤖 Claude Code ReviewI've reviewed the full diff across schema, migration, daemon, aggregation, API, and UI layers. ReviewOverall this is a clean, well-scoped addition. The new metric is threaded consistently through every layer (schema → migration → daemon parse → both merge paths → raw + bucketed storage selects → Things I verified and found correct:
Minor observations (not blockers):
No logic errors, edge-case gaps, or performance regressions found. Good to merge. |
🤖 Codex Code ReviewFindings
No security issues found in the reviewed diff. |
… data card Realtime dashboard polish for Turn Success Rate: - Turn Success Rate is its own summary card and a full-width time-series chart (%) alongside Response/Interrupt Latency (tooltip is now unit-aware so TSR reads "%" not "ms"). - Show the latest-eval provider name on Response Latency / Interrupt Latency / Turn Success Rate cards (each reflects the latest data point). - Merge "Data Points" + "Region Filter" into one card (count · region · time range) and surface the latest eval's provider there too. 🤖 Built with SMT <smt@agora.build>
…etric card The three summary cards read from the same latest data point, so the provider name was identical on all of them. Keep it only on the merged "Latest: <provider>" card; restore the TSR card's descriptor caption. 🤖 Built with SMT <smt@agora.build>
🤖 Codex Code ReviewFindings
I didn’t run tests; review only. |
🤖 Claude Code ReviewReviewed the full diff on the merge ref ( ReviewThis is a clean, well-tested feature addition. The new Correctness — verified sound:
Minor points (non-blocking):
Nothing here blocks merge. |
Custom is the catch-all provider for user-defined platforms and is never a Mainline entrant, so it shouldn't appear in the Mainline tab's provider filter. Community and My Evals still list it (those tiers include custom-platform evals). Also make the filter's visible-count robust to a hidden-set that carries provider ids absent from the current tab. 🤖 Built with SMT <smt@agora.build>
🤖 Codex Code ReviewFindings
Notes
|
🤖 Codex Code ReviewFindings
Notes
|
🤖 Claude Code ReviewI've reviewed the full diff (including SummaryClean, well-scoped, and consistently plumbed change. The new Findings1. 2. Leaderboard composite: transition-period penalty on a 25%-weighted axis (by design, but heavy) 3. Realtime headline TSR reflects only the single latest data point (minor UX) Nothing here is blocking. The metric definition is coherent, the null-vs-zero distinction is handled carefully throughout ("no data" never reads as "0% success"), weights still sum to 1.0, and the migration is properly registered in |
🤖 Claude Code ReviewThe changes look solid and well-engineered. I reviewed the full diff (schema/migration, daemon TSR computation in ReviewCorrectness — verified sound
Behavior change worth calling out (not a bug)
Minor nits (optional)
Everything else (the |
Context
Continues the no-response = NA latency work. Latency correctly excludes no-response runs (a missing response has no latency), but that meant network-impairment failures — where the agent legitimately doesn't respond — could vanish from realtime/leaderboard. Turn Success Rate (TSR) is the quality/resilience axis that captures them: it includes no-response turns as failures, so "responds 0% under impairment" shows up as a low score instead of disappearing.
What TSR measures
A turn succeeds when the agent does the right thing: responds when expected, stops promptly on interrupt, and doesn't false-barge-in. TSR is opportunity-weighted — every such expectation is one scored opportunity, and TSR is the fraction the agent got right:
Each turn counts once (no arbitrary per-dimension priority), and it's computed from the counters
computePerCaseAndRatesalready accumulates.NULLwhen there are no evaluable turns; behavioral success only (semantic "appropriateness" of the response content isn't judged by the pipeline).Changes
chunking.ts):turn_success_rateinComputedRates+ the formula;vox-agentdwires it intoEvalResult/ defaults / rate pickup.0021: nullableturn_success_ratecolumn (registered v22).formatMetricsResultsexposes it; api-v1 leaderboard exposes it.NAlatency but0%TSR — visible and correctly penalized rather than hidden.Roadmap note (not in this PR)
Network Resilience and Noise Reduction are conceptually the same core metrics measured under adverse conditions — a future Core Experience vs. Resilience restructure (impairment/condition profiles on eval-sets, condition-tagged results, baseline-vs-impaired scoring, run as separate evals) is deferred. This PR keeps the flat 6-metric composite; network/noise remain daemon placeholders today.
Verification
npm run checkclean; 161 unit tests pass (incl. new TSR formula cases).turn_success_rate.Generated with SMT smt@agora.io