Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

saa-js-demo

End-to-end browser demo for attention labs SAA (Selective Auditory Attention) SDK, streams microphone and webcam to the SAA Server, then forwards detected speech segments to OpenAI Realtime.

Everything runs in the browser. The server tells you when someone is speaking and what they said; this demo routes that speech to the LLM of your choice (OpenAI Realtime is shown).

What you'll need

  • A SAA auth token (sign up on the dashboard here)
  • An OpenAI API key with Realtime access (optional, omit to run and just see live predictions)
  • Node 18+ and a modern browser (Chrome, Edge, Safari, Firefox)

Setup

Follow these steps in order:

1. Install

From a checkout of the saa-sdk monorepo:

git clone https://github.com/attenlabs/saa-sdk.git
cd saa-sdk/examples/web
npm install

2. Serve the repo

npx serve

This prints a local URL, typically http://localhost:3000. Open it in your browser.

3. Connect

In the Setup panel (top-left of the page), paste your SAA token (and optionally your OpenAI key) and click Connect. The browser will prompt for microphone and camera access, allow both.

After a short warmup, the orb starts reacting to your voice.

URL parameters

All optional. The token / key fields stay editable in the UI. URL params just auto-populate them for future runs.

param notes
token Pre-fills the SAA auth token field.
openai_key Pre-fills the OpenAI key field. Omit to just watch predictions and VAD.

Example: /?token=al_live_…&openai_key=sk-…

How it works

  1. app.js constructs an AttentionClient from @attenlabs/saa-js, which acquires the mic + webcam and opens a WebSocket to the SAA server.
  2. The SDK emits typed events, prediction, vad, state, turnReady, warmupComplete. app.js renders into the UI.
  3. On turnReady, app.js hands the PCM16 audio (and any attached JPEG frames) to llm.js, a small OpenAI Realtime bridge that wraps them into input_audio / input_image content parts and plays the response back through WebAudio.
  4. While the LLM is speaking, app.js calls client.mute() + client.markResponding(true) so the server stops emitting predictions until playback ends.
  5. A small guided flow (top-of-screen pill) walks first-time users through talk to the computer → talk to each other → free play.

The LLM bridge is deliberately part of this demo, not the SDK, swap in whichever provider you like.

Recommended usage

Try three send thresholds and keep the one that performs best: 0.6, 0.77, 0.88. Raise it for fewer false triggers, lower it to catch borderline speech. Drag the threshold slider, or call client.setThreshold(v).

Known limitations

  • Mic/camera permission is requested before the token is validated. client.start() calls getUserMedia() before the broker /allocate call checks the token, so an invalid token still triggers a real permission prompt. If you only want to test auth, expect the browser to ask for mic/camera access first.
  • No automatic reconnect. The SDK does not retry the WebSocket on a network drop. A clean close shows a Disconnected — … toast and ends the session (mic/camera released, UI reset to the Setup panel); a stalled-but-open connection only surfaces a non-actionable Connection Stalled toast. Either way, click Connect again to start a new session — there is no resume.

Security note

This demo accepts the OpenAI API key in the browser (typed into the UI or passed via URL) for simplicity. Never do that in production, always proxy the Realtime connection through a server you control so the key never reaches the client.

License

Apache-2.0