@convai/web-sdk 1.7.0-beta.0 → 1.7.0-beta.1

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
@@ -2,7 +2,7 @@
2
2
 
3
3
  **Real-time conversational AI characters for the web.**
4
4
 
5
- [![npm](https://img.shields.io/badge/npm-1.6.0--beta-blue)](https://www.npmjs.com/package/@convai/web-sdk)
5
+ [![npm](https://img.shields.io/badge/npm-1.7.0-blue)](https://www.npmjs.com/package/@convai/web-sdk)
6
6
  [![TypeScript](https://img.shields.io/badge/TypeScript-first-3178C6)](https://www.typescriptlang.org/)
7
7
  [![License](https://img.shields.io/badge/license-Apache--2.0-green)](./LICENSE)
8
8
 
@@ -10,14 +10,18 @@ TypeScript-first SDK for embedding Convai AI characters into React and vanilla J
10
10
 
11
11
  ---
12
12
 
13
- ## What's new in 1.6.0
13
+ ## What's new in 1.7.0
14
14
 
15
- > Currently in beta — `npm install @convai/web-sdk@beta`. Stable 1.6.0 follows.
15
+ - **Character state of mind** set a temporary generation mood with the `stateOfMind` config option, and change it mid-session with `updateEmotion()` without triggering a response. [Usage below.](#character-state-of-mind)
16
+ - **Send-ahead enabled by default** — NeuroSync lipsync ahead-delivery is now on by default, reversing the 1.6.0 opt-in. Fall back to the legacy paced path with `blendshapeConfig.deliver_chunks_ahead: false`.
17
+ - **Lipsync naturalness pipeline** — modular naturalness processing with a tuned MetaHuman profile.
18
+ - **Adaptive glass widget styling** — `ConvaiWidget` adapts to light and dark backgrounds.
19
+
20
+ ### Previously in 1.6.0
16
21
 
17
22
  - **Narrative Design template keys** — personalize one narrative graph per session: seed values at connect with the `narrativeTemplateKeys` config option, replace them mid-session with `updateTemplateKeys()`. [Usage below.](#narrative-design-template-keys)
18
23
  - **Typed parameterized actions** — `actionResponse` is now typed via the exported `ConvaiAction` / `ActionResponseEvent`, including the `target` of parameterized actions. [Usage below.](#actions)
19
24
  - **Vision dynamic context** — camera, screen, canvas, and custom tracks feed unified vision context on WebRTC, with hardened WebSocket vision handling. [Usage below.](#vision-dynamic-context-beta)
20
- - **Send-ahead disabled by default** — lipsync send-ahead is now opt-in.
21
25
 
22
26
  ---
23
27
 
@@ -26,7 +30,7 @@ TypeScript-first SDK for embedding Convai AI characters into React and vanilla J
26
30
  - **React & vanilla JS** — `useConvaiClient` hook, `ConvaiWidget`, and a framework-agnostic core
27
31
  - **Real-time audio/video** — full-duplex WebRTC with echo cancellation, camera, and screen share
28
32
  - **Lipsync** — ARKit and MetaHuman blendshape streams for facial animation
29
- - **Emotions** — per-turn emotion detection with intensity scale
33
+ - **Emotions & state of mind** — per-turn emotion detection with intensity scale, plus a settable generation mood
30
34
  - **Dynamic context & vision** — inject text state, scene metadata, and LiveKit video frames mid-session
31
35
  - **Actions & Narrative Design** — typed action decisions with parameterized targets, named triggers, and per-session template keys
32
36
  - **Long-term memory** — persistent cross-session memories scoped to each end user
@@ -101,7 +105,7 @@ Full documentation is at **<a href="https://docs.convai.com/api-docs/plugins-and
101
105
  | <a href="https://docs.convai.com/api-docs/plugins-and-integrations/web-plugins/convai-web-sdk" target="_blank" rel="noopener noreferrer">Vanilla JS</a> | `ConvaiClient`, `createConvaiWidget`, and audio setup |
102
106
  | <a href="https://docs.convai.com/api-docs/plugins-and-integrations/web-plugins/convai-web-sdk/event-reference" target="_blank" rel="noopener noreferrer">Events</a> | Full event reference — `botReady`, `stateChange`, `messagesChange`, `interactionCreated`, and more |
103
107
  | <a href="https://docs.convai.com/api-docs/plugins-and-integrations/web-plugins/convai-web-sdk/dynamic-context" target="_blank" rel="noopener noreferrer">Context Management</a> | Dynamic context, `updateContext`, file upload, session management |
104
- | <a href="https://docs.convai.com/api-docs/plugins-and-integrations/web-plugins/convai-web-sdk/emotions" target="_blank" rel="noopener noreferrer">Emotions</a> | Per-turn emotion detection with provider options |
108
+ | <a href="https://docs.convai.com/api-docs/plugins-and-integrations/web-plugins/convai-web-sdk/emotions" target="_blank" rel="noopener noreferrer">Emotions</a> | Per-turn emotion detection, provider options, and `stateOfMind` / `updateEmotion()` |
105
109
  | <a href="https://docs.convai.com/api-docs/plugins-and-integrations/web-plugins/convai-web-sdk" target="_blank" rel="noopener noreferrer">Lipsync</a> | ARKit / MetaHuman blendshape streams and `BlendshapeQueue` API |
106
110
  | <a href="https://docs.convai.com/api-docs/plugins-and-integrations/web-plugins/convai-web-sdk/actions" target="_blank" rel="noopener noreferrer">Actions</a> | Trigger character behaviors and scene actions |
107
111
  | <a href="https://docs.convai.com/api-docs/plugins-and-integrations/web-plugins/convai-web-sdk/long-term-memory" target="_blank" rel="noopener noreferrer">Memory</a> | Long-term memory scoped to end users |
@@ -236,6 +240,36 @@ Requires Narrative Design on the character; `updateTemplateKeys` is a full repla
236
240
 
237
241
  ---
238
242
 
243
+ ## Character state of mind
244
+
245
+ Set a temporary generation mood that shapes tone and pacing for the next response. This is separate from `enableEmotion`, which reports the character's detected emotion *after* a turn.
246
+
247
+ ```ts
248
+ const client = new ConvaiClient({
249
+ apiKey: "...",
250
+ characterId: "...",
251
+ stateOfMind: "anticipation",
252
+ });
253
+
254
+ // Mid-session. Affects the next response; does not trigger one.
255
+ client.updateEmotion("joy");
256
+ client.updateEmotion(null); // clear — "neutral" and "" clear it too
257
+ ```
258
+
259
+ Values are trimmed and lowercased. The runtime value carries into the next connect, including a reconnect; an explicit `stateOfMind` in the connect config takes precedence.
260
+
261
+ Requires backend support — live on production as of 2026-08-20. On a backend without it, the server replies with an `Unknown message type` error on `serverResponse`. Because `/connect` silently ignores unknown fields, a successful connect alone does not prove `state_of_mind` was applied, so watch the ack:
262
+
263
+ ```ts
264
+ client.on("serverResponse", (r) => {
265
+ if (r.event_type === "update-emotion" && r.status !== "success") {
266
+ console.warn("state of mind unsupported by this backend:", r.message);
267
+ }
268
+ });
269
+ ```
270
+
271
+ ---
272
+
239
273
  ## License
240
274
 
241
275
  Licensed under the [Apache License 2.0](./LICENSE). Copyright 2025 Convai.
@@ -1,5 +1,5 @@
1
1
  import { Room } from "livekit-client";
2
- import { ConvaiConfig, ConvaiClientState, ChatMessage, IConvaiClient, AudioControls, VideoControls, ScreenShareControls, DynamicInfo, ContextUpdateOptions, UploadFileOptions, WebSocketSessionFactory, RespondModeUpdateOptions, UpdateSceneMetadataOptions, VisionStatusOptions, VisionTriggerOptions, ConvaiCharacterInstance, UpdateCharacterRosterOptions, CharacterRosterChange } from "./types";
2
+ import { ConvaiConfig, ConvaiClientState, ChatMessage, IConvaiClient, AudioControls, VideoControls, ScreenShareControls, DynamicInfo, ContextUpdateOptions, UploadFileOptions, WebSocketSessionFactory, RespondModeUpdateOptions, UpdateSceneMetadataOptions, VisionStatusOptions, VisionTriggerOptions } from "./types";
3
3
  import { EventEmitter } from "./EventEmitter";
4
4
  import { BlendshapeQueue } from "./BlendshapeQueue";
5
5
  import { MemoryManager } from "./MemoryManager";
@@ -46,7 +46,6 @@ export declare class ConvaiClient extends EventEmitter implements IConvaiClient
46
46
  private _apiKey;
47
47
  private _authToken;
48
48
  private _characterId;
49
- private _speakerId;
50
49
  private _characterSessionId;
51
50
  private _isBotReady;
52
51
  private _participantSid;
@@ -57,11 +56,6 @@ export declare class ConvaiClient extends EventEmitter implements IConvaiClient
57
56
  * so updateEmotion() called before any config is stored is not lost.
58
57
  */
59
58
  private _stateOfMind;
60
- /** Roster state for multi-character rooms. Empty for single-character sessions. */
61
- private _roster;
62
- /** Pending setInteractionTarget/updateCharacterRoster commands, keyed by command_id. */
63
- private _pendingRosterCommands;
64
- private _rosterCommandSeq;
65
59
  private _endUserId;
66
60
  private _endUserMetadata;
67
61
  private _wsSession;
@@ -93,7 +87,6 @@ export declare class ConvaiClient extends EventEmitter implements IConvaiClient
93
87
  get apiKey(): string | null;
94
88
  get authToken(): string | null;
95
89
  get characterId(): string | null;
96
- get speakerId(): string | null;
97
90
  get room(): Room;
98
91
  get chatMessages(): ChatMessage[];
99
92
  get userTranscription(): string;
@@ -224,29 +217,6 @@ export declare class ConvaiClient extends EventEmitter implements IConvaiClient
224
217
  * This is silent: it affects the next response and does not trigger one.
225
218
  */
226
219
  updateEmotion(stateOfMind: string | null): void;
227
- /** Timeout for a roster command to be acknowledged by the server. */
228
- private static readonly ROSTER_COMMAND_TIMEOUT_MS;
229
- /**
230
- * Correlate interaction-target / character-roster-update acks back to the
231
- * promise returned by the method that issued them, and keep roster state and
232
- * the two roster events in sync — including for changes we did not initiate.
233
- */
234
- private _handleRosterServerResponse;
235
- /**
236
- * Publish a roster command and resolve when its ack arrives.
237
- */
238
- private _sendRosterCommand;
239
- /**
240
- * Route subsequent user turns to a different character instance.
241
- *
242
- * Retries once against the server's authoritative epoch if the routing epoch
243
- * was stale, which happens when another participant switched first.
244
- */
245
- setInteractionTarget(membershipId: string): Promise<ConvaiCharacterInstance>;
246
- /**
247
- * Add or remove character instances on a live room, without reconnecting.
248
- */
249
- updateCharacterRoster(options: UpdateCharacterRosterOptions): Promise<CharacterRosterChange>;
250
220
  /**
251
221
  * Send descriptive scene updates. Use when environment description changes
252
222
  * and the bot should know what is visible or nearby. Does not modify action_config.
@@ -1 +1 @@
1
- {"version":3,"file":"ConvaiClient.d.ts","sourceRoot":"","sources":["../../src/core/ConvaiClient.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EAML,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,WAAW,EAEX,aAAa,EACb,aAAa,EACb,aAAa,EACb,mBAAmB,EACnB,WAAW,EACX,oBAAoB,EACpB,iBAAiB,EAIjB,uBAAuB,EACvB,wBAAwB,EAExB,0BAA0B,EAC1B,mBAAmB,EACnB,oBAAoB,EAGpB,uBAAuB,EACvB,4BAA4B,EAC5B,qBAAqB,EAEtB,MAAM,SAAS,CAAC;AAMjB,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AA8BhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,qBAAa,YAAa,SAAQ,YAAa,YAAW,aAAa;IACrE,OAAO,CAAC,KAAK,CAAO;IACpB,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,eAAe,CAAkC;IACzD,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,eAAe,CAAc;IACrC,OAAO,CAAC,cAAc,CAAgB;IACtC,OAAO,CAAC,aAAa,CAA6B;IAClD;;;OAGG;IACH,OAAO,CAAC,YAAY,CAAuB;IAC3C,mFAAmF;IACnF,OAAO,CAAC,OAAO,CAAyB;IACxC,wFAAwF;IACxF,OAAO,CAAC,sBAAsB,CAO1B;IACJ,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,gBAAgB,CAAwC;IAChE,OAAO,CAAC,UAAU,CAAkC;IACpD,OAAO,CAAC,gBAAgB,CAAwC;IAChE,OAAO,CAAC,gBAAgB,CAAiB;IACzC,OAAO,CAAC,gBAAgB,CAAkB;IAG1C,OAAO,CAAC,sBAAsB,CAA8C;IAC5E,OAAO,CAAC,wBAAwB,CAA8C;IAC9E,OAAO,CAAC,iBAAiB,CAAuB;IAChD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAAO;IACpD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,uBAAuB,CAAU;IAEzD;;;;OAIG;IACH,MAAM,CAAC,0BAA0B,CAAC,OAAO,EAAE,uBAAuB,GAAG,IAAI;IAKzE,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,mBAAmB,CAAqB;IAChD,OAAO,CAAC,eAAe,CAAiB;IACxC,OAAO,CAAC,uBAAuB,CAAyB;IAGxD,OAAO,CAAC,sBAAsB,CAAa;IAC3C,OAAO,CAAC,sBAAsB,CAAa;IAG3C,OAAO,CAAC,cAAc,CAA8B;gBAExC,MAAM,CAAC,EAAE,YAAY;IAiEjC,IAAI,KAAK,IAAI,iBAAiB,CAE7B;IAED,IAAI,cAAc,IAAI,OAAO,GAAG,OAAO,GAAG,IAAI,CAE7C;IAED,IAAI,MAAM,IAAI,MAAM,GAAG,IAAI,CAE1B;IAED,IAAI,SAAS,IAAI,MAAM,GAAG,IAAI,CAE7B;IAED,IAAI,WAAW,IAAI,MAAM,GAAG,IAAI,CAE/B;IAED,IAAI,SAAS,IAAI,MAAM,GAAG,IAAI,CAE7B;IAED,IAAI,IAAI,IAAI,IAAI,CAEf;IAED,IAAI,YAAY,IAAI,WAAW,EAAE,CAEhC;IAED,IAAI,iBAAiB,IAAI,MAAM,CAE9B;IAED,IAAI,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAEtC;IAED,IAAI,UAAU,IAAI,OAAO,CAExB;IAED,IAAI,aAAa,IAAI,aAAa,CAEjC;IAED,IAAI,aAAa,IAAI,aAAa,CAEjC;IAED,IAAI,mBAAmB,IAAI,mBAAmB,CAE7C;IAED,IAAI,eAAe,IAAI,eAAe,CAErC;IAED,IAAI,qBAAqB,IAAI,MAAM,CAElC;IAED,IAAI,aAAa,IAAI,aAAa,GAAG,IAAI,CAExC;IAED;;OAEG;IACH,OAAO,CAAC,mBAAmB;IA8L3B;;;;OAIG;IACH,OAAO,CAAC,yBAAyB;IASjC;;OAEG;IACH,OAAO,CAAC,WAAW;IAuBnB;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAkBtB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IASxB;;OAEG;IACG,OAAO,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;YA6brC,0CAA0C;IAgBxD;;;;;OAKG;IACH,OAAO,CAAC,0BAA0B;IAgDlC,OAAO,CAAC,yBAAyB;IAWjC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IA6BjC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAkBxB;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAOhC;;OAEG;IACH,YAAY,IAAI,IAAI;IAOpB;;OAEG;IACH,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAmCvC;;OAEG;IACH,kBAAkB,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI;IA2BvE;;;;OAIG;IACH,OAAO,CAAC,8BAA8B;IAmBtC,OAAO,CAAC,wBAAwB;IAkBhC;;OAEG;IACH,oBAAoB,IAAI,IAAI;IAwB5B;;;;OAIG;IACH,kBAAkB,CAAC,YAAY,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GAAG,IAAI;IAUjE;;OAEG;IACH,iBAAiB,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI;IASjD;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI;IAmClD,YAAY,CAAC,OAAO,GAAE,mBAAwB,GAAG,MAAM,GAAG,IAAI;IAU9D,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,MAAM,GAAG,IAAI;IAkBhE,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,MAAM,GAAG,IAAI;IAYnE;;;OAGG;IACH,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAiB/C,qEAAqE;IACrE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,yBAAyB,CAAS;IAE1D;;;;OAIG;IACH,OAAO,CAAC,2BAA2B;IA6DnC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA4B1B;;;;;OAKG;IACG,oBAAoB,CACxB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,uBAAuB,CAAC;IAkCnC;;OAEG;IACG,qBAAqB,CACzB,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,qBAAqB,CAAC;IAoCjC;;;OAGG;IACH,mBAAmB,CACjB,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,EACnD,OAAO,GAAE,0BAA+B,GACvC,IAAI;IAaP,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,qBAAqB;IAe7B;;;;;OAKG;IACG,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB5E;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAKjC;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAKjC;;;;OAIG;IACH,cAAc,IAAI,IAAI;CAMvB"}
1
+ {"version":3,"file":"ConvaiClient.d.ts","sourceRoot":"","sources":["../../src/core/ConvaiClient.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,7 @@ import { AudioManager } from "./AudioManager";
5
5
  import { VideoManager } from "./VideoManager";
6
6
  import { ScreenShareManager } from "./ScreenShareManager";
7
7
  import { MessageHandler } from "./MessageHandler";
8
- import { CharacterRoster } from "./CharacterRoster";
8
+ import { SDK_VERSION } from "../version";
9
9
  import { EventEmitter } from "./EventEmitter";
10
10
  import { MemoryManager } from "./MemoryManager";
11
11
  import { ConnectionStateHandler } from "./ConnectionStateHandler";
@@ -79,7 +79,6 @@ export class ConvaiClient extends EventEmitter {
79
79
  this._apiKey = null;
80
80
  this._authToken = null;
81
81
  this._characterId = null;
82
- this._speakerId = null;
83
82
  this._characterSessionId = "-1";
84
83
  this._isBotReady = false;
85
84
  this._participantSid = "";
@@ -89,11 +88,6 @@ export class ConvaiClient extends EventEmitter {
89
88
  * so updateEmotion() called before any config is stored is not lost.
90
89
  */
91
90
  this._stateOfMind = null;
92
- /** Roster state for multi-character rooms. Empty for single-character sessions. */
93
- this._roster = new CharacterRoster();
94
- /** Pending setInteractionTarget/updateCharacterRoster commands, keyed by command_id. */
95
- this._pendingRosterCommands = new Map();
96
- this._rosterCommandSeq = 0;
97
91
  this._endUserId = null;
98
92
  this._endUserMetadata = null;
99
93
  this._wsSession = null;
@@ -130,8 +124,6 @@ export class ConvaiClient extends EventEmitter {
130
124
  endUserId: null,
131
125
  endUserMetadata: null,
132
126
  metrics: [],
133
- characters: [],
134
- activeMembershipId: null,
135
127
  disconnectReason: null,
136
128
  };
137
129
  // Default audio settings for optimal interruption handling
@@ -174,9 +166,6 @@ export class ConvaiClient extends EventEmitter {
174
166
  get characterId() {
175
167
  return this._characterId;
176
168
  }
177
- get speakerId() {
178
- return this._speakerId;
179
- }
180
169
  get room() {
181
170
  return this._room;
182
171
  }
@@ -220,15 +209,7 @@ export class ConvaiClient extends EventEmitter {
220
209
  });
221
210
  this._room.on(RoomEvent.ConnectionStateChanged, this._connectionStateHandler.handleConnectionStateChanged.bind(this._connectionStateHandler));
222
211
  // Message handler events
223
- this._messageHandler.on("botReady", (about) => {
224
- // Each character instance sends its own bot-ready. Feed the roster
225
- // before the de-dupe below, which only guards the consumer-facing event.
226
- if (this._roster.applyBotReady(about)) {
227
- this.updateState({
228
- characters: this._roster.characters,
229
- activeMembershipId: this._roster.activeMembershipId,
230
- });
231
- }
212
+ this._messageHandler.on("botReady", () => {
232
213
  // Server may send multiple bot-ready frames (one per client-ready
233
214
  // we retried). Only surface the first to consumers per connect.
234
215
  if (this._isBotReady) {
@@ -348,7 +329,6 @@ export class ConvaiClient extends EventEmitter {
348
329
  this.emit("actionResponse", data);
349
330
  });
350
331
  this._messageHandler.on("serverResponse", (response) => {
351
- this._handleRosterServerResponse(response);
352
332
  this.emit("serverResponse", response);
353
333
  });
354
334
  this._messageHandler.on("interactionCreated", (data) => {
@@ -397,12 +377,8 @@ export class ConvaiClient extends EventEmitter {
397
377
  * For LiveKit: publishes via the data channel.
398
378
  * For WebSocket: sends via PipecatClient.sendClientMessage (wrapped in {t,d} envelope).
399
379
  */
400
- publishMessage(type, data, id) {
401
- // Roster commands are correlated by a top-level `id`, which the server
402
- // echoes back as extras.command_id. interaction-target REJECTS a message
403
- // without it (code "invalid_command") even when the same value is present
404
- // inside `data`, so the envelope field is not optional for those.
405
- const message = id ? { id, type, data } : { type, data };
380
+ publishMessage(type, data) {
381
+ const message = { type, data };
406
382
  if (this._activeTransport === "websocket" && this._wsSession?.isConnected) {
407
383
  this._wsSession.sendMessage(type, data);
408
384
  }
@@ -446,33 +422,15 @@ export class ConvaiClient extends EventEmitter {
446
422
  this._messageHandler.setRtviMessageLogging(this._logRtviMessages);
447
423
  const hasApiKey = Boolean(configWithDefaults.apiKey);
448
424
  const hasAuthToken = Boolean(configWithDefaults.authToken);
449
- const characterList = configWithDefaults.characters ?? [];
450
- const hasCharacterList = characterList.length > 0;
451
- if (!hasApiKey && !hasAuthToken) {
425
+ if ((!hasApiKey && !hasAuthToken) || !configWithDefaults.characterId) {
452
426
  throw new Error("Either apiKey or authToken is required, and characterId is required");
453
427
  }
454
- // Exactly one of characterId / characters — the server takes either shape,
455
- // but silently ignores unknown fields, so catch the ambiguity here.
456
- if (!hasCharacterList && !configWithDefaults.characterId) {
457
- throw new Error("Either apiKey or authToken is required, and characterId is required");
458
- }
459
- if (hasCharacterList && configWithDefaults.characterId) {
460
- throw new Error("Pass either characterId or characters, not both");
461
- }
462
- if (hasCharacterList && characterList.some((c) => !c?.characterId)) {
463
- throw new Error("Every entry in characters requires a characterId");
464
- }
465
428
  this.updateState({ isConnecting: true });
466
429
  try {
467
430
  // Store connection config
468
431
  this._apiKey = configWithDefaults.apiKey ?? null;
469
432
  this._authToken = configWithDefaults.authToken ?? null;
470
- this._characterId =
471
- configWithDefaults.characterId ??
472
- characterList[0]?.characterId ??
473
- null;
474
- this._roster.reset();
475
- // Resolve speaker ID based on endUserId
433
+ this._characterId = configWithDefaults.characterId;
476
434
  // Determine connection type based on enableVideo
477
435
  const connType = configWithDefaults.enableVideo ? "video" : "audio";
478
436
  this._connectionType = connType;
@@ -488,13 +446,7 @@ export class ConvaiClient extends EventEmitter {
488
446
  this._stateOfMind = stateOfMind;
489
447
  const characterSessionIdToSend = configWithDefaults.characterSessionId ?? this._characterSessionId;
490
448
  const requestBody = {
491
- ...(hasCharacterList
492
- ? {
493
- characters: characterList.map((c) => ({
494
- character_id: c.characterId,
495
- })),
496
- }
497
- : { character_id: configWithDefaults.characterId }),
449
+ character_id: configWithDefaults.characterId,
498
450
  ...(stateOfMind ? { state_of_mind: stateOfMind } : {}),
499
451
  ...(configWithDefaults.endUserId && {
500
452
  end_user_id: configWithDefaults.endUserId,
@@ -563,7 +515,7 @@ export class ConvaiClient extends EventEmitter {
563
515
  invocation_metadata: {
564
516
  source: configWithDefaults.invocationMetadata?.source ?? "web_sdk",
565
517
  client_version: configWithDefaults.invocationMetadata?.clientVersion ??
566
- "1.6.0-beta.0",
518
+ SDK_VERSION,
567
519
  ...(configWithDefaults.invocationMetadata?.extraMetadata && {
568
520
  extra_metadata: configWithDefaults.invocationMetadata.extraMetadata,
569
521
  }),
@@ -621,14 +573,6 @@ export class ConvaiClient extends EventEmitter {
621
573
  characterSessionId: connectionData.character_session_id,
622
574
  };
623
575
  }
624
- // Seed the roster before the transport comes up, so the first bot-ready
625
- // and any early roster change already have instances to match against.
626
- if (this._roster.applyConnectResponse(connectionData)) {
627
- this.updateState({
628
- characters: this._roster.characters,
629
- activeMembershipId: this._roster.activeMembershipId,
630
- });
631
- }
632
576
  if (connectionData.end_user_id) {
633
577
  this._endUserId = connectionData.end_user_id;
634
578
  }
@@ -911,7 +855,6 @@ export class ConvaiClient extends EventEmitter {
911
855
  this._apiKey = null;
912
856
  this._authToken = null;
913
857
  this._characterId = null;
914
- this._speakerId = null;
915
858
  this._endUserId = null;
916
859
  this._endUserMetadata = null;
917
860
  this._memoryManager = null; // Clear memory manager on disconnect
@@ -1187,139 +1130,6 @@ export class ConvaiClient extends EventEmitter {
1187
1130
  participant_sid: this._participantSid || this._room.localParticipant?.sid,
1188
1131
  });
1189
1132
  }
1190
- /**
1191
- * Correlate interaction-target / character-roster-update acks back to the
1192
- * promise returned by the method that issued them, and keep roster state and
1193
- * the two roster events in sync — including for changes we did not initiate.
1194
- */
1195
- _handleRosterServerResponse(response) {
1196
- const { event_type: eventType, extras } = response;
1197
- if (eventType !== "interaction-target" &&
1198
- eventType !== "character-roster-update") {
1199
- return;
1200
- }
1201
- // Always adopt the server's epochs, including from errors — a
1202
- // stale_route_epoch rejection carries the authoritative value.
1203
- const commandId = extras?.command_id;
1204
- const pending = commandId
1205
- ? this._pendingRosterCommands.get(commandId)
1206
- : undefined;
1207
- if (response.status === "error") {
1208
- this._roster.adoptEpochs(extras ?? null);
1209
- this.updateState({
1210
- characters: this._roster.characters,
1211
- activeMembershipId: this._roster.activeMembershipId,
1212
- });
1213
- if (pending && commandId) {
1214
- this._pendingRosterCommands.delete(commandId);
1215
- clearTimeout(pending.timer);
1216
- pending.reject(Object.assign(new Error(response.message ?? `${eventType} was rejected by the server`), { code: extras?.code ?? null, extras: extras ?? null }));
1217
- }
1218
- return;
1219
- }
1220
- let result;
1221
- if (eventType === "interaction-target") {
1222
- result = this._roster.applyInteractionTarget(extras ?? null);
1223
- this.updateState({
1224
- characters: this._roster.characters,
1225
- activeMembershipId: this._roster.activeMembershipId,
1226
- });
1227
- if (result)
1228
- this.emit("activeCharacterChange", result);
1229
- }
1230
- else {
1231
- result = this._roster.applyRosterUpdate(extras ?? null);
1232
- this.updateState({
1233
- characters: this._roster.characters,
1234
- activeMembershipId: this._roster.activeMembershipId,
1235
- });
1236
- if (result)
1237
- this.emit("rosterChange", result);
1238
- }
1239
- if (pending && commandId) {
1240
- this._pendingRosterCommands.delete(commandId);
1241
- clearTimeout(pending.timer);
1242
- pending.resolve(result);
1243
- }
1244
- }
1245
- /**
1246
- * Publish a roster command and resolve when its ack arrives.
1247
- */
1248
- _sendRosterCommand(type, build) {
1249
- if (!this.isTransportReady()) {
1250
- return Promise.reject(new Error(`Cannot send ${type}: not connected`));
1251
- }
1252
- if (!this._roster.isMultiCharacter) {
1253
- return Promise.reject(new Error(`Cannot send ${type}: this session was not created with a characters array`));
1254
- }
1255
- const commandId = `${type}-${++this._rosterCommandSeq}`;
1256
- return new Promise((resolve, reject) => {
1257
- const timer = setTimeout(() => {
1258
- this._pendingRosterCommands.delete(commandId);
1259
- reject(new Error(`${type} timed out waiting for a server response`));
1260
- }, ConvaiClient.ROSTER_COMMAND_TIMEOUT_MS);
1261
- this._pendingRosterCommands.set(commandId, { resolve, reject, timer });
1262
- this.publishMessage(type, build(commandId), commandId);
1263
- });
1264
- }
1265
- /**
1266
- * Route subsequent user turns to a different character instance.
1267
- *
1268
- * Retries once against the server's authoritative epoch if the routing epoch
1269
- * was stale, which happens when another participant switched first.
1270
- */
1271
- async setInteractionTarget(membershipId) {
1272
- if (!membershipId) {
1273
- throw new Error("setInteractionTarget requires a membershipId");
1274
- }
1275
- if (this._roster.isMultiCharacter && !this._roster.find(membershipId)) {
1276
- throw new Error(`Unknown membershipId "${membershipId}". Address instances by membershipId, not characterId.`);
1277
- }
1278
- const send = () => this._sendRosterCommand("interaction-target", (commandId) => this._roster.buildInteractionTarget(membershipId, commandId));
1279
- try {
1280
- await send();
1281
- }
1282
- catch (error) {
1283
- const code = error?.code;
1284
- if (code !== "stale_route_epoch")
1285
- throw error;
1286
- // The roster adopted the server's epoch when the error came in, so a
1287
- // single retry is now fenced correctly.
1288
- await send();
1289
- }
1290
- const instance = this._roster.find(membershipId);
1291
- if (!instance) {
1292
- throw new Error(`interaction-target succeeded but membership "${membershipId}" is not in the roster`);
1293
- }
1294
- return instance;
1295
- }
1296
- /**
1297
- * Add or remove character instances on a live room, without reconnecting.
1298
- */
1299
- async updateCharacterRoster(options) {
1300
- const add = options?.add ?? [];
1301
- const remove = options?.remove ?? [];
1302
- if (add.length === 0 && remove.length === 0) {
1303
- throw new Error("updateCharacterRoster requires at least one add or remove");
1304
- }
1305
- if (add.some((c) => !c?.characterId)) {
1306
- throw new Error("Every entry in add requires a characterId");
1307
- }
1308
- // The server rejects removing the active instance without a replacement
1309
- // (`replacement_target_required`), and rejects one that is not ready yet
1310
- // (`replacement_target_unavailable`). Choose a ready survivor by default.
1311
- const active = this._roster.activeMembershipId;
1312
- const effective = !options.replacementTarget && active && remove.includes(active)
1313
- ? { ...options, replacementTarget: this._roster.pickReplacement(remove) }
1314
- : options;
1315
- const result = (await this._sendRosterCommand("character-roster-update", (commandId) => this._roster.buildRosterUpdate(effective, commandId)));
1316
- // A success ack that moved nothing still resolves; report the roster as-is.
1317
- return (result ?? {
1318
- added: [],
1319
- removed: [],
1320
- characters: this._roster.characters,
1321
- });
1322
- }
1323
1133
  /**
1324
1134
  * Send descriptive scene updates. Use when environment description changes
1325
1135
  * and the bot should know what is visible or nearby. Does not modify action_config.
@@ -1405,6 +1215,4 @@ export class ConvaiClient extends EventEmitter {
1405
1215
  }
1406
1216
  ConvaiClient.CLIENT_READY_RETRY_MS = 500;
1407
1217
  ConvaiClient.CLIENT_READY_TIMEOUT_MS = 45000;
1408
- /** Timeout for a roster command to be acknowledged by the server. */
1409
- ConvaiClient.ROSTER_COMMAND_TIMEOUT_MS = 10000;
1410
1218
  //# sourceMappingURL=ConvaiClient.js.map