Agent Thinking

A dot-matrix disc that shows whether an agent is idle, listening, thinking or speaking.

Comparing roast notes
'use client';

import { useState } from 'react';
import { AgentThinking, Button } from '@brand-studio/ui';

const states = [
  { state: 'idle', label: 'Ready when you are' },
  { state: 'listening', label: 'Listening' },
  { state: 'thinking', label: 'Comparing roast notes' },
  { state: 'speaking', label: 'Answering' },
] as const;

export default function AgentThinkingDemo() {
  const [current, setCurrent] = useState<(typeof states)[number]>(states[2]);
  return (
    <div style={{ display: 'grid', justifyItems: 'center', gap: 40 }}>
      <AgentThinking state={current.state} label={current.label} size={72} />
      <div style={{ display: 'flex', flexWrap: 'wrap', justifyContent: 'center', gap: 8 }} role="group" aria-label="Agent state">
        {states.map((item) => (
          <Button key={item.state} tone={item === current ? 'primary' : 'secondary'} shape="pill" aria-pressed={item === current} onClick={() => setCurrent(item)}>
            {item.state}
          </Button>
        ))}
      </div>
    </div>
  );
}

Installation

pnpm add @brand-studio/ui

Usage

import { AgentThinking } from '@brand-studio/ui';
<AgentThinking state="thinking" label="Comparing roast notes" />

Examples

Sizes

size sets the width in pixels. Below 40 pixels the disc uses fewer, larger dots so it stays legible next to text.

Searching 14 orders
Listening
Speaking
import { AgentThinking } from '@brand-studio/ui';

export default function AgentThinkingSizes() {
  return (
    <div style={{ display: 'grid', gap: 24, justifyItems: 'start' }}>
      <AgentThinking size={20} label="Searching 14 orders" />
      <AgentThinking size={48} state="listening" />
      <AgentThinking size={96} state="speaking" />
    </div>
  );
}

Accessibility

  • The component has role="status". With label it shows and announces that text; without it, screen readers hear the state name.
  • Each state moves differently, so it does not rely on colour alone. Under reduced motion the disc holds still and the label stays.

API Reference

PropTypeDefault
state?"idle" | "listening" | "speaking" | "thinking"'thinking'
size?number64
label?string
className?string''

Still, Deskhand and Hollis are fictional brands. The coffee photographs are original generated artwork. @brand-studio/ui is MIT licensed.