I got tired of keeping a Telegram tab open all day just to talk to my local agent, so I built a monitor-resident avatar that fronts it instead — a video-call-style face that performs the replies instead of me reading a wall of text.

A few things that might interest this crowd:

No runtime GPU for the avatar. Instead of live-animating a face, the agent’s reply carries inline emotion-beat tags — [working], [confirm] deploy?, [happy] — and a player selects and blends between ~30 pre-rendered clips. The GPU stays 100% on the model. Code and logs render as chat cards instead of being read aloud, and [confirm] pops a human-in-the-loop approve/cancel that blocks the agent until you answer.

It hooks into a real agent as a connector. The agent’s gateway dials out to a local WebSocket the app hosts, so from the agent’s side the avatar is just “another channel,” indistinguishable from a messenger. Adapters for Hermes and OpenClaw are included, plus a demo mode that runs with zero setup.

Local voice both ways. Edge TTS out (swappable to Qwen3-TTS / MeloTTS / Piper), Silero VAD + faster-whisper in.

Open-core, MIT. The engine is fully usable on its own: drop in a folder of clips named by emotion, point it at your agent. Avatars are pure-data bundles — no code runs when you install one — so you can build your own. The repo ships the engine only; there’s no bundled character.

The engine just plays video clips — it doesn’t care what produced the pixels. So the avatar can be photoreal, 2D anime, a 3D render, pixel art, anything. You can even use a Live2D or VRM model: pre-render its expressions into clips and it becomes a Ghost Vessel preset. A Live2D shell can’t do the reverse — it can’t take live-action footage. Clips are a superset. The trade-off is that you give up real-time rig interactivity (no dragging the head around) and you pay a one-time render step.

Repo + 45s demo: https://github.com/ghdtjrtka/ghost-vessel

The part I’d most like feedback on is the emotion-beat output format — the contract that turns model text into a UI performance. Has anyone here tried similar output contracts to drive an interface from LLM output? Curious what broke on your setup, and whether smaller local models keep the tags straight.

  • catch88@sh.itjust.worksOP
    link
    fedilink
    English
    arrow-up
    2
    ·
    4 days ago

    Circling back since you called it: the NOTICE file is gone. Everything in the repo is MIT now — engine, tools, docs, and the bundled starter avatar — and the README says that in one line instead of three places contradicting each other.

    The carve-out only ever existed because the photoreal avatar is a commissioned likeness I can’t relicense, and that one isn’t in the repo anyway. So it’s named where it’s sold rather than sitting in a legal side-file scaring people off the code. Thanks for pushing on it.