# agentfaces: full reference
> Expressive animated faces for AI agents. One `` component shows what an agent is doing on React, React Native and as plain SVG strings. Zero runtime dependencies, MIT licensed, npm package `agentfaces`. Docs: https://ajibadedapo.github.io/agentfaces/ Source: https://github.com/ajibadedapo/agentfaces
This file is the complete API reference and recipes in one place, written for AI coding agents and humans. It matches agentfaces 0.2.x.
## Install
```sh
npm install agentfaces
```
React Native also needs `react-native-svg` (no reanimated):
```sh
npm install agentfaces react-native-svg
```
Peer dependencies are optional and only needed for the entry point you use: `react >= 18` for `agentfaces/react`, plus `react-native >= 0.72` and `react-native-svg >= 13` for `agentfaces/react-native`. Node 18 or newer.
## Entry points
| Import | Use it for |
| --- | --- |
| `agentfaces/react` | ``, `` and `useAudioLevel` on the web. Ships with `"use client"`, so it works in Next.js App Router server components as a child. |
| `agentfaces/react-native` | The same `` and provider for React Native, drawn with `react-native-svg` and the built-in `Animated` API. |
| `agentfaces/svg` | `renderFaceSvg` (one SVG string) and `buildFaceSet` (every state and expression as files, a sprite and a manifest). For servers, emails, other frameworks. |
| `agentfaces` | Framework-free core: state and expression names, labels, `faceFor`, geometry, the behaviour scheduler, the ticker and audio levels. No React. |
| `agentfaces/livekit` | Maps LiveKit `useVoiceAssistant()` to face props. |
| `agentfaces/openai-realtime` | Follows OpenAI Realtime events or an `@openai/agents-realtime` session as face states. |
| `agentfaces/elevenlabs` | Maps ElevenLabs conversation status, mode and volume to face props. |
`agentfaces/react` and `agentfaces/react-native` also re-export the names you usually need: `AGENT_STATES`, `EXPRESSION_NAMES`, `SHAPE_NAMES`, `STATE_LABEL`, `DEFAULT_PALETTE`, `VOICE_STATES`, `faceFor`, `placementVariant`, `createAudioLevel`, `createLevelFeed`, `createSyntheticVoice` and the types `AgentState`, `ExpressionName`, `ShapeName`, `VoiceState`, `Placement`, `AudioLevel` and friends.
Never import the web component from `agentfaces` (the root has no component) and never import `agentfaces/react` in a React Native app.
## `` props
Same props on `agentfaces/react` and `agentfaces/react-native`. Every prop is optional.
| Prop | Type | Default | Meaning |
| --- | --- | --- | --- |
| `state` | `AgentState` | `"idle"` | What the agent is doing. Drives motion, expressions, glyph morphs and the accessible name. |
| `shape` | `"circle" \| "triangle" \| "square"` | picked from `seed` | Body shape. |
| `color` | `string` (hex) | picked from `seed` | Body color. |
| `seed` | `string` | `""` | Stable id (agent or user id). Picks shape and color and seeds the motion so the same agent always looks the same. |
| `size` | `number` | `48` | Pixels on the web, points on native. |
| `expression` | `ExpressionName` | cycles the state's pool | Hold one expression instead of cycling. |
| `variant` | `"live" \| "still"` | `"live"` | `"still"` renders one frame and runs no timers. Use it in long lists. |
| `mouth` | `boolean` | `true` | Draw the mouth. |
| `label` | `string` | state name | Full accessible name. Overrides `name`. |
| `name` | `string` | | Agent name; the accessible name becomes `"name, State"`, for example `"Ada, Thinking"`. |
| `decorative` | `boolean` | `false` | Hide from assistive technology (when visible text already says the state). |
| `reducedMotion` | `boolean` | OS setting | Force reduced motion on or off. |
| `audio` | web: `MediaStream \| AudioNode \| HTMLMediaElement \| LevelCallback \| LevelStream \| AudioLevel \| null`; native: `LevelCallback \| LevelStream \| AudioLevel \| null` | simulated while speaking | Audio for the voice states. See Voice agents. |
| `className`, `style` | web only | | Applied to the root ``. |
| `testID` | native only | `"agentface-live"` or `"agentface-still"` | Test id on the root view. |
The web root is a `` with `data-af-state`, `data-af-variant` and `data-af-expression` attributes, handy for tests.
## States (`AgentState`)
20 states. Pick the one that matches what the agent is doing right now.
| Group | Constant | States |
| --- | --- | --- |
| Core work states | `CORE_STATES` | `idle`, `thinking`, `working`, `needs-you`, `done`, `alert`, `celebrate`, `sleeping` |
| Extended | `EXTENDED_STATES` | `starting`, `attentive`, `exploring`, `waiting`, `handing-off`, `heads-up` |
| Ornaments | `ORNAMENT_STATES` | `typing` (ellipsis over the mouth), `running` (spinner ring), `monitoring` (ripple), `background` (orbiting tracker dot) |
| Voice | `VOICE_STATES` | `listening`, `speaking` |
All of them: `AGENT_STATES`. Names are lowercase and kebab-case: `needs-you`, `handing-off`, `heads-up` (never `needs_you`, `needsYou` or `waiting_for_user`).
Accessible names (`STATE_LABEL`): Idle, Thinking, Working, Needs you, Done, Alert, Celebrating, Sleeping, Starting up, Paying attention, Exploring, Waiting, Handing off, Heads up, Typing, Running, Monitoring, Working in the background, Listening, Speaking. Translate them with the provider's `labels`.
Behaviour worth knowing:
- `alert`, `needs-you` and `done` periodically morph the body into `!`, `?` and a check mark and back.
- `celebrate` throws confetti.
- `done`, `starting` and `handing-off` play their body motion once; the others loop.
- `listening` leans in and pulses with the user's voice; `speaking` moves the mouth with the agent's audio.
- Morphs, ornaments, confetti and voice motion are skipped under reduced motion and in the still variant.
Suggested mapping from a typical agent loop:
| Agent is... | State |
| --- | --- |
| waiting for input, nothing happening | `idle` |
| request sent, model has not answered yet | `thinking` |
| streaming text | `typing` |
| running a tool or long task | `working` (or `running` for a spinner) |
| blocked on user approval or a question | `needs-you` |
| finished a turn successfully | `done` |
| error or failed tool | `alert` |
| big success (task complete, tests green) | `celebrate` |
| disconnected or paused | `sleeping` |
| booting or connecting | `starting` |
| delegating to another agent or a human | `handing-off` |
| watching something in the background | `monitoring` or `background` |
| voice agent hearing the user | `listening` |
| voice agent talking | `speaking` |
## Expressions (`ExpressionName`)
28 expressions in `EXPRESSION_NAMES`: `calm`, `glad`, `pleased`, `sly`, `playful`, `eager`, `giggling`, `cheering`, `overjoyed`, `smitten`, `bashful`, `flustered`, `wistful`, `serene`, `intrigued`, `pondering`, `intent`, `resolute`, `doubtful`, `puzzled`, `watchful`, `startled`, `uneasy`, `downcast`, `weary`, `drowsy`, `heedful`, `chatty`.
Each state cycles a small pool of expressions on its own (`STATE_EXPRESSIONS`), so you normally do not set `expression`. Set it only to hold one face, for example `expression="puzzled"`. Holding `smitten` morphs the body into a heart. There is no `happy`, `sad` or `angry`: use `glad`, `downcast` or `resolute`.
## Shapes and colors (`ShapeName`)
`circle`, `triangle`, `square` (`SHAPE_NAMES`). Default palette (`DEFAULT_PALETTE`): `#8B5CF6`, `#2B90FF`, `#20C75E`, `#13B8A7`, `#F97216`, `#F6254C`, `#EA489B`, `#64748B`, `#D4A000`. With a `seed` and no `shape` or `color`, `faceFor(seed, { shapes, palette })` picks both deterministically.
## Unknown names
`state`, `shape` and `expression` are checked at runtime. An unknown value never throws: the face falls back (`idle` for state, the seeded shape for shape, the state's own expressions for expression; `renderFaceSvg` and `buildFaceSet` fall back to `circle`) and, in development only (`process.env.NODE_ENV !== "production"`), warns once with the fix, for example:
```
agentfaces: unknown state "needs_you". Did you mean "needs-you"? Using "idle" instead. Valid states: idle, thinking, ...
```
The same checks are exported for your own code: `checkState(value, fallback?)`, `checkShape(value, fallback?)`, `checkExpression(value)`, `suggestName(value, names)` and `isAgentState(value)` from `agentfaces`.
## ``
Sets defaults for every face below it. Providers nest and merge.
| Prop | Type | Meaning |
| --- | --- | --- |
| `shapes` | `ShapeName[]` | Shapes seeded faces are picked from. |
| `palette` | `string[]` | Colors seeded faces and confetti are picked from. |
| `size` | `number` | Default size. |
| `variant` | `"live" \| "still"` | Default variant. |
| `mouth` | `boolean` | Default mouth switch. |
| `reducedMotion` | `boolean` | Force reduced motion for every face. |
| `labels` | `Partial>` | Override or translate accessible state names. |
`useAgentFacesTheme()` reads the current theme.
## `agentfaces/svg`
- `renderFaceSvg(options): string` returns one standalone `