Canvas Design System
Main Site Tokens

Agent Status

What the AI is doing right now, while the person waits: a single thinking line, or the stages of a longer run, each done, failed, in progress or still to come.

When to Use

Use when: The AI is working and the person is waiting on it. Thinking mode is for a short wait with nothing to report, such as a chat reply being written. Stages mode is for a run with three or more steps worth naming, such as generating an agenda or synthesizing a workshop: a long wait shows how far it has got, and a failure says which step broke and what to do about it.
Don't use when: The wait is not the AI working. A list fetching from the server is a Skeleton; an upload with a known percentage is Progress. The record of what a finished run did, with its details, is Agent Steps.

Variants

Stages

An ordered list of the run's stages. Each is done, failed, now or todo, with an optional detail line. A failed stage takes a recovery sentence and one action, so the person always knows what to do next.

Building your agenda

  1. Done: Read the brief

    12 product leaders, 2 hours, one decision to make.

  2. Failed: Transcribe the kickoff recording

    The file stopped at 12 minutes. Upload it again, or carry on without it.

  3. In progress: Choose activities from the library

  4. Not started: Check the timings and the breaks

<?= ws_agent_status([
    'id'     => 'generator-status',
    'label'  => 'Building your agenda',
    'stages' => [
        ['key' => 'brief', 'label' => 'Read the brief', 'state' => 'done', 'detail' => '12 product leaders, 2 hours.'],
        ['key' => 'recording', 'label' => 'Transcribe the kickoff recording', 'state' => 'failed',
         'recovery' => 'The file stopped at 12 minutes. Upload it again, or carry on without it.',
         'action' => ['label' => 'Try again']],
        ['key' => 'pick', 'label' => 'Choose activities from the library', 'state' => 'now'],
        ['key' => 'check', 'label' => 'Check the timings and the breaks', 'state' => 'todo'],
    ],
]) ?>

Thinking

One line: the AI mark, a sentence, three dots. The sentence says what it is doing when you know ("Reading your notes"); "Working on it" is the default. A quieter detail can follow.

Working on it
Reading your notes 14 notes and 2 recordings
<?= ws_agent_status() ?>
<?= ws_agent_status(['label' => 'Reading your notes', 'detail' => '14 notes and 2 recordings']) ?>

From JavaScript

Most AI waits start in the browser. WsAgent.status(options) prints the same markup, and WsAgent.setStage(root, key, patch) redraws one stage as the run moves on; the list's live region reads that stage out. Press the button to move this run forward.

<script src="/js/ws-agent.js?v=<?= filemtime(WS_ROOT . '/js/ws-agent.js') ?>"></script>
panel.innerHTML = WsAgent.status({ id: 'gen', label: 'Building your agenda', stages: [
    { key: 'brief', label: 'Read the brief', state: 'now' },
    { key: 'pick',  label: 'Choose activities', state: 'todo' },
] });
WsAgent.setStage('gen', 'brief', { state: 'done', detail: '12 people, 2 hours.' });
WsAgent.setStage('gen', 'pick', { state: 'failed', recovery: 'The library did not answer.', action: { label: 'Try again' } });
document.addEventListener('ws:agent-retry', e => restart(e.detail.stage));

States

StageLooksSays
doneA tick in a stone circle; the name in ink"Done:"
failedAn exclamation in an amber circle, the recovery sentence in amber ink, and the action"Failed:"
nowA turning ring in a filled red circle; still under reduced motion"In progress:", and aria-current="step"
todoAn empty circle; the name muted"Not started:"
ThinkingThree dots that pulse, and hold still under reduced motionIts sentence, as a status

Real-World Usage

It replaces the Planner generator's loading view and Synthesize's hand-built progress screen, and the six thinking indicators around the chat surfaces. The failed stage is the part those screens never had: say which step broke, what the person can do, and give them the one button that does it.

Options

OptionTypeDefaultPurpose
modestring'stages' when stages are passed, else 'thinking'thinking | stages
labelstring''Thinking: the sentence ("Working on it" when empty). Stages: the list's title.
detailstring''Thinking only: a second, quieter sentence
stagesarray[]Each: label, state (done | failed | now | todo), detail, key (default: its position from 1), recovery and action (failed only; the action takes ws_button options plus label)
idstring''Element id. With a label in stages mode the list is named by {id}-title; WsAgent.setStage() takes it.
class / attrsstring / arrayAdditional classes and attributes

Events: a failed stage's action dispatches ws:agent-retry with detail.stage (its key) and detail.status (the root). Load /js/ws-agent.js for it.

Accessibility

ConcernBehavior
ThinkingThe line is role="status", so its sentence is read when it appears. The dots are aria-hidden and stop under prefers-reduced-motion.
Stage changesThe stage list is a polite live region. When WsAgent.setStage() redraws a stage, a screen reader hears that stage whole: its state, its name, its detail.
State in wordsEvery stage starts with visually hidden words for its state ("Done:", "Failed:", "In progress:", "Not started:"), and each state has its own glyph, so nothing rests on colour. The stage in progress carries aria-current="step".
RecoveryA failed stage's action is a real button in reading order, right after the sentence that says what went wrong.
MotionThe turning ring and the dots stop under reduced motion; the red circle and the words still say the run is going.

Tokens

TokenUsed for
--brand / --brand-tint / --brand-lineThe dots, the stage in progress, and the thinking line's fill and border
--color-warning / --color-warning-surface / --color-warning-surface-inkA failed stage and its recovery sentence
--gray-100 / --gray-300Done and still-to-come circles
--text-dark / --text-default / --text-mutedNames, details, stages not started
--font-heading / --text-h4The stages title
--space-* / --radius-lg / --radius-fullSpacing and shape
--ease-in-outThe dots' pulse

CSS Classes

ClassPurpose
.ws-agent-statusRoot; --thinking or --stages
.ws-agent-status__text / __label / __detail / __dotsThe thinking line
.ws-agent-status__titleThe stages title, with the AI mark
.ws-agent-status__stagesThe live list
.ws-agent-status__stageOne stage, --done / --failed / --now / --todo; carries data-ws-stage
.ws-agent-status__icon / __glyphThe state circle and its glyph
.ws-agent-status__name / __recovery / __actionA stage's name, recovery sentence and action

Files

FilePurpose
includes/components/helpers.phpws_agent_status() helper
includes/components/agent-status.phpTemplate
includes/components/components.cssStyles, in the agent components section
js/ws-agent.jsWsAgent.status(), WsAgent.setStage() and ws:agent-retry