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
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
-
Done: Read the brief
12 product leaders, 2 hours, one decision to make.
-
Failed: Transcribe the kickoff recording
The file stopped at 12 minutes. Upload it again, or carry on without it.
-
In progress: Choose activities from the library
-
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.
<?= 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
| Stage | Looks | Says |
|---|---|---|
done | A tick in a stone circle; the name in ink | "Done:" |
failed | An exclamation in an amber circle, the recovery sentence in amber ink, and the action | "Failed:" |
now | A turning ring in a filled red circle; still under reduced motion | "In progress:", and aria-current="step" |
todo | An empty circle; the name muted | "Not started:" |
| Thinking | Three dots that pulse, and hold still under reduced motion | Its 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
| Option | Type | Default | Purpose |
|---|---|---|---|
mode | string | 'stages' when stages are passed, else 'thinking' | thinking | stages |
label | string | '' | Thinking: the sentence ("Working on it" when empty). Stages: the list's title. |
detail | string | '' | Thinking only: a second, quieter sentence |
stages | array | [] | 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) |
id | string | '' | Element id. With a label in stages mode the list is named by {id}-title; WsAgent.setStage() takes it. |
class / attrs | string / array | Additional 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
| Concern | Behavior |
|---|---|
| Thinking | The line is role="status", so its sentence is read when it appears. The dots are aria-hidden and stop under prefers-reduced-motion. |
| Stage changes | The 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 words | Every 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". |
| Recovery | A failed stage's action is a real button in reading order, right after the sentence that says what went wrong. |
| Motion | The turning ring and the dots stop under reduced motion; the red circle and the words still say the run is going. |
Tokens
| Token | Used for |
|---|---|
--brand / --brand-tint / --brand-line | The dots, the stage in progress, and the thinking line's fill and border |
--color-warning / --color-warning-surface / --color-warning-surface-ink | A failed stage and its recovery sentence |
--gray-100 / --gray-300 | Done and still-to-come circles |
--text-dark / --text-default / --text-muted | Names, details, stages not started |
--font-heading / --text-h4 | The stages title |
--space-* / --radius-lg / --radius-full | Spacing and shape |
--ease-in-out | The dots' pulse |
CSS Classes
| Class | Purpose |
|---|---|
.ws-agent-status | Root; --thinking or --stages |
.ws-agent-status__text / __label / __detail / __dots | The thinking line |
.ws-agent-status__title | The stages title, with the AI mark |
.ws-agent-status__stages | The live list |
.ws-agent-status__stage | One stage, --done / --failed / --now / --todo; carries data-ws-stage |
.ws-agent-status__icon / __glyph | The state circle and its glyph |
.ws-agent-status__name / __recovery / __action | A stage's name, recovery sentence and action |
Files
| File | Purpose |
|---|---|
includes/components/helpers.php | ws_agent_status() helper |
includes/components/agent-status.php | Template |
includes/components/components.css | Styles, in the agent components section |
js/ws-agent.js | WsAgent.status(), WsAgent.setStage() and ws:agent-retry |