Bot Orb — a living face for every bot
Glass blob + two eyes, inspired by the Kree8 mascot post. Driven by the bot's real state and voice.
Lead: Add Orb as a bot look. It is the bot's face everywhere a bot shows up. It moves only when the bot's real state changes, so it tells you what the bot is doing before you read anything.
Live prototype — click the states, move the pointer, try the mic
What it's for
- Memorable bots. Each bot gets its own tint from its id, so you can tell your bots apart at a glance.
- Status without text. Listening, thinking, working, speaking and "needs you" each look different.
- A face for voice. The orb reacts to your mic level while it listens and to its own voice while it speaks.
- Tap to talk. Clicking the orb starts or stops voice with that bot.
- One component at every size. The same orb works at 16 px in a pill and at 200 px on the stage.
States — real signal → what the orb does
| State | Real signal (already in code) | Orb |
|---|---|---|
| Idle | run | slow breathe, eyes glance around, random blinks |
| Selected | bot picked in chat (@-mention, pill, thread) | small hop, eyes open wide, greeting under it |
| Listening | voice listening / hearing |
body swells with mic level, eyes big, looking at you |
| Thinking | voice thinking, model streaming before text |
body shrinks to a core, rim spins fast, eyes look up |
| Working | tool call running (useAvatarActivity) |
eyes scan side to side, rim speeds up |
| Speaking | voice speaking + outputLevel() |
body and eyes pulse with the spoken audio |
| Needs you | approval / question card waiting | eyes look at the composer, small nudge |
| Muted | voice muted |
eyes closed |
| Error | run or voice error |
eyes flatten, motion nearly stops |
All states: eyes follow the pointer on hover. A click makes the orb squish. Reduced motion shows one still frame with open eyes.
Where it shows
Build plan
BotOrbcomponent (src/components/bots/orb/). Owned canvas 2D, no new package, no WebGL, so it runs in Safari 17. One shared animation loop for every orb on screen. Each orb pauses when it is off screen or the tab is hidden.- Look + storage. Add the
orblook tobot-looks.ts. AddorbTint(optional) toAvatarConfig. The default tint comes from the bot id. Add a tint row to the look picker and Edit bot. - Render branch. Add
orbtoResolvedBotAvatar,LayerArtandLookThumb(BotAvatar.tsx:643,BotLookStage.tsx:148,300). - State in.
BotOrbreadsuseAvatarActivity().VoiceBotAvatarprovides the voice phase and thelevel()/outputLevel()functions through context. The orb reads levels in its own loop, with no React re-render per frame. - Selected stage. When you pick a bot in chat,
LaunchHeader(44 px today) grows into a 160 px stage with the greeting. TheBotChatSessionView.tsx:1386empty state gets the same stage. A click on the stage orb starts voice. - Voice bar.
VoiceBarshows the bot's avatar instead of the genericVoiceOrbwhen a bot is in the chat. This works for every look, not only Orb. - Fix in scope:
ActiveAgentMascot.tsx:121ignores the main bot's picked look. It must honor the pick. - Phone + PWA. Same
BotChatSessionViewandVoiceSessioncode, with phone sizing (stage 120 px). PWA deploy is a manual step after your go-ahead. - Docs. User guide: "Bot looks → Orb". Dev docs: the
BotOrbstates contract. Runcheck_links.pyand the MDX check. - Ship. One build and one live check at the end on Desktop, the ai.allternit.com phone view and the PWA.