Observed since 21 Oct, 11:02 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Generative, animated avatars for AI agents — deterministic from a seed.
Generative, animated avatars for AI agents — a deterministic visual identity grown from a seed string. Instead of a photoreal face (creepy) or a cartoon mascot (cheesy), each agent gets an irregular faceted presence: a "broken-whole" cluster of crystalline shards that reads as an object with character, and can come alive — listening, thinking, speaking — without ever pretending to be human.
Same seed → same avatar, forever, under a given generation version.
![]()
from ai_identicon import Genome, color_svg, line_art_svg
g = Genome.from_seed("agent://alice") # deterministic identity
open("alice.svg", "w").write(color_svg(g)) # a filled, shaded portrait
open("alice-line.svg", "w").write(line_art_svg(g, "white")) # line-art, for dark UIs
(seed, algo_version, brand, overrides). The generation algorithm is versioned and immutable:
improving it later ships as a new ALGO_VERSION, so an existing agent's face
never changes under it. A committed golden-file suite locks each version.idle / listening / thinking / speaking / streaming / notify / success / error) with gaze choreography,
breathing, blinks, and shard micro-physics. Present without being noisy; never
interrupts.genome, geometry, model, portrait,
controller are pure Python. SVG portraits need nothing. The live animated
widget and mic-reactive audio are an optional Qt extra.The orb expresses what an agent is doing through motion and light — never a
face. One seed (bmev5p5akc), all eight states:
idle at rest, breathing; the odd blink | listening turns to face you; ripples drift inward | thinking comes apart to turn it over, gaze down‑right | speaking voice drawn as a waveform around it |
streaming text arriving; a bright point laps its edge | notify a chirp and an excited spin; self‑returns | success a warm pulse and spin‑up; self‑returns | error seized: rotation frozen, flushed red, one flinch |
speaking is voice, streaming is text tokens landing — the two output channels. notify / success / error are transient: they play out and settle back to idle on their own.
pip install ai-identicon # core: genomes + SVG portraits (no deps)
pip install "ai-identicon[qt]" # + the live animated widget, audio, and gallery
Both lines install the same package — [qt] is not a different build, it
asks pip to bring along an optional dependency group. The library code is
identical either way; the only difference is whether PySide6 comes with it.
| core | [qt] | |
|---|---|---|
| Genomes, deterministic from a seed | ✅ | ✅ |
| SVG portraits (color + line-art) | ✅ | ✅ |
| Headless state model / controller | ✅ | ✅ |
| Live animated widget, mic + sounds | — | ✅ |
Copy-to-clipboard, ai-identicon-gallery | — | ✅ |
The split is worth it because of the size: the library is ~500 KB and PySide6
is ~1.1 GB. Generating avatars on a server has no business downloading a
desktop GUI toolkit, so the core declares no dependencies at all — every
requirement is conditional on an extra. Qt is imported by exactly four
modules — widget, audio, clipboard and gallery — never by the core,
and the test suite runs without it, which is what keeps that promise honest
rather than aspirational.
Extras are additive: install the core now, and pip install "ai-identicon[qt]"
later just adds PySide6 alongside — nothing is reinstalled or swapped.
Quote the brackets. In zsh and bash
[and]are glob characters, so an unquotedpip install ai-identicon[qt]can fail withno matches found.
Python 3.10+. To see it move without installing anything at all:
pipx run --spec "ai-identicon[qt]" ai-identicon-gallery
from ai_identicon import Genome, color_svg, line_art_svg, export_svg
g = Genome.from_seed("EK7f...aid-prefix")
color_svg(g, px=40) # tuned for a 40px avatar
line_art_svg(g, "black", px=40) # dark strokes for light UIs
line_art_svg(g, "white") # light strokes for dark UIs
export_svg(g, "out.svg", variant="color")
Portraits render the canonical front pose (physics-settled), size-aware: at small sizes strokes thicken and near-coplanar interior lines fade to whispers, so the mark still reads as a shape at 40px.
from ai_identicon import Genome, AvatarController
from ai_identicon.widget import PresenceWidget
from ai_identicon.audio import SoundBank
orb = PresenceWidget(Genome.from_seed("agent://alice"), sounds=SoundBank())
ctl = AvatarController(orb) # map your assistant's lifecycle to states
ctl.thinking(); ctl.speaking(); ctl.on_audio(amplitude=level)
Run the interactive gallery — installed as a command, no clone needed:
pip install "ai-identicon[qt]"
ai-identicon-gallery # optionally: ai-identicon-gallery <seed>
Or try it without installing anything: pipx run --spec "ai-identicon[qt]" ai-identicon-gallery. Its copy 📋 button puts the avatar on the clipboard
to paste into chats/notes.
from ai_identicon import Genome
from ai_identicon.clipboard import copy_to_clipboard # needs a running Qt app
copy_to_clipboard(Genome.from_seed("agent://alice")) # pasteable PNG
Copies a PNG (with the SVG attached as a bonus MIME) — PNG is the format
that pastes reliably into Obsidian, MS Teams, Signal, Discord, Slack, and
docs, and it keeps transparency so the avatar drops onto any background. The
live widget has a convenience method too: presence_widget.copy_to_clipboard().
from ai_identicon import Genome, Brand
# pin specific fields; everything unpinned still tracks the seed
g = Genome.from_seed("alice").with_overrides(material=1, hue=250)
# constrain a whole product's palette/materials to a brand
brand = Brand(hues=(215, 250, 285), materials=("crystal", "glass"))
g = Genome.from_seed("alice", brand=brand)
g.to_dict() # {seed, algo_version, brand, overrides} — the portable identity
The package version (semver) and ALGO_VERSION (the avatar-generation
contract) are independent. Package releases never alter an existing seed's
avatar; only a new ALGO_VERSION may, and prior versions stay renderable. This
is enforced by tests/golden_v1.json.
An avatar is an identity affordance, not a control. A determined party can grind seeds toward a look-alike, so never let the avatar substitute for a verifiable identifier (e.g. show the full AID/prefix where trust matters).
Sixteen names, sixteen seeds, sixteen agents you'd know on sight — each one
idling below: breathing, glowing, gently turning. All just
Genome.from_seed(name), deterministic, so "James" always looks like James,
everywhere, forever. 👋
James | Mary | Michael | Jennifer |
William | Elizabeth | David | Sarah |
John | Jessica | Robert | Emily |
Joseph | Emma | Daniel | Olivia |
MIT.
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.8.2 | 9 Aug 2026 | 2 |
This describes our collected data; it is not a security assessment.
Shared repository data · GitHub
Observed since 21 Oct, 11:02 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:66c4837f781588f682a237651550157b8cefc8bdfc40173a4ad2c3100100286a