Skip to main content

Agent shrinkage and state history

Shrinkage is the gap between what you pay an agent for and the time they are actually productive. The agent detail page measures it from a per-agent event stream: every state flip — available, busy, wrapup, away, offline — appends one row, and the dashboard aggregates those rows into per-state durations you read as “productive vs not productive” time. This page defines shrinkage, the event schema behind it, the productive vs non-productive buckets, and the supervisor workflow on Voice → Agents → [agent]. The state machine itself — the five states and who moves each edge — is defined in Agent presence and aux-code lifecycle. This page covers the measurement surface on top of it.

1. What shrinkage measures

Shrinkage is measured productive time against paid time. In contact-centre terms it is usually expressed as a percentage:
The non-productive numerator is the time an agent spends in paused (on break, training, lunch) plus offline (logged out) during their shift. The productive denominator groups available, busy, and wrapup — the agent is either waiting for a call, on a call, or doing post-call work; all three are on-the-clock and counted as productive. Because every transition writes an append-only row with an exact timestamp, shrinkage is a deterministic aggregate, not an estimate. A supervisor can answer “how much of Tuesday was this agent actually productive” from one per-day read.

2. The event stream

Every accepted state change writes one row to the per-agent history. The row carries the prior state, the new state, an optional reason, and an exact timestamp: The read endpoint is GET /api/v1/voice/agents/:id/state-history, with optional from, to (both ISO datetimes), and limit (default 500, max 5000) query parameters. When omitted, from defaults to 24 hours ago and to defaults to now. Rows come back newest-first, ordered by changed_at descending:
Access is self-or-supervisor: an agent reads their own stream; reading another agent’s stream requires an owner, admin, or supervisor role, because break-compliance rows are sensitive.

3. Bucketing productive against non-productive time

The dashboard groups the five states into two buckets and credits each row’s elapsed time to its to_state: The duration aggregate walks the chronological sequence and credits the time between consecutive transitions to the state the agent was in. The most recent transition accrues live time up to the end of the queried window, so an agent currently in available keeps accruing productive time while you watch. On the detail page the aggregate is rendered as five per-state KPI tiles formatted as Xh Ym; the same helper the page uses is exported for reuse.

4. Supervisor workflow

Open Voice → Wallboard and click an agent tile, or navigate directly to Voice → Agents → [agent id]. The page is gated to supervisor-class roles (owner, admin); an agent always has access to their own detail view. Steps:
  1. Pick a single day with the date selector. The page defaults to today; the read is a single-day window (the event-stream endpoint caps the row limit, so multi-day exports are a separate surface, not the wallboard view).
  2. Read the five KPI tiles — per-state durations in Xh Ym. A state with no credited time shows — so you can distinguish “absent” from “trace”.
  3. Scan the transitions table — newest first — with a per-row duration. The current (most recent) row has no duration because the agent is still in that state.
  4. Read bucket badges: the available tile is the productive anchor; away and offline are the shrinkage contributors. A long away tile with a reason like lunch or training tells you whether the shrinkage is scheduled or a leak.
Badge colouring is deliberately quiet — available is highlighted so a supervisor’s eye lands on currently-productive, while busy/wrapup/away/offline use neutral greys to avoid colour-noise on a wallboard that many people share.

5. Reading the numbers against quality and scheduling

Shrinkage tells you how time was spent; it does not tell you whether the productive time was good. Pair the timeline with two sibling surfaces:
  • Voice Agent Quality (/voice/vaqi) — the per-call quality index (latency, turn-taking, barge-in) for AI voice agents, so “productive time” also has a quality read.
  • WFM model (/concepts/wfm-model) — the schedule-adherence model. Shrinkage feeds the adherence numerator: an agent whose away/offline time spikes during a scheduled shift shows up both here and as an adherence miss.