Call detailPro
One voice agent call, reviewed. The recording, who spoke when, and the transcript on one clock, with response latency on every agent turn, tool calls where they ran, and a summary of p50 and p90, interruptions and talk time.
On this page
ProA finished pharmacy refill call. Play it, seek from any timestamp or barge-in, and open any response's stages in the rail.
Installation
Usage
import { CallDetail } from "@/components/ui/chatcn/pro/call-detail"
<CallDetail
title="Rosa Delgado"
duration={call.durationMs}
outcome={{ label: "Refill placed", tone: "success" }}
turns={call.turns}
toolCalls={call.tools}
src={call.recordingUrl}
/>Times are milliseconds from the start of the call. Agent turns take latency, the ms per stage of the response that started them, and render the compact turn latency bar; click one to see its stages in the rail, which opens on the slowest response. With src the recording plays through an internal audio element; without it the player runs on a simulated clock, which is what the examples use. The line being played lights up and stays in view; scroll away and a Follow playback pill brings it back.
Examples
Loading, a dropped call, no speech and RTL
ProLoading, a dropped call with no recording and a call with no speech.
Props
| Prop | Type | Notes |
|---|---|---|
title, subtitle | ReactNode | Who called, and the line under it |
agentName, callerName | string | Names in the turn list. Default "Assistant" and "Caller" |
date | ReactNode | When the call happened, formatted |
duration | number | Call length in ms |
outcome | { label, tone: "success" | "error" | "warning" | "info" } | Status tint with a glyph |
cost | ReactNode | Formatted cost |
turns | CallTurn[] | { id, speaker, start, end?, text, interrupted?, unspoken?, latency?, latencyStatus?, failedAt? } |
toolCalls | CallToolCall[] | { id, name, args?, at, duration?, status: "running" | "success" | "error", result? } |
events | CallEvent[] | { id, at, text, tone?: "neutral" | "error" } |
peaks | number[] | Waveform peaks, 0 to 1. Generated from the turns when left out |
src | string | Recording URL |
recording, recordingMessage | "ready" | "loading" | "unavailable", ReactNode | Unavailable keeps the transcript and says how to fix it |
budget | number | false | Response budget in ms. Default 800 |
loading | boolean | Skeleton of the whole review |
defaultTime, onTimeChange | number, (ms) => void | Start position and the playhead |
Keyboard
| Key | Action |
|---|---|
Space, K | Play or pause, when focus is not on a control |
J, L | Back or forward 5 s |
ArrowLeft, ArrowRight | Back or forward 5 s outside the scrubber |
Tab | Timestamps, barge-in marks and latency bars are buttons in reading order |
Accessibility
- Timestamps are buttons named "0:35, play from 35 seconds, Refill line"; the playing line carries
aria-current. - The transcript is a focusable, labelled region, so it scrolls by keyboard; scrolling it releases following and never moves the page.
- The outcome uses a status tint plus a glyph and its label. Failed tool calls say what went wrong under the call.
- The summary is an
asidewith a definition list; the stage breakdown is a captioned table.
Motion
- Following scrolls the list smoothly to keep the playing line in view, and instantly under reduced motion. Keyboard seeks never animate.
- The playhead over the turn lanes moves with a transform. Row highlights change color in 150 ms.
- The Follow playback pill enters in 150 ms with opacity and scale.