@keyframelabs/elements 0.0.7 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -77,6 +77,41 @@ For `PersonaEmbed`, this is determined by the values you set in the Keyframe pla
77
77
 
78
78
  For `PersonaView`, this is determined by `voiceAgentDetails`.
79
79
 
80
+ ## Emotion Controls
81
+
82
+ The avatar can display emotional expressions (`neutral`, `angry`, `sad`, `happy`) that affect its facial expression and demeanor.
83
+
84
+ ### Automatic Emotion Detection (ElevenLabs)
85
+
86
+ When using ElevenLabs as the voice agent, emotions are automatically detected from the agent's speech. The ElevenLabs agent parses emotion tags from audio alignment data (e.g., `[angry]`, `[happy]`) and the avatar expression updates in real-time.
87
+
88
+ This requires no additional configuration—just configure your ElevenLabs agent to include emotion tags in its responses.
89
+
90
+ ### Manual Emotion Control
91
+
92
+ For other agents or custom emotion logic, you can access the underlying session to set emotions manually:
93
+
94
+ ```typescript
95
+ // Access the underlying SDK session for manual control
96
+ // (Available when using @keyframelabs/sdk directly)
97
+ import { createClient } from '@keyframelabs/sdk';
98
+
99
+ const session = createClient({ ... });
100
+ await session.setEmotion('happy');
101
+ ```
102
+
103
+ ### Agent Events
104
+
105
+ The `emotion` event is emitted when an agent detects an emotion change:
106
+
107
+ ```typescript
108
+ agent.on('emotion', (emotion) => {
109
+ console.log('Emotion detected:', emotion); // 'neutral' | 'angry' | 'sad' | 'happy'
110
+ });
111
+ ```
112
+
113
+ Currently, only the ElevenLabs agent emits emotion events.
114
+
80
115
  ## API
81
116
 
82
117
  ### `PersonaEmbed`
@@ -150,6 +185,8 @@ type VoiceAgentDetails = {
150
185
  agent_id?: string; // For elevenlabs, cartesia
151
186
  signed_url?: string; // For elevenlabs, vapi
152
187
  };
188
+
189
+ type Emotion = 'neutral' | 'angry' | 'sad' | 'happy';
153
190
  ```
154
191
 
155
192
  ## License
@@ -20,6 +20,7 @@ export declare class ElevenLabsAgent extends BaseAgent {
20
20
  private sourceInputSampleRate;
21
21
  private initialized;
22
22
  private lastInterruptId;
23
+ private emotionEmittedForEventId;
23
24
  connect(config: ElevenLabsConfig): Promise<void>;
24
25
  protected handleParsedMessage(message: unknown): void;
25
26
  private handleInitMetadata;
@@ -9,7 +9,7 @@ import { VapiAgent, VapiConfig } from './vapi';
9
9
  * various voice AI backends to the Persona SDK.
10
10
  */
11
11
  export { BaseAgent, DEFAULT_INPUT_SAMPLE_RATE } from './base';
12
- export type { Agent, AgentConfig, AgentEventMap, AgentState } from './types';
12
+ export type { Agent, AgentConfig, AgentEventMap, AgentState, Emotion } from './types';
13
13
  export { GeminiLiveAgent, type GeminiLiveConfig };
14
14
  export { ElevenLabsAgent, type ElevenLabsConfig };
15
15
  export { CartesiaAgent, type CartesiaConfig };
@@ -8,6 +8,8 @@
8
8
  */
9
9
  /** Agent state for UI */
10
10
  export type AgentState = 'idle' | 'listening' | 'thinking' | 'speaking';
11
+ /** Emotion states for avatar expression */
12
+ export type Emotion = 'neutral' | 'angry' | 'sad' | 'happy';
11
13
  /** Agent configuration */
12
14
  export interface AgentConfig {
13
15
  /** System prompt for the agent */
@@ -37,6 +39,8 @@ export interface AgentEventMap {
37
39
  text: string;
38
40
  isFinal: boolean;
39
41
  };
42
+ /** Emotion change (currently only supported by ElevenLabs agent) */
43
+ emotion: Emotion;
40
44
  /** Agent connection closed (unexpected disconnect) */
41
45
  closed: {
42
46
  code?: number;
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { createClient as v } from "@keyframelabs/sdk";
2
- const h = 24e3;
1
+ import { createClient as w } from "@keyframelabs/sdk";
2
+ const l = 24e3;
3
3
  function g(i) {
4
4
  const e = atob(i), t = new Uint8Array(e.length);
5
5
  for (let s = 0; s < e.length; s++)
@@ -15,16 +15,16 @@ function m(i) {
15
15
  function c(i, e, t) {
16
16
  if (e === t)
17
17
  return i;
18
- const s = new Int16Array(i.buffer, i.byteOffset, i.length / 2), n = e / t, a = Math.floor(s.length / n), o = new Int16Array(a);
19
- for (let r = 0; r < a; r++) {
20
- const S = r * n, p = Math.floor(S), f = Math.min(p + 1, s.length - 1), _ = S - p;
21
- o[r] = Math.round(
22
- s[p] * (1 - _) + s[f] * _
18
+ const s = new Int16Array(i.buffer, i.byteOffset, i.length / 2), n = e / t, a = Math.floor(s.length / n), r = new Int16Array(a);
19
+ for (let o = 0; o < a; o++) {
20
+ const _ = o * n, p = Math.floor(_), b = Math.min(p + 1, s.length - 1), v = _ - p;
21
+ r[o] = Math.round(
22
+ s[p] * (1 - v) + s[b] * v
23
23
  );
24
24
  }
25
- return new Uint8Array(o.buffer);
25
+ return new Uint8Array(r.buffer);
26
26
  }
27
- function b() {
27
+ function E() {
28
28
  const i = /* @__PURE__ */ new Map();
29
29
  return {
30
30
  on(e, t) {
@@ -41,7 +41,7 @@ function b() {
41
41
  }
42
42
  };
43
43
  }
44
- function w(i) {
44
+ function f(i) {
45
45
  const e = new Int16Array(i.length);
46
46
  for (let t = 0; t < i.length; t++) {
47
47
  const s = Math.max(-1, Math.min(1, i[t]));
@@ -53,7 +53,7 @@ const I = 16e3;
53
53
  class u {
54
54
  ws = null;
55
55
  _state = "idle";
56
- events = b();
56
+ events = E();
57
57
  inputSampleRate = I;
58
58
  /** Current agent state */
59
59
  get state() {
@@ -113,8 +113,8 @@ class u {
113
113
  this.events.emit("closed", { code: e, reason: t });
114
114
  }
115
115
  }
116
- const E = "gemini-2.5-flash-native-audio-preview-12-2025", C = "wss://generativelanguage.googleapis.com/ws/google.ai.generativelanguage.v1beta.GenerativeService.BidiGenerateContent", k = "wss://generativelanguage.googleapis.com/ws/google.ai.generativelanguage.v1alpha.GenerativeService.BidiGenerateContentConstrained";
117
- class A extends u {
116
+ const A = "gemini-2.5-flash-native-audio-preview-12-2025", C = "wss://generativelanguage.googleapis.com/ws/google.ai.generativelanguage.v1beta.GenerativeService.BidiGenerateContent", k = "wss://generativelanguage.googleapis.com/ws/google.ai.generativelanguage.v1alpha.GenerativeService.BidiGenerateContentConstrained";
117
+ class R extends u {
118
118
  agentName = "GeminiLive";
119
119
  async connect(e) {
120
120
  if (this.ws)
@@ -122,10 +122,10 @@ class A extends u {
122
122
  if (!e.apiKey)
123
123
  throw new Error("Gemini API key is required");
124
124
  e.inputSampleRate && (this.inputSampleRate = e.inputSampleRate);
125
- const t = e.model ?? E, n = (e.authType ?? "api_key") === "ephemeral_token" ? `${k}?access_token=${encodeURIComponent(e.apiKey)}` : `${C}?key=${encodeURIComponent(e.apiKey)}`;
126
- return new Promise((a, o) => {
125
+ const t = e.model ?? A, n = (e.authType ?? "api_key") === "ephemeral_token" ? `${k}?access_token=${encodeURIComponent(e.apiKey)}` : `${C}?key=${encodeURIComponent(e.apiKey)}`;
126
+ return new Promise((a, r) => {
127
127
  this.ws = new WebSocket(n), this.ws.onopen = () => {
128
- const r = {
128
+ const o = {
129
129
  setup: {
130
130
  model: `models/${t}`,
131
131
  generationConfig: {
@@ -134,13 +134,13 @@ class A extends u {
134
134
  systemInstruction: e.systemPrompt ? { parts: [{ text: e.systemPrompt }] } : void 0
135
135
  }
136
136
  };
137
- this.ws.send(JSON.stringify(r)), this.setState("listening"), a();
137
+ this.ws.send(JSON.stringify(o)), this.setState("listening"), a();
138
138
  }, this.ws.onerror = () => {
139
- o(new Error("Failed to connect to Gemini Live"));
140
- }, this.ws.onclose = (r) => {
141
- this.ws = null, this.setState("idle"), this.emitClosed(r.code, r.reason);
142
- }, this.ws.onmessage = (r) => {
143
- this.handleMessage(r.data);
139
+ r(new Error("Failed to connect to Gemini Live"));
140
+ }, this.ws.onclose = (o) => {
141
+ this.ws = null, this.setState("idle"), this.emitClosed(o.code, o.reason);
142
+ }, this.ws.onmessage = (o) => {
143
+ this.handleMessage(o.data);
144
144
  };
145
145
  });
146
146
  }
@@ -189,8 +189,8 @@ class A extends u {
189
189
  this.ws.send(JSON.stringify(t));
190
190
  }
191
191
  }
192
- const R = "wss://api.elevenlabs.io/v1/convai/conversation";
193
- class M extends u {
192
+ const M = ["neutral", "angry", "sad", "happy"], x = "wss://api.elevenlabs.io/v1/convai/conversation";
193
+ class S extends u {
194
194
  agentName = "ElevenLabs";
195
195
  outputSampleRate = 24e3;
196
196
  // Default, updated from metadata
@@ -202,6 +202,8 @@ class M extends u {
202
202
  // True after conversation_initiation_metadata received
203
203
  lastInterruptId = 0;
204
204
  // Track interruptions to filter stale audio
205
+ emotionEmittedForEventId = -1;
206
+ // Track which turn's emotion we've already emitted
205
207
  async connect(e) {
206
208
  if (this.ws)
207
209
  throw new Error("Already connected");
@@ -209,7 +211,7 @@ class M extends u {
209
211
  throw new Error("ElevenLabs agent ID or signed URL is required");
210
212
  e.inputSampleRate && (this.sourceInputSampleRate = e.inputSampleRate);
211
213
  let t;
212
- return e.signedUrl ? t = e.signedUrl : (t = `${R}?agent_id=${e.agentId}`, e.apiKey && (t += `&xi-api-key=${e.apiKey}`)), new Promise((s, n) => {
214
+ return e.signedUrl ? t = e.signedUrl : (t = `${x}?agent_id=${e.agentId}`, e.apiKey && (t += `&xi-api-key=${e.apiKey}`)), new Promise((s, n) => {
213
215
  this.ws = new WebSocket(t), this.ws.onopen = () => {
214
216
  this.setState("listening"), s();
215
217
  }, this.ws.onerror = () => {
@@ -269,19 +271,19 @@ class M extends u {
269
271
  }
270
272
  handleAudio(e) {
271
273
  const t = e.audio_event;
272
- if (!t?.audio_base_64 || (t.event_id ?? 0) <= this.lastInterruptId)
274
+ if (!t?.audio_base_64) return;
275
+ const s = t.event_id ?? 0;
276
+ if (s <= this.lastInterruptId)
273
277
  return;
274
- this._state !== "speaking" && (this.events.emit("turnStart", void 0), this.setState("speaking"));
275
- let n = g(t.audio_base_64);
276
- this.outputSampleRate !== h && (n = c(n, this.outputSampleRate, h));
277
- const a = 4800;
278
- if (n.length <= a)
279
- this.events.emit("audio", n);
280
- else
281
- for (let o = 0; o < n.length; o += a) {
282
- const r = n.slice(o, Math.min(o + a, n.length));
283
- this.events.emit("audio", r);
278
+ if (this._state !== "speaking" && (this.events.emit("turnStart", void 0), this.setState("speaking")), this.emotionEmittedForEventId !== s && t.alignment?.chars) {
279
+ const r = t.alignment.chars.join("").match(/\[(\w+)\]/);
280
+ if (r) {
281
+ const o = r[1].toLowerCase();
282
+ M.includes(o) && (this.events.emit("emotion", o), this.emotionEmittedForEventId = s);
284
283
  }
284
+ }
285
+ let n = g(t.audio_base_64);
286
+ this.outputSampleRate !== l && (n = c(n, this.outputSampleRate, l)), this.events.emit("audio", n);
285
287
  }
286
288
  handleUserTranscript(e) {
287
289
  const t = e.user_transcription_event;
@@ -293,11 +295,11 @@ class M extends u {
293
295
  }
294
296
  handleAgentResponse(e) {
295
297
  const t = e.agent_response_event;
296
- t?.agent_response && this.events.emit("transcript", {
298
+ t?.agent_response && (this.events.emit("turnEnd", void 0), this.setState("listening"), this.events.emit("transcript", {
297
299
  role: "assistant",
298
300
  text: t.agent_response,
299
301
  isFinal: !0
300
- });
302
+ }));
301
303
  }
302
304
  handleInterruption(e) {
303
305
  const t = e.interruption_event;
@@ -341,8 +343,8 @@ class M extends u {
341
343
  this.initialized = !1, this.lastInterruptId = 0, super.close();
342
344
  }
343
345
  }
344
- const x = "wss://api.cartesia.ai/agents/stream", P = "2025-04-16";
345
- class T extends u {
346
+ const P = "wss://api.cartesia.ai/agents/stream", T = "2025-04-16";
347
+ class O extends u {
346
348
  agentName = "Cartesia";
347
349
  // Audio configuration
348
350
  cartesiaInputFormat = "pcm_16000";
@@ -361,7 +363,7 @@ class T extends u {
361
363
  if (!e.apiKey)
362
364
  throw new Error("Cartesia API Key is required");
363
365
  e.inputSampleRate && (this.inputSampleRate = e.inputSampleRate), this.inputSampleRate === 16e3 ? this.cartesiaInputFormat = "pcm_16000" : this.inputSampleRate === 24e3 ? this.cartesiaInputFormat = "pcm_24000" : this.inputSampleRate === 44100 ? this.cartesiaInputFormat = "pcm_44100" : this.cartesiaInputFormat = "pcm_16000";
364
- const t = `${x}/${e.agentId}?api_key=${e.apiKey}&cartesia_version=${P}`;
366
+ const t = `${P}/${e.agentId}?api_key=${e.apiKey}&cartesia_version=${T}`;
365
367
  return new Promise((s, n) => {
366
368
  this.ws = new WebSocket(t), this.ws.onopen = () => {
367
369
  this.sendStartEvent(), this.startHeartbeat(), s();
@@ -424,7 +426,7 @@ class T extends u {
424
426
  if (!e.media?.payload) return;
425
427
  this._state !== "speaking" && (this.events.emit("turnStart", void 0), this.setState("speaking"));
426
428
  let t = g(e.media.payload);
427
- this.cartesiaOutputRate !== h && (t = c(t, this.cartesiaOutputRate, h)), this.events.emit("audio", t);
429
+ this.cartesiaOutputRate !== l && (t = c(t, this.cartesiaOutputRate, l)), this.events.emit("audio", t);
428
430
  }
429
431
  handleClear() {
430
432
  this.events.emit("interrupted", void 0), this.setState("listening");
@@ -446,7 +448,7 @@ class T extends u {
446
448
  this.stopHeartbeat(), this.isReady = !1, this.streamId = null, super.close();
447
449
  }
448
450
  }
449
- class O extends u {
451
+ class N extends u {
450
452
  agentName = "Vapi";
451
453
  // Audio configuration - Vapi uses 16kHz PCM by default
452
454
  vapiSampleRate = 16e3;
@@ -473,7 +475,7 @@ class O extends u {
473
475
  */
474
476
  handleBinaryAudio(e) {
475
477
  this._state !== "speaking" && (this.events.emit("turnStart", void 0), this.setState("speaking"));
476
- const t = new Uint8Array(e), s = this.vapiSampleRate !== h ? c(t, this.vapiSampleRate, h) : t;
478
+ const t = new Uint8Array(e), s = this.vapiSampleRate !== l ? c(t, this.vapiSampleRate, l) : t;
477
479
  this.events.emit("audio", s);
478
480
  }
479
481
  handleParsedMessage(e) {
@@ -525,7 +527,7 @@ class O extends u {
525
527
  this.hangup(), super.close();
526
528
  }
527
529
  }
528
- const N = [
530
+ const U = [
529
531
  { id: "gemini", name: "Gemini Live", description: "Google Gemini Live API" },
530
532
  { id: "elevenlabs", name: "ElevenLabs", description: "ElevenLabs Conversational AI" },
531
533
  { id: "cartesia", name: "Cartesia", description: "Cartesia Agents API" },
@@ -534,21 +536,21 @@ const N = [
534
536
  function y(i) {
535
537
  switch (i) {
536
538
  case "gemini":
537
- return new A();
539
+ return new R();
538
540
  case "elevenlabs":
539
- return new M();
541
+ return new S();
540
542
  case "cartesia":
541
- return new T();
542
- case "vapi":
543
543
  return new O();
544
+ case "vapi":
545
+ return new N();
544
546
  default:
545
547
  throw new Error(`Unknown agent type: ${i}`);
546
548
  }
547
549
  }
548
- function L(i) {
549
- return N.find((e) => e.id === i);
550
+ function F(i) {
551
+ return U.find((e) => e.id === i);
550
552
  }
551
- class U extends Error {
553
+ class D extends Error {
552
554
  status;
553
555
  payload;
554
556
  url;
@@ -556,8 +558,8 @@ class U extends Error {
556
558
  super(e.message), this.name = "ApiError", this.status = e.status, this.payload = e.payload, this.url = e.url;
557
559
  }
558
560
  }
559
- const l = /* @__PURE__ */ new Set();
560
- class F {
561
+ const h = /* @__PURE__ */ new Set();
562
+ class K {
561
563
  apiBaseUrl;
562
564
  publishableKey;
563
565
  callbacks;
@@ -601,31 +603,31 @@ class F {
601
603
  }
602
604
  /** Connect to the embed session */
603
605
  async connect() {
604
- if (l.has(this.publishableKey)) {
606
+ if (h.has(this.publishableKey)) {
605
607
  console.log("[PersonaEmbed] Connection already in progress, skipping");
606
608
  return;
607
609
  }
608
- l.add(this.publishableKey), this.mounted = !0, this.abortController = new AbortController(), this.setStatus("connecting");
610
+ h.add(this.publishableKey), this.mounted = !0, this.abortController = new AbortController(), this.setStatus("connecting");
609
611
  try {
610
612
  const e = await this.fetchSession(this.abortController.signal);
611
613
  if (!this.mounted) {
612
- l.delete(this.publishableKey);
614
+ h.delete(this.publishableKey);
613
615
  return;
614
616
  }
615
617
  if (await this.initSession(e), await this.initMicrophone(), await this.connectAgent(e.voice_agent_details), !this.mounted) {
616
- this.cleanup(), l.delete(this.publishableKey);
618
+ this.cleanup(), h.delete(this.publishableKey);
617
619
  return;
618
620
  }
619
621
  this.setStatus("connected");
620
622
  } catch (e) {
621
- if (l.delete(this.publishableKey), e instanceof Error && e.name === "AbortError")
623
+ if (h.delete(this.publishableKey), e instanceof Error && e.name === "AbortError")
622
624
  return;
623
625
  console.error("[PersonaEmbed]", e), this.mounted && (this.setStatus("error"), this.callbacks.onError?.(e));
624
626
  }
625
627
  }
626
628
  /** Disconnect and cleanup */
627
629
  disconnect() {
628
- this.mounted = !1, this.abortController?.abort(), this.abortController = null, l.delete(this.publishableKey), this.cleanup(), this.setStatus("disconnected");
630
+ this.mounted = !1, this.abortController?.abort(), this.abortController = null, h.delete(this.publishableKey), this.cleanup(), this.setStatus("disconnected");
629
631
  }
630
632
  /** Toggle microphone mute */
631
633
  toggleMute() {
@@ -650,7 +652,7 @@ class F {
650
652
  s = await t.json();
651
653
  } catch {
652
654
  }
653
- throw new U({
655
+ throw new D({
654
656
  message: s?.message ?? "create_session failed",
655
657
  status: t.status,
656
658
  payload: s,
@@ -664,7 +666,7 @@ class F {
664
666
  return t.json();
665
667
  }
666
668
  async initSession(e) {
667
- this.session = v({
669
+ this.session = w({
668
670
  serverUrl: e.session_details.server_url,
669
671
  participantToken: e.session_details.participant_token,
670
672
  agentIdentity: e.session_details.agent_identity,
@@ -684,9 +686,11 @@ class F {
684
686
  onClose: () => {
685
687
  this.mounted && this.callbacks.onDisconnect?.();
686
688
  }
687
- }), this.agent = y(e.voice_agent_details.type), this.agent.on("audio", (t) => this.session?.sendAudio(t)), this.agent.on("interrupted", () => this.session?.interrupt()), this.agent.on("stateChange", (t) => this.setAgentState(t)), this.agent.on("closed", () => {
689
+ }), this.agent = y(e.voice_agent_details.type), this.agent.on("audio", (t) => this.session?.sendAudio(t)), this.agent.on("turnEnd", () => this.session?.endAudioTurn()), this.agent.on("interrupted", () => {
690
+ this.session?.endAudioTurn(), this.session?.interrupt();
691
+ }), this.agent.on("stateChange", (t) => this.setAgentState(t)), this.agent.on("closed", () => {
688
692
  this.mounted && this.callbacks.onDisconnect?.();
689
- }), await this.session.connect();
693
+ }), this.agent instanceof S && this.agent.on("emotion", (t) => this.session?.setEmotion(t)), await this.session.connect();
690
694
  }
691
695
  async initMicrophone() {
692
696
  this.stream = await navigator.mediaDevices.getUserMedia({
@@ -695,7 +699,7 @@ class F {
695
699
  const e = this.audioContext.createMediaStreamSource(this.stream);
696
700
  this.processor = this.audioContext.createScriptProcessor(4096, 1, 1), this.processor.onaudioprocess = (t) => {
697
701
  if (!this._isMuted) {
698
- const s = w(t.inputBuffer.getChannelData(0));
702
+ const s = f(t.inputBuffer.getChannelData(0));
699
703
  this.agent?.sendAudio(s);
700
704
  }
701
705
  }, e.connect(this.processor), this.processor.connect(this.audioContext.destination);
@@ -725,7 +729,7 @@ class F {
725
729
  }
726
730
  }
727
731
  const d = /* @__PURE__ */ new Set();
728
- class K {
732
+ class B {
729
733
  voiceAgentDetails;
730
734
  sessionDetails;
731
735
  callbacks;
@@ -799,7 +803,7 @@ class K {
799
803
  this._agentState !== e && (this._agentState = e, this.callbacks.onAgentStateChange?.(e));
800
804
  }
801
805
  async initSession() {
802
- this.session = v({
806
+ this.session = w({
803
807
  serverUrl: this.sessionDetails.server_url,
804
808
  participantToken: this.sessionDetails.participant_token,
805
809
  agentIdentity: this.sessionDetails.agent_identity,
@@ -819,9 +823,11 @@ class K {
819
823
  onClose: () => {
820
824
  this.mounted && this.callbacks.onDisconnect?.();
821
825
  }
822
- }), this.agent = y(this.voiceAgentDetails.type), this.agent.on("audio", (e) => this.session?.sendAudio(e)), this.agent.on("interrupted", () => this.session?.interrupt()), this.agent.on("stateChange", (e) => this.setAgentState(e)), this.agent.on("closed", () => {
826
+ }), this.agent = y(this.voiceAgentDetails.type), this.agent.on("audio", (e) => this.session?.sendAudio(e)), this.agent.on("turnEnd", () => this.session?.endAudioTurn()), this.agent.on("interrupted", () => {
827
+ this.session?.endAudioTurn(), this.session?.interrupt();
828
+ }), this.agent.on("stateChange", (e) => this.setAgentState(e)), this.agent.on("closed", () => {
823
829
  this.mounted && this.callbacks.onDisconnect?.();
824
- }), await this.session.connect();
830
+ }), this.agent instanceof S && this.agent.on("emotion", (e) => this.session?.setEmotion(e)), await this.session.connect();
825
831
  }
826
832
  async initMicrophone() {
827
833
  this.stream = await navigator.mediaDevices.getUserMedia({
@@ -830,7 +836,7 @@ class K {
830
836
  const e = this.audioContext.createMediaStreamSource(this.stream);
831
837
  this.processor = this.audioContext.createScriptProcessor(4096, 1, 1), this.processor.onaudioprocess = (t) => {
832
838
  if (!this._isMuted) {
833
- const s = w(t.inputBuffer.getChannelData(0));
839
+ const s = f(t.inputBuffer.getChannelData(0));
834
840
  this.agent?.sendAudio(s);
835
841
  }
836
842
  }, e.connect(this.processor), this.processor.connect(this.audioContext.destination);
@@ -860,20 +866,20 @@ class K {
860
866
  }
861
867
  }
862
868
  export {
863
- N as AGENT_REGISTRY,
869
+ U as AGENT_REGISTRY,
864
870
  u as BaseAgent,
865
- T as CartesiaAgent,
866
- M as ElevenLabsAgent,
867
- A as GeminiLiveAgent,
868
- U as KeyframeApiError,
869
- F as PersonaEmbed,
870
- K as PersonaView,
871
- h as SAMPLE_RATE,
871
+ O as CartesiaAgent,
872
+ S as ElevenLabsAgent,
873
+ R as GeminiLiveAgent,
874
+ D as KeyframeApiError,
875
+ K as PersonaEmbed,
876
+ B as PersonaView,
877
+ l as SAMPLE_RATE,
872
878
  g as base64ToBytes,
873
879
  m as bytesToBase64,
874
880
  y as createAgent,
875
- b as createEventEmitter,
876
- w as floatTo16BitPCM,
877
- L as getAgentInfo,
881
+ E as createEventEmitter,
882
+ f as floatTo16BitPCM,
883
+ F as getAgentInfo,
878
884
  c as resamplePcm
879
885
  };
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "0.0.7",
7
+ "version": "0.0.9",
8
8
  "type": "module",
9
9
  "main": "./dist/index.js",
10
10
  "types": "./dist/index.d.ts",
@@ -19,7 +19,7 @@
19
19
  ],
20
20
  "sideEffects": false,
21
21
  "dependencies": {
22
- "@keyframelabs/sdk": "0.1.5"
22
+ "@keyframelabs/sdk": "0.1.7"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@types/node": "^25.0.9",