<!-- Generated by scripts/gen-docs.mts from the JSDoc in registry/. Do not edit; run `pnpm run docs`. -->

# AgentPresence

The person's always-visible sign of which of their agents are listening to something on their behalf, such as a meeting, with Stop one click away. A chip with the agent sparkle says "inbox agent listening", or "2 agents listening"; it opens a popover that lists each agent, what it listens for and a Stop, plus Stop all with two or more. It never hides itself while an agent listens (no fading, no collapsing), and renders nothing when none does. `compact` shows only the sparkle and a count, and `unread` a dot when an agent left something for the person.

```tsx
import { AgentPresence } from "@/components/ouro/agent-presence/agent-presence";
```

## Example

```tsx
<AgentPresence
  label="Agents listening"
  agents={[{ id: "inbox", name: "inbox agent", doing: "listening for your name" }]}
  onStop={(id) => stopListening(id)}
/>
<AgentPresence label="Agents listening" agents={agents} onStop={stop} onStopAll={stopAll} compact unread />
```

## Usage

The chip is a button named by the count and the names ("2 agents listening: inbox agent, research agent"). When an agent starts or stops listening, screen readers hear it once, politely ("inbox agent is now listening", "inbox agent stopped"). When a Stop goes with its agent, focus moves to the next Stop, and when the last agent goes, to the control after the chip.

Its agent side, `agentPresenceAx` in `agent-presence-styles.ts`, lets agents read who is listening and what for (consent `none`). An agent may stop only its own listening: `stop` is `scope: "self"`, so Ouro AX refuses an agent's call on another agent's row. Stop on another agent's row and Stop all are the person's, because the person asked those agents to listen. It offers no way to start listening: that stays the person's.

## Use instead when

- Use `Avatar` or `Badge` instead to show who is present in a conversation, and `toast()` for a one-off notice.

## Props

Type: `AgentPresenceProps`.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `agents` (required) | `readonly ListeningAgent[]` |  | The agents listening now. With none, AgentPresence renders nothing; keep it mounted, so it can say when an agent stops or starts. |
| `className` | `string` |  | Layout only: margins, placement (`ms-auto`). Appearance classes warn in development; use `size`. |
| `compact` | `boolean` |  | Only the sparkle and a count, for a tight bar or a floating mini-window. Its name still says who is listening. |
| `label` (required) | `string` |  | Names the list of agents: the popover's title, "Agents listening". It is always required. |
| `labels` | `AgentPresenceLabels` |  | The words it says, for other languages. |
| `onStop` (required) | `(id: string) => void` |  | Called with an agent's `id` when the person presses its Stop. Stop the agent and drop it from `agents`; AgentPresence says "inbox agent stopped" once it has gone. The person may stop any agent here. |
| `onStopAll` | `(() => void)` |  | Called when the person presses Stop all, which shows with two agents or more. Without it, Stop all calls `onStop` for each agent. |
| `ref` | `Ref<HTMLSpanElement>` |  | Reaches the rendered element. |
| `size` | `"sm" \| "md" \| "lg"` | `"sm"` | The chip's size, Button's sizes. |
| `unread` | `boolean` |  | Shows a dot on the chip: an agent left something for the person. AgentPresence opens nothing for it; the app shows what was left where it belongs. |

## Don't use

These are not props. Passing one fails the type check with the fix in the error, and in development a console message names the fix.

- `autoHide`: Not a prop. AgentPresence never hides while an agent listens; it renders nothing only when `agents` is empty.
- `listeners`: Not a prop. The agents are `agents`: `<AgentPresence agents={[{ id: "inbox", name: "inbox agent" }]}>`.
- `onRemove`: Not a prop. Ouro UI says `onStop`, called with the agent's id: `<AgentPresence onStop={(id) => stop(id)}>`.
- `variant`: Not a prop. The small form is `compact`: `<AgentPresence compact>`.

## `className` is for layout only

Pass margins, width and grid placement (`mt-4`, `w-full`, `col-span-2`).

Appearance comes from props, not classes. In development, a class that sets appearance logs one warning per component instance, naming the prop to use instead. A class sets appearance when, after its variants (`hover:`, `sm:`) and any `!` are removed, it starts with `bg-`, `text-`, `border-`, `rounded-`, `shadow-`, `font-`, `ring-`, `from-`, `via-`, `to-`, `fill-` or `stroke-`, or is `border`, `rounded`, `shadow` or `ring`, or has a `dark:` variant. Text wrapping, overflow and table layout classes (`text-wrap`, `text-ellipsis`, `border-collapse`) are layout and do not warn.

Alignment classes (`text-center`) warn too: set alignment on a parent element.

## Types

### `AgentPresenceLabels`

The words AgentPresence says, for apps in other languages.

```ts
interface AgentPresenceLabels {
  /** The chip for one agent. @default (name) => `${name} listening` */
  one?: ((name: string) => string) | undefined;
  /** The chip for several. @default (count) => `${count} agents listening` */
  many?: ((count: number) => string) | undefined;
  /** Said once when an agent starts listening. @default (name) => `${name} is now listening` */
  started?: ((name: string) => string) | undefined;
  /** Said once when an agent stops, whoever stopped it. @default (name) => `${name} stopped` */
  stopped?: ((name: string) => string) | undefined;
  /**
   * Each agent's Stop button. Screen readers hear the agent's name after it. @default "Stop"
   */
  stop?: string | undefined;
  /**
   * The button that stops every agent. @default "Stop all"
   */
  stopAll?: string | undefined;
  /** What screen readers hear for the unread dot. @default "Something new from your agents" */
  unread?: string | undefined;
  /** The popover's close button, which shows when it has keyboard focus. @default "Close" */
  close?: string | undefined;
}
```

### `ListeningAgent`

One agent listening for the person.

```ts
interface ListeningAgent {
  /** Stays the same while the agent listens; `onStop` gets it back. */
  id: string;
  /** What the person calls the agent, by its role: "inbox agent". */
  name: string;
  /** What it listens for, in a few words: "listening for your name, and anything about the empty state". */
  doing?: string | undefined;
}
```
