Per-turn latency, LLM credit, and call-cost columns are populated by the analysis pipeline that runs at the end of a call. Conversations still in progress, and conversations recorded before analysis was enabled for the agent, show an em-dash for those fields.
Overview
A conversation is created the moment an agent dispatch starts. It carries:- the agent that handled the call,
- the branch the call was served from (resolved through the conversation’s
agent_version_id— every conversation pins the immutable version that ran), - a transcript built up as turns arrive from the agent runtime,
- per-agent-turn retrieval sources — the knowledge-base chunks the LLM was given as context for that reply,
- an LLM-generated summary and call status when the post-call analysis pipeline finishes.
404 with no enumeration difference between “wrong org” and “doesn’t exist.”
Anatomy of a conversation
The history surface breaks down into four pieces, built on the same@zeptar/ui primitives — Table, Badge, Dropdown — used elsewhere in the dashboard.
List
The list page (/agents/conversations) renders one row per conversation, newest first. The default columns are:
Additional columns — Conversation ID, Language, Direction, Source, Version, Tools — are available from the Customize-table panel but off by default.
Detail
Opening a row routes to/agents/conversations/[conversationId]. The detail layout is two columns:
- Main column — header (title, branch badge, copy-id button, prev/next chevrons, Add-tag button), audio bar, and three tabs: Overview, Transcription, Client data.
- Right sidebar — metadata: date, text-only flag, environment, connection duration, call cost, LLM credits, LLM cost. Collapsible.
Transcription
The Transcription tab is the screen most teams spend the most time on. Each turn renders as a bubble with:- the turn timestamp relative to the start of the call,
- the role (agent on the left, user on the right),
- the text the participant said,
- a row of metric pills —
ASRon user turns,LLM/TTS/RAGon agent turns. Any pill that doesn’t apply to a role is hidden rather than dashed. - a sources pill on every agent turn that used retrieval —
1 source,3 sources, etc. Click to expand.
Client data
The Client-data tab surfaces what the SDK sent alongside the dispatch — current environment, language overrides, and any other per-call overrides the client passed onPOST /v1/agents/{agentId}/conversations. Useful when you’re chasing “the agent behaved differently for this user” — it’s almost always an override.
Filtering and customizing the table
The filter rail sits directly under the page title. Add filters with the trailing Add filter button; each chip you add is dismissible. The MVP filter set covers:- Agent — narrow to one agent across all branches.
- Branch — narrow to one branch on one agent.
- Date range — inclusive start/end (ISO strings on the wire).
- Status —
successful/failed/unknown. - Duration — min and max, in whole seconds.
- Direction —
inbound(user dialled) vsoutbound(agent dialled out). Not all transports populate this. - Language — IETF tag (
en,de, …).
?branch_id=…&status=…) so a filtered view is shareable as a link. The list endpoint accepts the same names as query params — see the API overview.
Customize table (the trailing button on the filter rail) opens a popover that lets you reorder columns, toggle non-default columns on, switch the Date format between relative and absolute, and hide ongoing & processing calls. Choices persist in the browser per user.
Per-turn retrieval
The clearest signal that the knowledge base is doing useful work is the per-turn Sources affordance. Every agent turn that triggered retrieval carries a sources pill. Clicking it expands an inline panel under the bubble (not a modal) titled Sources — Used RAG chunks, with one row per chunk:- Document title — the source document the chunk came from.
- Chunk number — the chunk’s position in the document.
- Similarity — the embedding cosine score we observed at retrieval time. We snapshot this on the conversation row so the displayed ranking matches what the agent saw, even if the chunk is later re-embedded.
- Show — opens a centred Document Chunk Preview modal with the full chunk body and an Open link that routes to the source document in the knowledge base.
Tags
Tags are user-supplied free-form labels attached to a single conversation. They’re the canonical way to flag calls for follow-up —flaky, bug, escalate, demo, whatever vocabulary your team agrees on.
- Add a tag from the conversation header. The first tag opens an inline input; subsequent tags append to the row.
- Tags are per conversation, not per branch or per agent. A tag’s label is unique inside one conversation but the same label can be re-used across conversations.
- Tags are organization-scoped. A label used in organization A is not visible to organization B.
- Removing a tag is
DELETE /v1/conversations/{id}/tags/{tagId}— deletes the row, doesn’t soft-delete.
Limits & costs
Two cost surfaces show up on the detail page’s right sidebar. LLM credits — the dollar-equivalent we bill for the LLM tokens consumed in the call (input + output + cached, summed across every turn). The Overview tab also shows the same number broken down by$/min so you can compare against your model’s published rate.
Call cost — the total credit charge for the call. This rolls up:
- LLM credits (above),
- ASR (speech recognition) credits,
- TTS (speech synthesis) credits,
- agent runtime time (the minutes a LiveKit worker held the room).
— is either in-flight, analysis-pending, or pre-dates the metric being tracked on this agent.
Audio
The audio waveform and player controls render whenever a recording is available for the call. Whether a recording exists for any given call depends on:- Your plan — recording is opt-in on lower tiers.
- Your organization’s recording policy — admins can disable recording for compliance reasons, in which case the agent runtime never persists the audio in the first place.
- Your per-call client overrides — an SDK caller can suppress recording for a single call.
What’s next
- Evaluation criteria — server-side eval that drives the
successful/failedverdict instead of treating it as a free-form analysis output. Lands after the criteria-editor spec. - Conversation-level dynamic variables — surfacing per-call variables the SDK passed on
dispatch_envelope_v1directly in the Client-data tab. - Tools — calling-out per-turn tool invocations as their own affordance alongside RAG sources.
- Tag dictionary — opt-in controlled vocabulary, so misspelled tags don’t fragment your filter set.