Connect YOUR AI to a NetShow Alive Agent Avatar
Your avatar's .alive.json is a portable face. It has no brain and no voice of its own —
$0/min · $0/sec — no meter, you pay only your own AI & voice.
Any LLM, any voice model, any device — even offline.
1 · Put the face on the page (two lines)
<script type="module" src="/alive-site/alive-element.js"></script>
<netshow-alive id="ava" type="hybrid" src="/your-path/your-avatar.alive.json"></netshow-alive>
The Alive Agent Avatar is now on screen — breathing, blinking, alive. It's waiting for signals from your AI.
2 · The five signals
| Moment in your app | One line of JavaScript |
|---|---|
| the user starts talking | ava.session.event('listening-started') |
| your LLM is working | ava.session.event('thinking') |
| your reply starts (voice or text) | ava.session.event('responding-started') |
| the reply is finished | ava.session.event('response-completed') |
| set a feeling any time | ava.session.event('state-changed', { mood: 'happy', intensity: 0.8 }) |
3 · Make the mouth move — pick your lane
Voice lane (any voice provider — OpenAI, ElevenLabs, open-source TTS, anything): hand the session your reply audio and the lips ride it automatically:
// WebRTC / OpenAI Realtime: use the remote audio track's stream
ava.session.attachStream(remoteStream);
// Plain TTS audio (any provider, even a local open-source model):
const el = new Audio(urlOfYourTtsAudio);
ava.session.attachStream(el.captureStream());
el.play();
Text lane (chat models, local LLMs, no audio): stream the words and the face speaks them visually:
for (const word of replyText.split(/\s+/)) ava.session.transcript(word);
Manual lane (full control): feed loudness yourself, 0..1, ~30 times a second: ava.session.level(v).
4 · Full example — your own OpenAI (or ANY) pipeline
const ava = document.getElementById('ava');
async function ask(question) {
ava.session.event('listening-started'); // user spoke
ava.session.event('thinking'); // your model is working
// YOUR call, YOUR key, YOUR account — the avatar never sees it
const reply = await yourLLM(question); // OpenAI, Claude, llama.cpp, anything
ava.session.event('responding-started');
const audio = await yourTTS(reply); // any voice model, or skip for text-only
ava.session.attachStream(audio.captureStream()); // lips ride your audio
audio.play();
audio.onended = () => ava.session.event('response-completed');
}
5 · Phone / offline — no internet needed
Use the portable pack (.alive.portable.json — the photo is embedded inside the JSON) plus the
runtime files listed in the live manifest (portableRuntime.files).
Copy them to the device, serve them locally, and the two lines above work with zero network — proven.
Point the signals at any on-device model (llama.cpp, Whisper, a local TTS). One serving note: .mjs files must be
served with a JavaScript MIME type.
Ready-made adapters (optional shortcuts)
If you'd rather not send signals by hand: alive-adapter-openai.js (OpenAI Realtime lifecycles),
alive-adapter-text.js (any token stream — buffers into words for you), alive-adapter-gemini.js,
alive-adapter-local.js. Each speaks the same five-signal protocol; none of them ever touch your keys.
NetShow Alive · Alive Agent Avatars · connected mode stays linked to your NetShow admin; detached mode is yours to take anywhere.