cd /news/artificial-intelligence/i-replaced-the-chat-window-for-my-lo… · home topics artificial-intelligence article
[ARTICLE · art-51774] src=dev.to ↗ pub= topic=artificial-intelligence verified=true sentiment=· neutral

I replaced the chat window for my local AI agent with a face

A developer built Ghost Vessel, a monitor-resident avatar that replaces the chat interface for a local LLM agent. The avatar uses pre-rendered clips and emotion beats from the model's output to create a video-call-style interaction, avoiding live inference to keep GPU resources for the LLM. The project is open-source under MIT and includes adapters for Hermes and OpenClaw agents.

read3 min views1 publishedJul 8, 2026

I run a local LLM agent (Hermes) on my own machine. The problem was never the model — it was the interface. I had a Telegram tab open all day just to talk to it: type a command, wait, read a wall of text back, scroll. It felt like texting a very capable stranger.

So I built ** Ghost Vessel** — a monitor-resident, video-call-style avatar that fronts the agent. The name is the whole idea: the

Here's what actually turned out to be interesting to build.

The core idea is an output contract. Instead of treating the agent's reply as text to print, I split every reply into three planes:

Emotion beats are inline tags the model emits in-band with its answer:

[working] — the avatar puts on glasses and takes notes while a task runs[confirm] deploy to prod?

— pops a human-in-the-loop approve/cancel, and the agent blocks on your keypress`[happy]`

/ `[concerned]`

/ … — fine-grained facial expressionsSo "run the build, and if it passes, deploy" becomes a little performance: it looks busy while working, shows you the log as a card, then leans in and asks before the irreversible step. The text you'd have skim-read becomes something you glance at.

The obvious way to animate a face is live inference. I didn't want that — the GPU is busy running the actual model.

Instead the avatar is ~30 pre-rendered clips, and the emotion beats just select and blend between them (blink-aligned seamless idle loops, a head-pose "settle gate" so an expression only reveals when the head is frontal). The avatar's runtime cost is basically video playback. Your GPU stays 100% on your LLM.

The tradeoff: no real-time lip-sync. I decided a believable talking mouth loop + expressive face reads as "a person on a call" far more than perfect phoneme-matching does, and it costs nothing at runtime. That single decision collapsed most of the hard engineering.

The agent integration is the part I was most unsure would work. It turned out clean: the app registers as a connector. The agent's gateway dials out to a local WebSocket the app hosts, and exchanges frames — so from the agent's side, the avatar is just "another channel," indistinguishable from Telegram.

Adapters for Hermes and OpenClaw are included, plus a demo responder so it runs with zero setup. And the chat pane serves the agent's live slash-command menu — type /

and you get the same 52 commands you'd see in the messenger, passed straight through.

The engine is MIT and usable on its own: clone it, drop a folder of clips named by emotion (happy.mp4

, working.mp4

, idle.mp4

, …), point it at your agent. Avatars are pure-data bundles — no code runs when you install one — so you can build your own; the full reproducible method is in the repo.

The part I'd most like feedback on is the emotion-beat output format — the contract that turns LLM text into a UI performance. Has anyone else built output contracts to drive an interface from model output? What broke, and what did models reliably get right vs. wrong? I'd genuinely like to compare notes.

── more in #artificial-intelligence 4 stories · sorted by recency
── more on @ghost vessel 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/i-replaced-the-chat-…] indexed:0 read:3min 2026-07-08 ·