ADK feature flag and the agent/supervisor roles, and is served under /agent-console. The console persists across page refresh and is built from several pieces.
Surfaces
| Surface | Component | Role |
|---|---|---|
| Layout + heartbeat | Agent layout | shell, nav, heartbeat, call recovery |
| Status toggle | Agent status toggle | available/away/busy selector |
| Queue ticker + drawer | Queue ticker | scrolling waiting list |
| Queue card | Queue card | accept/decline/reject a call |
| Incoming modal | Incoming call modal | full-screen accept prompt |
| Waiting home | Agent queue page | idle “waiting for call” screen |
| Active call | Agent call page + call panel | live LiveKit call + wrap-up |
Status toggle
The status toggle reads/writes status viagetAgentStatus / setAgentStatus. Agents can select Available, Away, or Busy. The control locks (read-only) while in a non-selectable state — on_call, wrap_up, offline, or disconnected — and shows a colored dot per status. On a failed update it re-reads the server status and surfaces an error.
Heartbeat and call recovery
The agent layout callsheartbeatAgent every 15 seconds and updates the agent status from the response. On pagehide/unmount it marks the agent offline. When the status is active (on_call, wrap_up, disconnected) and the agent is not already on the call page, the layout recovers the current call via fetchCurrentCall and redirects to /agent-console/call, so a refresh or stray navigation cannot abandon a live call or skip a pending wrap-up.
Queue ticker, drawer, and incoming modal
The queue ticker pollsfetchQueue every 3 seconds. It shows a “N waiting” label and a scrolling ticker of callers. Clicking opens a drawer of queue cards. The oldest waiting call is treated as primary and — when the agent is available and not on the call page — pops the incoming call modal.
Per-call actions (shared by card and modal):
| Action | API | Effect |
|---|---|---|
| Accept | acceptCall | stores call in sessionStorage, navigates to /agent-console/call |
| Decline | declineCall | removes from this agent’s queue (may terminate if no agents left) |
| Reject | rejectCall | ends the call with a reason |
Active call and wrap-up
The agent call page restores call state fromlocation.state or sessionStorage (and recovers from fetchCurrentCall on refresh). It captures mic audio, mixes in remote tracks, and records the call locally. The call panel joins the LiveKit room, lists connected participants (filtering out service identities like hold-worker, core-bot, ai-copilot), and offers mute and end-call controls. When Agent Assist is enabled it shows the Agent Assist panel (live suggestions + transcript over LiveKit data messages).
Wrap-up is enforced: when the call ends (agent hangup or customer disconnect, detected via LiveKit callbacks with a 3-second state-poll fallback), a modal requires a Disposition (Resolved, Transferred, Escalated, No Resolution, Callback Scheduled) and Comments before submit. Finalize tears down via endCall, then best-effort uploads the recording via uploadRecording.
Related docs
Agent history & analytics
An agent’s handled calls and personal stats.
Supervisor dashboard
Listen, barge in, and force-end.
Agent Assist
Phrase-triggered suggestion moments.
Agent Desk (CXB API)
Queue, rooms, and supervisor controls server-side.