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.

The whole secret: the avatar never calls any AI and never sees your API keys. It listens for five simple signals that you send from wherever your model runs — browser, phone, server, or a fully offline device.

2 · The five signals

Moment in your appOne line of JavaScript
the user starts talkingava.session.event('listening-started')
your LLM is workingava.session.event('thinking')
your reply starts (voice or text)ava.session.event('responding-started')
the reply is finishedava.session.event('response-completed')
set a feeling any timeava.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.