@animated-waffle/client
v0.2.6
Published
Framework-independent browser SDK for Narya Animated Waffle talking Agents.
Downloads
1,283
Readme
@animated-waffle/client
Framework-independent browser SDK for embedding a published Narya talking
Agent: connection lifecycle, microphone input, text input, state, and
transcripts. React applications should use
@animated-waffle/react, which re-exports this entire API
and adds the Avatar renderer.
The Agent owns its avatar, voice, and prompt. Pipecat, Daily, API routes, and
avatar asset URLs are SDK implementation details. Production is the default
API origin; tests and non-production integrations may pass apiOrigin.
Connect
Keep the permanent workspace API key on your server. Exchange it for a short-lived Agent session token and give the browser a callback that obtains one for each connection:
import { WaffleClient } from '@animated-waffle/client'
const agentId = '22222222-2222-4222-8222-222222222222'
const endUserId = '55555555-5555-4555-8555-555555555555'
const waffle = new WaffleClient({
agentId,
// Set false for text-triggered, output-only applications.
inputAudioEnabled: false,
sessionToken: async () => {
const response = await fetch('/api/narya-session-token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ agentId, endUserId }),
})
const body = await response.json()
return body.token
},
})
waffle.on('transcript', ({ id, role, text, final }) => {
// Completed Narya conversation rows use the same id as persisted history.
if (final) console.log(id, role, text)
})
await waffle.connect()endUserId is one stable bare UUID per end user. An anonymous application can
generate it once with crypto.randomUUID() and persist it on that device.
To target a non-production environment:
const waffle = new WaffleClient({
agentId,
sessionToken: () => getSessionToken(agentId),
apiOrigin: 'https://animated-waffle-dev.narya.ai',
})API surface
connect({ inputMode? })—'push-to-talk'(default) or'automatic'.inputAudioEnabled: false— never requests or enables the browser microphone; text input, Agent audio, transcripts, and reconnects continue to work. Push- to-talk controls fail closed withinput_audio_disabled. The default istrue, enabled only after the Agent is ready.muted— silences the Agent's voice while it keeps performing: the session, the transcript and the Avatar's cues carry on, only playback goes quiet.audioPlayback: false— the client builds no audio element of its own. PlayremoteAudioTrackyourself; an application that routes the voice through its own element, mixer or Web Audio graph must turn this off, or the voice is heard twice.mutedthen has nothing to do.disconnect(),sendText(text).startPushToTalk()/commitPushToTalk()/cancelPushToTalk().on('status' | 'session' | 'transcript' | 'agentSpeaking' | 'error', fn)— returns the unsubscribe function.- Conversation transcripts carry the same required
idas persisted history. Provider sentence/progress framing never defines a public conversation row. status,sessiongetters; failures throwWaffleErrorwithcode.
./internal is a private contract consumed by @animated-waffle/react; it is
not part of the public API and may change without notice.
See the SDK documentation for the complete integration guide.
