# Agent Status Card

> A React AI agent status card: orb, name, status, current step, progress, elapsed time, steps, logs and the controls that matter right now.

- Type: React component (AI Kit)
- Access: Pro (the source needs a Wingo UI Pro plan, see https://wingo-ui.com/pricing)
- Version: 1.0.0
- Install: `npx wingo-ui@latest add agent-status-card`
- Docs: https://wingo-ui.com/components/agent-status-card

## Interaction

The card shows the agent's orb (it thinks while the agent runs, listens while it waits for a person and rests otherwise; it only animates near the viewport and holds still under reduced motion), its name and task, and a status badge whose dot pings while it runs and which pops once with a check when a run finishes with every step green. Under it the current step shimmers while it runs, a progress bar glides from step to step (Step 3 of 5) and the elapsed time ticks every second. Only the controls that matter now appear: Pause and Stop while it runs, Resume and Stop while paused, Reject and Approve in an amber box when it waits for approval, Retry in a red box when it failed, View result in a green box when it finished. Stop asks first in a centered dialog (Escape or Keep running cancels). A handler that returns a promise spins its button and disables the others until it settles; a rejection is announced. The Steps and Logs toggles at the bottom open the step timeline and a monospace log that follows new lines until you scroll up inside it, and scroll with the keyboard once focused. The ⋯ button opens the agent's menu, a bottom sheet on phones. Tab reaches every control in order, Enter and Space press them, and each control's name includes the agent's name (Stop Collections agent). Status changes are announced once to screen readers. The compact variant keeps the orb, name, status, current step, progress and one primary action for grids; the row variant is a 64px list line with a progress ring that opens the agent on click, tap or Enter. Below 400px the orb sits above the text, buttons share the width and grow to 44px on touch, and logs cap at 40% of the screen height.

## Installation

```bash
npx wingo-ui@latest add agent-status-card
```

Pro item: run `npx wingo-ui@latest login` once with a Pro account. The CLI adds the files, their dependencies and a version record for updates.

With shadcn: `npx shadcn@latest add @wingo-ui/agent-status-card` (needs the @wingo-ui registry with your API key in components.json)

Files:

- `components/ui/agent-status-card.tsx`

npm dependencies: `npm i motion lucide-react`

Wingo UI dependencies (installed automatically):

- [Alert Dialog](https://wingo-ui.com/components/alert-dialog) ([Markdown](https://wingo-ui.com/components/alert-dialog.md))
- [Badge](https://wingo-ui.com/components/badge) ([Markdown](https://wingo-ui.com/components/badge.md))
- [Button](https://wingo-ui.com/components/button) ([Markdown](https://wingo-ui.com/components/button.md))
- [Dropdown Menu](https://wingo-ui.com/components/dropdown-menu) ([Markdown](https://wingo-ui.com/components/dropdown-menu.md))
- [Fluid Orb](https://wingo-ui.com/components/fluid-orb) ([Markdown](https://wingo-ui.com/components/fluid-orb.md))
- [Matrix Orb](https://wingo-ui.com/components/matrix-orb) ([Markdown](https://wingo-ui.com/components/matrix-orb.md))
- [Progress](https://wingo-ui.com/components/progress) ([Markdown](https://wingo-ui.com/components/progress.md))
- [Tool Call Timeline](https://wingo-ui.com/components/tool-call-timeline) ([Markdown](https://wingo-ui.com/components/tool-call-timeline.md))
- [useControllableState](https://wingo-ui.com/components/use-controllable-state) ([Markdown](https://wingo-ui.com/components/use-controllable-state.md))
- [useLocale](https://wingo-ui.com/components/use-locale) ([Markdown](https://wingo-ui.com/components/use-locale.md))
- [useStickToBottom](https://wingo-ui.com/components/use-stick-to-bottom) ([Markdown](https://wingo-ui.com/components/use-stick-to-bottom.md))
- [AI Chat](https://wingo-ui.com/components/ai-chat) ([Markdown](https://wingo-ui.com/components/ai-chat.md))
- [Motion presets](https://wingo-ui.com/components/motion) ([Markdown](https://wingo-ui.com/components/motion.md))
- [Number format](https://wingo-ui.com/components/number-format) ([Markdown](https://wingo-ui.com/components/number-format.md))
- [Relative time](https://wingo-ui.com/components/relative-time) ([Markdown](https://wingo-ui.com/components/relative-time.md))
- [Tones](https://wingo-ui.com/components/tones) ([Markdown](https://wingo-ui.com/components/tones.md))
- [UIProvider](https://wingo-ui.com/components/ui-config) ([Markdown](https://wingo-ui.com/components/ui-config.md))

## Usage

```tsx
import { AlertDialogProvider } from "@/components/ui/alert-dialog"
import { AgentStatusCard, type ToolCall } from "@/components/ui/agent-status-card"

const steps: ToolCall[] = [
  { id: "s1", name: "search_invoices", title: "Finding overdue invoices", status: "complete", durationMs: 820 },
  { id: "s2", name: "get_client_contacts", title: "Getting the contact details", status: "complete", durationMs: 410 },
  { id: "s3", name: "send_reminders", title: "Sending reminders (2 of 3)", status: "running" },
  { id: "s4", name: "update_statuses", title: "Updating the statuses", status: "pending" },
  { id: "s5", name: "send_report", title: "Sending the report", status: "pending" },
]

export function CollectionsAgent({
  onPause,
  onStop,
}: {
  onPause: () => Promise<void>
  onStop: () => Promise<void>
}) {
  return (
    <>
      <AlertDialogProvider />
      <AgentStatusCard
        name="Collections agent"
        task="Reminders for September's overdue invoices"
        status="running"
        steps={steps}
        startedAt={new Date(2026, 8, 24, 16, 38, 2)}
        logs={[{ time: new Date(2026, 8, 24, 16, 38, 5), message: "Found 3 invoices, $22,775.95 in total" }]}
        onPause={onPause}
        onStop={onStop}
        labels={{
          status: { running: "Working", paused: "On hold", complete: "Done" },
          stopTitle: (name) => `Stop ${name} now?`,
          elapsed: (duration) => `Working for ${duration}`,
        }}
      />
    </>
  )
}
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `name?` | `ReactNode` | `""` | The agent's name, also used in the controls' accessible names and the stop dialog. Empty shows labels.untitled. |
| `task?` | `ReactNode` | `""` | What it is doing this run, clamped to two lines with the full text in a tooltip title. |
| `status?` | `"idle" \| "queued" \| "running" \| "paused" \| "awaiting-approval" \| "complete" \| "error" \| "canceled"` | `"idle"` | The run's state. It picks the badge (AGENT_STATUS_TONES: running info, paused and awaiting warning, complete success, error danger, the rest neutral), the orb's mood, the box under the progress and which controls show. In the playground Idle plays the live run and any other value forces that state. |
| `steps?` | `ToolCall[]` |  | The run's steps in the ToolCall shape from lib/ai-chat. The progress (done / total), Step 3 of 5 and the current step derive from them, and the Steps toggle shows them as a tool-call-timeline. |
| `currentStep?` | `ReactNode` | `""` | Overrides the derived current step (the running or waiting step's title, the failed one, else the last finished one). It shimmers while the agent runs. |
| `progress?` | `number \| null` |  | 0 to 1, clamped; null is an indeterminate bar. Undefined derives it from steps; with no steps it is indeterminate while running and hidden otherwise. |
| `startedAt?` | `Date \| string \| number` |  | When the run started; the elapsed time counts from here (live while running or waiting). |
| `endedAt?` | `Date \| string \| number` |  | When it ended: Finished in 1 min 48 s, or Stopped after 14 s for failed and stopped runs. Ignored without startedAt. |
| `logs?` | `(AgentLogEntry \| string)[]` |  | Log lines ({ id?, time?, level?: debug \| info \| warn \| error, message } or plain strings). Passing an array (even empty) shows the Logs toggle with its count. |
| `approval?` | `{ question: ReactNode; description?: ReactNode; approveLabel?: ReactNode; rejectLabel?: ReactNode }` |  | The question shown in the amber box while status is awaiting-approval, with Reject and Approve when their handlers are set. |
| `result?` | `ReactNode` |  | Shown in a green box with a check when the status is complete. |
| `error?` | `ReactNode` |  | Shown in a red box with an alert icon when the status is error. |
| `variant?` | `"card" \| "compact" \| "row"` | `"card"` | card: everything, for a detail page. compact: orb, name, status, current step, progress and one primary action, for a grid of agents. row: a 64px list line with a 32px orb, name and current step, a progress ring with the percent (hidden when the row is narrower than 384px), the badge and the menu. |
| `visual?` | `"matrix-orb" \| "fluid-orb" \| "icon" \| "none"` | `"matrix-orb"` | matrix-orb: dots that think while running, listen while waiting and rest otherwise. fluid-orb: a WebGL blob that drifts while running and holds still otherwise. icon: a round Bot mark tinted by the status. Orbs only mount near the viewport. |
| `orbColor?` | `string` | `""` | A hex color for the orb. Empty follows the status tone (blue while running, green when done, red when failed, gray at rest). |
| `size?` | `"sm" \| "md"` | `"md"` | Card orb 56 / 72px and name 15 / 17px. Compact (48px orb) and row (32px) keep their sizes. |
| `radius?` | `"none" \| "sm" \| "md" \| "lg"` | `"lg"` | Corners of the card and compact surfaces: 0, 12, 16 or 24px. |
| `tone?` | `"neutral" \| "brand" \| "success" \| "warning" \| "danger" \| "info"` | `"neutral"` | The progress fill and the solid buttons (Resume, Approve, Retry). Status colors stay semantic. |
| `color?` | `string` | `""` | Any CSS color; replaces the tone. |
| `shimmer?` | `boolean` | `true` | The moving highlight on the current step while it runs (off under reduced motion; turn it off for static stills). |
| `showSteps?` | `"toggle" \| "always" \| "never"` | `"toggle"` | Card only: the steps timeline behind a Steps toggle, always open under the controls, or not at all. |
| `showLogs?` | `boolean` | `true` | Card only: the Logs toggle (shown when logs is an array). |
| `defaultStepsOpen?` | `boolean` | `false` | Start with the steps timeline open. |
| `stepsOpen?` | `boolean` |  | Controlled open state of the steps panel. |
| `onStepsOpenChange?` | `(open: boolean) => void` |  | Called when the Steps toggle is pressed. |
| `defaultLogsOpen?` | `boolean` | `false` | Start with the logs open. |
| `logsOpen?` | `boolean` |  | Controlled open state of the logs panel. |
| `onLogsOpenChange?` | `(open: boolean) => void` |  | Called when the Logs toggle is pressed. |
| `onPause?` | `() => (void \| Promise<unknown>)` |  | Shows Pause while running. A returned promise keeps the button loading and the others disabled until it settles. |
| `onResume?` | `() => (void \| Promise<unknown>)` |  | Shows Resume (solid) while paused. |
| `onStop?` | `() => (void \| Promise<unknown>)` |  | Shows Stop while running, paused or queued; asks first when confirmStop is on. |
| `onRetry?` | `() => (void \| Promise<unknown>)` |  | Shows Retry when the run failed or was stopped. |
| `onApprove?` | `() => (void \| Promise<unknown>)` |  | Shows Approve in the approval box. |
| `onReject?` | `() => (void \| Promise<unknown>)` |  | Shows Reject in the approval box. |
| `onOpen?` | `() => (void \| Promise<unknown>)` |  | Shows View result when complete; in the row variant the whole row opens the agent. |
| `menu?` | `MenuEntry[]` |  | The ⋯ menu's entries (dropdown-menu's shape): Edit agent, Duplicate, Run history, Delete. A bottom sheet below 768px. |
| `confirmStop?` | `boolean` | `true` | Ask in an alert dialog before onStop (through useConfirm, so mount AlertDialogProvider once). |
| `locale?` | `string` | `""` | Locale for durations (1 min 58 sec in en-US), percents and counts. Empty uses UIProvider's, then the page's. |
| `now?` | `Date \| number` |  | A fixed clock for the elapsed time (screenshots, tests, a paused run). Without it a running agent ticks on the shared ticker. |
| `labels?` | `Partial<AgentStatusCardLabels>` |  | Every visible and spoken string: status (one word per status, partial), untitled, pause, resume, stop, stopTitle(name), stopDescription, keepRunning, approve, reject, approvalNeeded, retry, viewResult, steps, logs, stepOf(index, total), elapsed(duration), finishedIn(duration), stoppedAfter(duration), pausedAfter(duration), noLogs, menu, cancel (the menu sheet's close button on phones), announce(name, status), actionFailed. English defaults in DEFAULT_AGENT_STATUS_CARD_LABELS. |
| `stepsLabels?` | `ToolCallTimelineLabelsInput` |  | Labels for the steps timeline (its status words, Approve, Retry). |
| `classNames?` | `Partial<Record<"visual" \| "header" \| "name" \| "task" \| "status" \| "menu" \| "current" \| "progress" \| "progressLabel" \| "elapsed" \| "approval" \| "result" \| "error" \| "controls" \| "toggles" \| "steps" \| "logs", string>>` |  | Extra classes for the inner parts. |
| `className?` | `string` |  | Extra classes for the root article, merged last. |

## Parts

### AgentLogView (component)

The log scroller alone: monospace lines with 16:38:05 times and warn / error tags, following new lines until the reader scrolls up. A focusable labelled region, not a live region. Props: { logs?: (AgentLogEntry | string)[]; label?: string; emptyText?: ReactNode; showTime?: boolean; follow?: boolean; classNames? }.

### AGENT_STATUS_TONES (constant)

The status to tone map, for your own badges and dots. Type: Record<AgentStatus, Tone>.

### DEFAULT_AGENT_STATUS_CARD_LABELS (constant)

The English strings, to spread and override. Type: AgentStatusCardLabels.

## Examples

- **Awaiting approval**: The agent stops and asks. Approve settles after a fake request and the run completes.
- **Grid of compact cards**: The four agents of Summit CRM: running, waiting, done in 1 min 48 s, failed with Retry.
- **Rows**: The same agents as 64px rows in a list; tap a row to open it, the menu stays separate.
- **Fluid orb**: visual="fluid-orb" in a custom blue, with the steps always visible.
- **Logs open**: 300 generated lines (mulberry32) plus a new one every 1.2 s, following the tail.
- **Sizes and tone**: size sm with a result, size md paused in the brand tone.
- **AgentLogView alone**: The log scroller as its own part, for a run detail page.

## See also

- [Tool Call Timeline](https://wingo-ui.com/components/tool-call-timeline) ([Markdown](https://wingo-ui.com/components/tool-call-timeline.md))
- [Matrix Orb](https://wingo-ui.com/components/matrix-orb) ([Markdown](https://wingo-ui.com/components/matrix-orb.md))
- [Fluid Orb](https://wingo-ui.com/components/fluid-orb) ([Markdown](https://wingo-ui.com/components/fluid-orb.md))
- [Progress](https://wingo-ui.com/components/progress) ([Markdown](https://wingo-ui.com/components/progress.md))
- [Stat Card](https://wingo-ui.com/components/stat-card) ([Markdown](https://wingo-ui.com/components/stat-card.md))

---

Canonical: https://wingo-ui.com/components/agent-status-card
More components: https://wingo-ui.com/components · Index for agents: https://wingo-ui.com/llms.txt
