Drop-in avatar template for the AgentCall plugin's bridge-visual.py.
Replaces ui-templates/avatar/index.html with a Pattern AI sunburst design.
.
├── index.html # the avatar (16 KB, no build step)
├── agentcall-audio.js # AgentCall audio helper (copied from the plugin)
└── README.md
Keeps the stock avatar template intact; users opt into pattern:
mkdir -p ~/.claude/plugins/join-meeting-agentcall/ui-templates/pattern
cp index.html ~/.claude/plugins/join-meeting-agentcall/ui-templates/pattern/index.html
# agentcall-audio.js is already at ui-templates/ (no copy needed)Then add "pattern" to the --template choices in bridge-visual.py.
Use it:
bridge-visual.py "<meet-url>" --name "Claude" --template patterncp index.html ~/.claude/plugins/join-meeting-agentcall/ui-templates/avatar/index.htmlbridge-visual.py … --template avatar now uses this design.
# Already live at:
bridge-visual.py "<meet-url>" --webpage-url \
https://anandpattern.github.io/agentcall-pattern-avatar/No tunnel, no local server. The bridge appends ?ws=…&name=… and FirstCall
loads it directly.
| State | Color | Animation | Primary text | Sub-line |
|---|---|---|---|---|
| listening | white | slow opacity pulse (2.4s) | "Listening" | — |
| hearing-input | blue | faster opacity pulse (1.2s) | "Listening" | — |
| thinking | purple | opacity pulse + ring spin | "Thinking" | — |
| working | orange | opacity pulse (1s) | "Working" | active task with icon |
| speaking | green | length breath, ~20% expand | "Replying" | — |
| holding | yellow | opacity pulse (1.4s) | "✋ Can I add something?" | — |
| interrupted | amber | frozen | "Interrupted" | — |
| contextually_aware | teal | slow pulse | "Following up" | — |
All non-speaking states animate opacity only — every spoke keeps the same length so the outer circle stays perfectly round. Only speaking pulses the height, anchored at the inner end so the center hole stays fixed.
The sub-line under "Working" is the only place text is dynamic. The agent can push the active task at any time via a custom event the bridge re-broadcasts to the avatar's WebSocket:
{ "event": "agent.activity", "text": "🔎 Researching dynamic UI patterns" }Recommended verbs (with icons) so they read at a glance:
| Verb | Icon |
|---|---|
| Researching | 🔎 |
| Preparing presentation | 📊 |
| Web search | 🌐 |
| Reading the codebase | 📂 |
| Drafting reply | ✍️ |
| Querying database | 🗄️ |
The bridge clears the sub-line on every state change other than working.
The avatar's WS connection (same URL as bridge.py's WS) reacts to:
| Event | Effect |
|---|---|
transcript.partial |
state → hearing-input |
transcript.final |
state → thinking |
voice.state |
named state (overrides above when the bridge knows) |
tts.audio.* |
passed to AgentCallAudio — drives speaking/listening state |
tts.interrupted |
state → interrupted, then back to listening after 1.2s |
agent.activity |
sets the working sub-line (custom; see above) |
| Constant | Default | What it controls |
|---|---|---|
BAR_COUNT |
16 | Number of spokes around the circle |
RADIUS |
36 px | Inner radius (size of the central empty circle) |
.bar { height } |
60 px | Spoke length |
.bar { width } |
10 px | Spoke thickness |
--pulse-period |
varies | Pulse duration per state (CSS per [data-state]) |
| Speaking peak | 72 px | Max height during speaking pulse (~20% expansion) |
--listening, etc. |
colors | State accent colors (CSS variables on :root) |
- Pure HTML/CSS/JS, ~16 KB. No framework, no build step.
- Animation runs on the GPU compositor (
opacity,transform, withwill-change: opacity, heightandcontain: layout style paint). - Single external request:
agentcall-audio.js(already in the plugin). - No polling, no heavy DOM updates. Every state change is one class swap.
MIT — copy, ship, modify freely.