English | 简体中文 | Español | Русский | Français | Português | Deutsch | 日本語 | 한국어 | 繁體中文
A lightweight, expressive robot avatar Web Component for AI agents and interactive applications.
Suitable for AI assistant and agent interfaces, including products and experiences similar to ChatGPT, Claude, Codex, Cursor, Grok Bot, Gemini CLI, and OpenCode.
It can also be used for desktop pets, virtual pets, desktop companions, digital mascots, chatbot avatars, and other interactive character experiences.
Agent Robot Avatar can also be used as a visual feedback layer for AG-UI-style agent interfaces.
Built with SVG and vanilla JavaScript, it works as a native custom element with zero runtime dependencies.
- Native Web Component
- SVG rendering + vanilla JavaScript
- Zero runtime dependencies
- Automatic blinking and subtle idle behavior
- Pointer-following eyes and inertial head movement
- Jelly-style drag deformation with elastic recovery
- Press-and-hold squeeze and draggable spring antenna interactions
- Programmatically controlled Agent states and expressions
- Expressions for waiting, success, failure, affirm, wary, inspect, angry, refuse, love and more
- Reduced-motion support
- Configurable sleep behavior
- Adjustable head roundness
- 42 material and pattern skins with light that follows the pointer
- TypeScript declarations included
npm install agent-robot-avatarimport 'agent-robot-avatar';Or load the repository source directly:
<script type="module" src="./agent-robot-avatar.js"></script>Then add the component:
<agent-robot-avatar id="avatar"></agent-robot-avatar>No initialization code is required. The avatar enters its default idle behavior automatically.
const avatar = document.querySelector('#avatar');
avatar.play('success');
avatar.play('wary');
avatar.play('refuse');
avatar.reset();Available actions:
| Action | Looks like | Use when |
|---|---|---|
idle |
Blinks and glances around | Default state |
bored |
Glances slowly from side to side | Nothing has happened for a while |
waiting-spin |
Eyes circle from side to side | Waiting for a reply (default) |
waiting-wrap |
Eyes slide out one side and back in the other | Waiting for a reply |
waiting-wave |
Eyes bob up and down in turn | Waiting for a reply |
input |
Eyes become blinking text cursors | The user is typing |
affirm |
Nods | Got it, confirmed |
success |
Happy, smiling eyes | Task completed |
failure |
Head and eyes droop | Task or connection failed |
wary |
Turns its head and gives a guarded up-and-down look | An action needs confirmation |
inspect |
Narrows its eyes and scans up and down | Checking or reviewing something |
angry |
Lowered, glaring eyes | Content blocked |
refuse |
Shakes its head | Cannot or will not do the request |
surprise |
Wide-open eyes | Something unexpected |
love |
Eyes merge into a beating heart | Thanks, affection |
random |
Eyes spin like slot-machine reels | Random pick, playful moment |
sleep |
Closes its eyes and sleeps | No activity for a long time |
wake |
Opens its eyes and wakes up | Activity resumes |
Waiting actions play one round with play(). startWaiting({ variant: 'spin' | 'wrap' | 'wave' }) loops until another action starts or stopWaiting() is called.
Names from 0.5 (send, warning, error, blocked, slot and others) still work with a console notice until 1.0; see the upgrade table.
For a real Agent request lifecycle:
avatar.startWaiting();
// Alternative waiting motion: eyes turn out through one side and return through the other.
avatar.startWaiting({ variant: 'wrap' });
// Alternative waiting motion: staggered vertical eye waves.
avatar.startWaiting({ variant: 'wave' });
try {
const result = await runAgentRequest();
await avatar.play(result.ok ? 'success' : 'failure');
} catch (error) {
await avatar.play('failure');
}<agent-robot-avatar
size="160"
color="#08090b"
auto-sleep="30000"
wake-on="activity"
motion="auto">
</agent-robot-avatar>| Attribute | Purpose |
|---|---|
size |
Avatar size in pixels |
color |
Main avatar color |
auto-sleep |
Idle time before automatic sleep; 0 disables it |
wake-on |
Automatic wake policy: activity, interaction, or manual |
motion |
Motion policy: auto, reduce, or full |
press-squeeze |
Center press-and-hold squeeze; set to false to disable |
antenna-drag |
Antenna drag, spring return, and angry reaction; set to false to disable |
skin |
Material: obsidian, porcelain, gold … (42); leave it out for the flat color |
Common runtime controls:
avatar.setPointerFollow(false);
avatar.setHeadRoundness(75);
avatar.setPressSqueeze(true);
avatar.setAntennaDrag(true);The avatar center begins the squeeze interaction. Moving more than 4 CSS pixels transfers the same pointer gesture to the existing head drag. Dragging the antenna uses the same pull limit as head dragging and ends with the existing angry reaction.
42 skins in five families. Light follows the pointer:
<agent-robot-avatar skin="obsidian"></agent-robot-avatar>avatar.setSkin('porcelain'); // any name below
avatar.setSkin(null); // back to the flat color| Family | Skins |
|---|---|
| Glass and gems | obsidian, midnight, jade, amber, ruby, sapphire, emerald, neon |
| Porcelain, pastel and clay | porcelain, pearl, sakura, mint, lavender, lemon, sky, peach, terracotta |
| Metal | gold, silver, copper, titanium, rose-gold, graphite |
| Gradients | aurora, ocean, forest, candy |
| Printed patterns | tartan, polka, terrazzo, marble, black-marble, wood, pixel, confetti, rainbow, denim, graph-paper, halftone, leaves, blossoms, brick |
The SKIN_NAMES export lists every name, for example to build a picker.
Every expression and gesture works with a skin. When the skin is removed, the color attribute applies again.
The component emits face-state for visual state changes and action-state for semantic action lifecycle changes.
For host integrations and accessibility status text, prefer action-state. See examples/accessibility.html for a runnable request-lifecycle example.
A minimal integration example is available at examples/basic.html.
Designed for modern browsers with support for ES Modules, Custom Elements, SVG, Pointer Events, Web Animations API, IntersectionObserver, ResizeObserver, and matchMedia.
Automated browser tests cover Chromium, Firefox, and WebKit.
A C++ version that shows the avatar's expressions on robot and dev-board screens (it draws only the eyes) is in development and not released yet. See the hardware guide.
Issues and pull requests are welcome. See CONTRIBUTING.md before submitting changes.
Current public version: v0.6.0
The public API is intentionally kept compact while the project evolves toward a future 1.0.0 stability commitment.
Agent Robot Avatar is independently developed and is not affiliated with, endorsed by, or representative of any AI platform or brand.
The Agent Robot Avatar character, including its robot appearance and visual identity, is an original design by CX ArtLab.
The MIT License applies to the software and source code. It allows the avatar to be used, modified, and distributed as part of applications, but it does not transfer ownership of the Agent Robot Avatar name, character identity, or visual identity, or grant the right to present them as another party's original character or standalone brand.
Third-party product names mentioned in this project describe possible use cases only and do not indicate affiliation or endorsement.
MIT License. See LICENSE.
If this project is useful to you, you can buy me a coffee.