Skip to content

Docs

Components

AgentStatus

The run’s state in one pill, announced to screen readers.

Example

Thinking
Workingread_file3.42s
Waiting for approvalrun_command
Done21.8s
Rate limited by provider

Interactive, and the same on the components page. Try the keyboard below on it.

Installation

npm i @dgesteves/agent-ui-kit ai
import { AgentStatus, deriveAgentState } from '@dgesteves/agent-ui-kit';
// Once per app (with Tailwind v4: @import '@dgesteves/agent-ui-kit/tailwind.css'; in your CSS)
import '@dgesteves/agent-ui-kit/styles.css';

The styles are once per app; Getting started has the Tailwind v4 and plain CSS options.

Usage

const last = messages.findLast((m) => m.role === 'assistant');
// Waiting on a person (an approval, a client-side tool) wins over "working".
const { state, detail } = deriveAgentState({ status, message: last, pendingClientTools: ['review_changes'] });

<AgentStatus state={state} detail={detail} />

API reference

Generated from the types the package ships, so it matches the version you install.

AgentStatus

A compact, live status pill for an agent run. State changes are announced through a polite live region (assertive for errors and approval requests), debounced so rapid transitions do not flood screen readers.

Props

staterequired
AgentState
'idle' | 'thinking' | 'working' | 'awaiting-approval' | 'done' | 'error'
label
string

Overrides the default label for the state.

detail
string

Secondary detail, e.g. the tool being run.

startedAt
number

Epoch ms when the run started. Shows a live elapsed timer while active.

elapsedMs
number

Fixed elapsed time to show (e.g. the final run duration). Takes precedence over startedAt.

announce
booleanDefault true

Announce state changes to assistive tech.

size
'sm' | 'md'Default 'md'

Other props go to the root <div>: className (merged with tailwind-merge), id, aria-*, data-* and event handlers.

AgentState

type AgentState = 'idle' | 'thinking' | 'working' | 'awaiting-approval' | 'done' | 'error';

Accessibility

  • Changes are announced through a live region, debounced by 350 ms so quick flips aren’t read one by one. Approvals and errors are assertive; everything else is polite.
  • Render one AgentStatus per run with announce on; pass announce={false} to any copy, or the state is read twice.
  • Each state has an icon and a word. The thinking shimmer and the spinner run only without prefers-reduced-motion.

Theming

Every color, radius and font is a CSS variable, so the overrides in Theming apply, on :root or scoped to any element. These hooks are read from the component's markup.

Slots (data-slot)
agent-status
State attributes
data-stateon agent-status'idle' | 'thinking' | 'working' | 'awaiting-approval' | 'done' | 'error'
Tokens it uses
--aui-accent--aui-accent-fg--aui-border--aui-fg--aui-fg-muted--aui-fg-subtle--aui-font-mono--aui-font-sans--aui-hot--aui-hot-fg--aui-surface
app/globals.css
/* Only this component, and only inside .settings-panel */
.settings-panel [data-slot='agent-status'] {
  --aui-radius: 4px;
}

[data-slot='agent-status'][data-state='idle'] {
  outline: 1px solid var(--aui-accent);
}