@convai/web-sdk 1.8.0-beta.4 → 1.8.0-beta.5

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
@@ -114,6 +114,7 @@ Full documentation is at **<a href="https://docs.convai.com/api-docs/plugins-and
114
114
  | <a href="https://docs.convai.com/api-docs/plugins-and-integrations/web-plugins/convai-web-sdk/auth-tokens" target="_blank" rel="noopener noreferrer">Auth Tokens</a> | Server-side token exchange for production |
115
115
  | <a href="https://docs.convai.com/api-docs/plugins-and-integrations/web-plugins/convai-web-sdk/websocket-transport-layer" target="_blank" rel="noopener noreferrer">WebSocket Transport</a> | Alternative transport for WebRTC-constrained environments |
116
116
  | <a href="https://docs.convai.com/api-docs/plugins-and-integrations/web-plugins/convai-web-sdk" target="_blank" rel="noopener noreferrer">SSE Transport</a> | Text-only interaction transport; the one that runs under Node |
117
+ | [Character Versioning](docs/convai_character_versioning.md) | Connect to a draft, latest, or tagged version; list, compare, release and promote versions |
117
118
 
118
119
  ---
119
120
 
@@ -181,6 +182,30 @@ Full guide: [SSE Interaction Transport](docs/convai_sse_transport.md).
181
182
 
182
183
  ---
183
184
 
185
+ ## Character versioning (beta)
186
+
187
+ Connect to a character's editable draft, its promoted latest release, or an immutable tag, and
188
+ manage those versions from the same client:
189
+
190
+ ```ts
191
+ const client = new ConvaiClient({
192
+ apiKey: "...",
193
+ characterId: "...",
194
+ characterVersion: "draft", // or "latest", "1.2" — omit for the effective latest
195
+ });
196
+
197
+ const versions = client.characterVersions!;
198
+ const { has_unpublished_changes } = await versions.list();
199
+ if (has_unpublished_changes) await versions.create("1.1", { makeLatest: true });
200
+ await client.connect();
201
+ ```
202
+
203
+ Explicit selectors are resolved by the runtime through the Character REST platform; staging has
204
+ this today and production returns `503` for explicit selectors until it is promoted there.
205
+ Full guide: [Character Versioning](docs/convai_character_versioning.md).
206
+
207
+ ---
208
+
184
209
  ## Vision dynamic context beta
185
210
 
186
211
  Vision dynamic context is the default WebRTC/LiveKit vision path when `enableVideo: true`. Camera, screen, canvas, and custom video tracks can feed unified vision context; set `visionInputConfig.enabled: false` only when you need to keep the video channel while opting out.
@@ -0,0 +1,100 @@
1
+ import type { CharacterDraftBootstrapResult, CharacterVersionInfo, CharacterVersionList, CharacterVersionManagerOptions, CharacterVersionRawDiff, CharacterVersionSemanticDiff, CreateCharacterVersionOptions, DiscardCharacterDraftResult, ForkCharacterVersionResult, ResolveCharacterVersionOptions, ResolvedCharacterVersion, RevertCharacterChangeOptions, RevertCharacterChangeResult } from "./types.js";
2
+ import { type CharacterVersionSelector } from "./characterReference.js";
3
+ export declare const DEFAULT_CHARACTER_API_URL = "https://api2.convai.com";
4
+ /**
5
+ * Error raised when the Character REST platform answers with a non-2xx
6
+ * status. `status` carries the HTTP code; `detail` carries the parsed body
7
+ * (`{ detail: string }` for most failures, a validation list for 422).
8
+ */
9
+ export declare class CharacterApiError extends Error {
10
+ readonly status: number;
11
+ readonly detail: unknown;
12
+ constructor(message: string, status: number, detail: unknown);
13
+ }
14
+ /**
15
+ * Authoring client for character versions.
16
+ *
17
+ * Every character has an editable **draft** and, once released, a set of
18
+ * immutable **tagged versions** (`1.0`, `1.1`, …). `latest` is a movable
19
+ * pointer that the runtime follows when a client connects without a
20
+ * selector. The lifecycle is:
21
+ *
22
+ * 1. edit the draft (Playground, `/character/update`, MCP);
23
+ * 2. {@link diff} the draft against `latest` to review the change;
24
+ * 3. {@link create} a tag from the draft, optionally making it latest;
25
+ * 4. {@link promote} an older tag to roll back, or {@link discardDraft} to
26
+ * throw unreleased edits away.
27
+ *
28
+ * Connect to any of these with `characterVersion` in `ConvaiConfig`.
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * const versions = new CharacterVersionManager({
33
+ * apiKey: 'YOUR_API_KEY',
34
+ * characterId: 'YOUR_CHARACTER_ID',
35
+ * });
36
+ * const { has_unpublished_changes } = await versions.list();
37
+ * if (has_unpublished_changes) {
38
+ * await versions.create('1.1', { makeLatest: true });
39
+ * }
40
+ * ```
41
+ */
42
+ export declare class CharacterVersionManager {
43
+ private readonly apiKey;
44
+ private readonly personalAccessToken;
45
+ private readonly baseUrl;
46
+ private readonly workspaceId;
47
+ readonly characterId: string;
48
+ constructor(options: CharacterVersionManagerOptions);
49
+ /** List released tags plus the current latest and draft revisions. */
50
+ list(): Promise<CharacterVersionList>;
51
+ /**
52
+ * Resolve a reference to the configuration snapshot the runtime would run.
53
+ * Omit `version` to resolve the effective latest, or pass `draft`,
54
+ * `latest`, or a tag.
55
+ */
56
+ resolve(version?: CharacterVersionSelector | null, options?: ResolveCharacterVersionOptions): Promise<ResolvedCharacterVersion>;
57
+ /**
58
+ * Give a character that predates versioning an editable draft. Safe to call
59
+ * repeatedly — `created` is false when a draft already existed.
60
+ */
61
+ bootstrap(): Promise<CharacterDraftBootstrapResult>;
62
+ /**
63
+ * Compare two references. Each side is `draft`, `latest`, or a tag.
64
+ * The raw view lists JSON paths; the semantic view groups them into
65
+ * labelled changes that {@link revert} can undo one at a time.
66
+ */
67
+ diff(from: string, to: string, options?: {
68
+ view?: "raw";
69
+ }): Promise<CharacterVersionRawDiff>;
70
+ diff(from: string, to: string, options: {
71
+ view: "semantic";
72
+ }): Promise<CharacterVersionSemanticDiff>;
73
+ /**
74
+ * Release the current draft as an immutable tagged version.
75
+ * @param version - New tag, `major.minor` or `major.minor.patch`
76
+ */
77
+ create(version: string, options?: CreateCharacterVersionOptions): Promise<CharacterVersionInfo>;
78
+ /** Point `latest` at an already released tag — the way to roll back. */
79
+ promote(version: string): Promise<CharacterVersionInfo>;
80
+ /**
81
+ * Discard every saved draft change and restore the draft from its released
82
+ * parent. Pass the draft revision you last saw so a concurrent edit is
83
+ * refused instead of silently thrown away.
84
+ */
85
+ discardDraft(expectedDraftRevisionId: string): Promise<DiscardCharacterDraftResult>;
86
+ /** Undo one semantic change in the draft, identified by a semantic diff's `change_id`. */
87
+ revert(options: RevertCharacterChangeOptions): Promise<RevertCharacterChangeResult>;
88
+ /** Mark a tag deprecated, or restore it with `deprecated: false`. Deprecated tags stay connectable. */
89
+ deprecate(version: string, deprecated?: boolean): Promise<CharacterVersionInfo>;
90
+ /**
91
+ * Replace the draft with the contents of a released tag, to branch new work
92
+ * from an older version. `expectedDraftRevisionId` guards against clobbering
93
+ * a draft someone else just changed.
94
+ */
95
+ fork(version: string, expectedDraftRevisionId?: string): Promise<ForkCharacterVersionResult>;
96
+ private assertSelector;
97
+ private assertTag;
98
+ private request;
99
+ }
100
+ //# sourceMappingURL=CharacterVersionManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CharacterVersionManager.d.ts","sourceRoot":"","sources":["../../src/core/CharacterVersionManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,6BAA6B,EAG7B,oBAAoB,EACpB,oBAAoB,EACpB,8BAA8B,EAC9B,uBAAuB,EACvB,4BAA4B,EAC5B,6BAA6B,EAC7B,2BAA2B,EAC3B,0BAA0B,EAC1B,8BAA8B,EAC9B,wBAAwB,EACxB,4BAA4B,EAC5B,2BAA2B,EAC5B,MAAM,SAAS,CAAC;AACjB,OAAO,EAGL,KAAK,wBAAwB,EAC9B,MAAM,sBAAsB,CAAC;AAE9B,eAAO,MAAM,yBAAyB,4BAA4B,CAAC;AAEnE;;;;GAIG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;gBAEb,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;CAM7D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,uBAAuB;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAgB;IACpD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAgB;IAC5C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;gBAEjB,OAAO,EAAE,8BAA8B;IAgBnD,sEAAsE;IAChE,IAAI,IAAI,OAAO,CAAC,oBAAoB,CAAC;IAI3C;;;;OAIG;IACG,OAAO,CACX,OAAO,CAAC,EAAE,wBAAwB,GAAG,IAAI,EACzC,OAAO,GAAE,8BAAmC,GAC3C,OAAO,CAAC,wBAAwB,CAAC;IAUpC;;;OAGG;IACG,SAAS,IAAI,OAAO,CAAC,6BAA6B,CAAC;IAIzD;;;;OAIG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,KAAK,CAAA;KAAE,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAC5F,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,IAAI,EAAE,UAAU,CAAA;KAAE,GAAG,OAAO,CAAC,4BAA4B,CAAC;IAWpG;;;OAGG;IACG,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,6BAAkC,GAAG,OAAO,CAAC,oBAAoB,CAAC;IASzG,wEAAwE;IAClE,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAM7D;;;;OAIG;IACG,YAAY,CAAC,uBAAuB,EAAE,MAAM,GAAG,OAAO,CAAC,2BAA2B,CAAC;IASzF,0FAA0F;IACpF,MAAM,CAAC,OAAO,EAAE,4BAA4B,GAAG,OAAO,CAAC,2BAA2B,CAAC;IAczF,uGAAuG;IACjG,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,UAAO,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAMlF;;;;OAIG;IACG,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,uBAAuB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,0BAA0B,CAAC;IASlG,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,SAAS;YASH,OAAO;CA2CtB"}
@@ -0,0 +1,227 @@
1
+ import { isCharacterVersionSelector, parseCharacterReference, } from "./characterReference.js";
2
+ export const DEFAULT_CHARACTER_API_URL = "https://api2.convai.com";
3
+ /**
4
+ * Error raised when the Character REST platform answers with a non-2xx
5
+ * status. `status` carries the HTTP code; `detail` carries the parsed body
6
+ * (`{ detail: string }` for most failures, a validation list for 422).
7
+ */
8
+ export class CharacterApiError extends Error {
9
+ constructor(message, status, detail) {
10
+ super(message);
11
+ this.name = "CharacterApiError";
12
+ this.status = status;
13
+ this.detail = detail;
14
+ }
15
+ }
16
+ /**
17
+ * Authoring client for character versions.
18
+ *
19
+ * Every character has an editable **draft** and, once released, a set of
20
+ * immutable **tagged versions** (`1.0`, `1.1`, …). `latest` is a movable
21
+ * pointer that the runtime follows when a client connects without a
22
+ * selector. The lifecycle is:
23
+ *
24
+ * 1. edit the draft (Playground, `/character/update`, MCP);
25
+ * 2. {@link diff} the draft against `latest` to review the change;
26
+ * 3. {@link create} a tag from the draft, optionally making it latest;
27
+ * 4. {@link promote} an older tag to roll back, or {@link discardDraft} to
28
+ * throw unreleased edits away.
29
+ *
30
+ * Connect to any of these with `characterVersion` in `ConvaiConfig`.
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * const versions = new CharacterVersionManager({
35
+ * apiKey: 'YOUR_API_KEY',
36
+ * characterId: 'YOUR_CHARACTER_ID',
37
+ * });
38
+ * const { has_unpublished_changes } = await versions.list();
39
+ * if (has_unpublished_changes) {
40
+ * await versions.create('1.1', { makeLatest: true });
41
+ * }
42
+ * ```
43
+ */
44
+ export class CharacterVersionManager {
45
+ constructor(options) {
46
+ const { characterId, apiKey, personalAccessToken, baseUrl, workspaceId } = options;
47
+ if (!characterId) {
48
+ throw new Error("Character ID is required");
49
+ }
50
+ if (!apiKey && !personalAccessToken) {
51
+ throw new Error("Either apiKey or personalAccessToken is required");
52
+ }
53
+ // Accept a suffixed reference but talk to the API about the bare character.
54
+ this.characterId = parseCharacterReference(characterId)?.characterId ?? characterId;
55
+ this.apiKey = apiKey ?? null;
56
+ this.personalAccessToken = personalAccessToken ?? null;
57
+ this.baseUrl = (baseUrl || DEFAULT_CHARACTER_API_URL).replace(/\/$/, "");
58
+ this.workspaceId = workspaceId ?? null;
59
+ }
60
+ /** List released tags plus the current latest and draft revisions. */
61
+ async list() {
62
+ return this.request("GET", "/character/versions/list");
63
+ }
64
+ /**
65
+ * Resolve a reference to the configuration snapshot the runtime would run.
66
+ * Omit `version` to resolve the effective latest, or pass `draft`,
67
+ * `latest`, or a tag.
68
+ */
69
+ async resolve(version, options = {}) {
70
+ const reference = version ? `${this.characterId}-${this.assertSelector(version)}` : this.characterId;
71
+ return this.request("GET", "/character/versions/resolve", {
72
+ query: {
73
+ character_id: reference,
74
+ ...(options.includeRuntimeSettings ? { include_runtime_settings: "true" } : {}),
75
+ },
76
+ });
77
+ }
78
+ /**
79
+ * Give a character that predates versioning an editable draft. Safe to call
80
+ * repeatedly — `created` is false when a draft already existed.
81
+ */
82
+ async bootstrap() {
83
+ return this.request("POST", "/character/versions/bootstrap");
84
+ }
85
+ async diff(from, to, options = {}) {
86
+ return this.request("GET", "/character/versions/diff", {
87
+ query: {
88
+ from: this.assertSelector(from),
89
+ to: this.assertSelector(to),
90
+ ...(options.view ? { view: options.view } : {}),
91
+ },
92
+ });
93
+ }
94
+ /**
95
+ * Release the current draft as an immutable tagged version.
96
+ * @param version - New tag, `major.minor` or `major.minor.patch`
97
+ */
98
+ async create(version, options = {}) {
99
+ return this.request("POST", "/character/versions/create", {
100
+ body: {
101
+ version: this.assertTag(version),
102
+ ...(options.makeLatest !== undefined ? { make_latest: options.makeLatest } : {}),
103
+ },
104
+ });
105
+ }
106
+ /** Point `latest` at an already released tag — the way to roll back. */
107
+ async promote(version) {
108
+ return this.request("POST", "/character/versions/promote", {
109
+ body: { version: this.assertTag(version) },
110
+ });
111
+ }
112
+ /**
113
+ * Discard every saved draft change and restore the draft from its released
114
+ * parent. Pass the draft revision you last saw so a concurrent edit is
115
+ * refused instead of silently thrown away.
116
+ */
117
+ async discardDraft(expectedDraftRevisionId) {
118
+ if (!expectedDraftRevisionId) {
119
+ throw new Error("expectedDraftRevisionId is required");
120
+ }
121
+ return this.request("POST", "/character/versions/discard-draft", {
122
+ body: { expected_draft_revision_id: expectedDraftRevisionId },
123
+ });
124
+ }
125
+ /** Undo one semantic change in the draft, identified by a semantic diff's `change_id`. */
126
+ async revert(options) {
127
+ const { from, changeId, expectedDraftRevisionId } = options;
128
+ if (!changeId || !expectedDraftRevisionId) {
129
+ throw new Error("changeId and expectedDraftRevisionId are required");
130
+ }
131
+ return this.request("POST", "/character/versions/revert", {
132
+ body: {
133
+ from: this.assertSelector(from),
134
+ change_id: changeId,
135
+ expected_draft_revision_id: expectedDraftRevisionId,
136
+ },
137
+ });
138
+ }
139
+ /** Mark a tag deprecated, or restore it with `deprecated: false`. Deprecated tags stay connectable. */
140
+ async deprecate(version, deprecated = true) {
141
+ return this.request("POST", "/character/versions/deprecate", {
142
+ body: { version: this.assertTag(version), deprecated },
143
+ });
144
+ }
145
+ /**
146
+ * Replace the draft with the contents of a released tag, to branch new work
147
+ * from an older version. `expectedDraftRevisionId` guards against clobbering
148
+ * a draft someone else just changed.
149
+ */
150
+ async fork(version, expectedDraftRevisionId) {
151
+ return this.request("POST", "/character/versions/fork", {
152
+ body: {
153
+ version: this.assertTag(version),
154
+ ...(expectedDraftRevisionId ? { expected_draft_revision_id: expectedDraftRevisionId } : {}),
155
+ },
156
+ });
157
+ }
158
+ assertSelector(value) {
159
+ if (!isCharacterVersionSelector(value)) {
160
+ throw new Error(`Expected "draft", "latest", or a major.minor[.patch] tag; received ${JSON.stringify(value)}`);
161
+ }
162
+ return value;
163
+ }
164
+ assertTag(value) {
165
+ if (!isCharacterVersionSelector(value) || value === "draft" || value === "latest") {
166
+ throw new Error(`Expected a major.minor[.patch] version tag; received ${JSON.stringify(value)}`);
167
+ }
168
+ return value;
169
+ }
170
+ async request(method, path, options = {}) {
171
+ const params = new URLSearchParams({
172
+ character_id: this.characterId,
173
+ ...(this.workspaceId ? { workspace_id: this.workspaceId } : {}),
174
+ ...options.query,
175
+ });
176
+ const url = `${this.baseUrl}${path}?${params.toString()}`;
177
+ const headers = { Accept: "application/json" };
178
+ if (this.personalAccessToken) {
179
+ headers["Authorization"] = `Bearer ${this.personalAccessToken}`;
180
+ }
181
+ else if (this.apiKey) {
182
+ headers["CONVAI-API-KEY"] = this.apiKey;
183
+ }
184
+ if (options.body !== undefined) {
185
+ headers["Content-Type"] = "application/json";
186
+ }
187
+ const response = await fetch(url, {
188
+ method,
189
+ headers,
190
+ ...(options.body !== undefined ? { body: JSON.stringify(options.body) } : {}),
191
+ });
192
+ const text = await response.text();
193
+ let data = null;
194
+ if (text) {
195
+ try {
196
+ data = JSON.parse(text);
197
+ }
198
+ catch {
199
+ data = text;
200
+ }
201
+ }
202
+ if (!response.ok) {
203
+ throw new CharacterApiError(describeFailure(response.status, data), response.status, data);
204
+ }
205
+ return data;
206
+ }
207
+ }
208
+ function describeFailure(status, data) {
209
+ const body = (data ?? null);
210
+ const detail = body?.detail;
211
+ if (typeof detail === "string")
212
+ return detail;
213
+ // Access denials use `{ error, message }` rather than `{ detail }`.
214
+ if (typeof body?.message === "string")
215
+ return body.message;
216
+ if (Array.isArray(detail)) {
217
+ const parts = detail
218
+ .map((e) => [e.loc?.join("."), e.msg].filter(Boolean).join(": "))
219
+ .filter(Boolean);
220
+ if (parts.length)
221
+ return parts.join("; ");
222
+ }
223
+ if (typeof data === "string" && data)
224
+ return `HTTP ${status}: ${data}`;
225
+ return `HTTP ${status}`;
226
+ }
227
+ //# sourceMappingURL=CharacterVersionManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CharacterVersionManager.js","sourceRoot":"","sources":["../../src/core/CharacterVersionManager.ts"],"names":[],"mappings":"AAiBA,OAAO,EACL,0BAA0B,EAC1B,uBAAuB,GAExB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,CAAC,MAAM,yBAAyB,GAAG,yBAAyB,CAAC;AAEnE;;;;GAIG;AACH,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAI1C,YAAY,OAAe,EAAE,MAAc,EAAE,MAAe;QAC1D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,OAAO,uBAAuB;IAOlC,YAAY,OAAuC;QACjD,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,mBAAmB,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;QACnF,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC9C,CAAC;QACD,IAAI,CAAC,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACtE,CAAC;QACD,4EAA4E;QAC5E,IAAI,CAAC,WAAW,GAAG,uBAAuB,CAAC,WAAW,CAAC,EAAE,WAAW,IAAI,WAAW,CAAC;QACpF,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,IAAI,CAAC;QAC7B,IAAI,CAAC,mBAAmB,GAAG,mBAAmB,IAAI,IAAI,CAAC;QACvD,IAAI,CAAC,OAAO,GAAG,CAAC,OAAO,IAAI,yBAAyB,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACzE,IAAI,CAAC,WAAW,GAAG,WAAW,IAAI,IAAI,CAAC;IACzC,CAAC;IAED,sEAAsE;IACtE,KAAK,CAAC,IAAI;QACR,OAAO,IAAI,CAAC,OAAO,CAAuB,KAAK,EAAE,0BAA0B,CAAC,CAAC;IAC/E,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,OAAO,CACX,OAAyC,EACzC,UAA0C,EAAE;QAE5C,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC;QACrG,OAAO,IAAI,CAAC,OAAO,CAA2B,KAAK,EAAE,6BAA6B,EAAE;YAClF,KAAK,EAAE;gBACL,YAAY,EAAE,SAAS;gBACvB,GAAG,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC,CAAC,EAAE,wBAAwB,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAChF;SACF,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,SAAS;QACb,OAAO,IAAI,CAAC,OAAO,CAAgC,MAAM,EAAE,+BAA+B,CAAC,CAAC;IAC9F,CAAC;IASD,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,EAAU,EAAE,UAAuC,EAAE;QAC5E,OAAO,IAAI,CAAC,OAAO,CAAuB,KAAK,EAAE,0BAA0B,EAAE;YAC3E,KAAK,EAAE;gBACL,IAAI,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;gBAC/B,EAAE,EAAE,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;gBAC3B,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAChD;SACF,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,MAAM,CAAC,OAAe,EAAE,UAAyC,EAAE;QACvE,OAAO,IAAI,CAAC,OAAO,CAAuB,MAAM,EAAE,4BAA4B,EAAE;YAC9E,IAAI,EAAE;gBACJ,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;gBAChC,GAAG,CAAC,OAAO,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACjF;SACF,CAAC,CAAC;IACL,CAAC;IAED,wEAAwE;IACxE,KAAK,CAAC,OAAO,CAAC,OAAe;QAC3B,OAAO,IAAI,CAAC,OAAO,CAAuB,MAAM,EAAE,6BAA6B,EAAE;YAC/E,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE;SAC3C,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,YAAY,CAAC,uBAA+B;QAChD,IAAI,CAAC,uBAAuB,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACzD,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAA8B,MAAM,EAAE,mCAAmC,EAAE;YAC5F,IAAI,EAAE,EAAE,0BAA0B,EAAE,uBAAuB,EAAE;SAC9D,CAAC,CAAC;IACL,CAAC;IAED,0FAA0F;IAC1F,KAAK,CAAC,MAAM,CAAC,OAAqC;QAChD,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,uBAAuB,EAAE,GAAG,OAAO,CAAC;QAC5D,IAAI,CAAC,QAAQ,IAAI,CAAC,uBAAuB,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACvE,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAA8B,MAAM,EAAE,4BAA4B,EAAE;YACrF,IAAI,EAAE;gBACJ,IAAI,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;gBAC/B,SAAS,EAAE,QAAQ;gBACnB,0BAA0B,EAAE,uBAAuB;aACpD;SACF,CAAC,CAAC;IACL,CAAC;IAED,uGAAuG;IACvG,KAAK,CAAC,SAAS,CAAC,OAAe,EAAE,UAAU,GAAG,IAAI;QAChD,OAAO,IAAI,CAAC,OAAO,CAAuB,MAAM,EAAE,+BAA+B,EAAE;YACjF,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE;SACvD,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,IAAI,CAAC,OAAe,EAAE,uBAAgC;QAC1D,OAAO,IAAI,CAAC,OAAO,CAA6B,MAAM,EAAE,0BAA0B,EAAE;YAClF,IAAI,EAAE;gBACJ,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;gBAChC,GAAG,CAAC,uBAAuB,CAAC,CAAC,CAAC,EAAE,0BAA0B,EAAE,uBAAuB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC5F;SACF,CAAC,CAAC;IACL,CAAC;IAEO,cAAc,CAAC,KAAa;QAClC,IAAI,CAAC,0BAA0B,CAAC,KAAK,CAAC,EAAE,CAAC;YACvC,MAAM,IAAI,KAAK,CACb,sEAAsE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAC9F,CAAC;QACJ,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,SAAS,CAAC,KAAa;QAC7B,IAAI,CAAC,0BAA0B,CAAC,KAAK,CAAC,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;YAClF,MAAM,IAAI,KAAK,CACb,wDAAwD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAChF,CAAC;QACJ,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,KAAK,CAAC,OAAO,CACnB,MAAsB,EACtB,IAAY,EACZ,UAA8D,EAAE;QAEhE,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;YACjC,YAAY,EAAE,IAAI,CAAC,WAAW;YAC9B,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/D,GAAG,OAAO,CAAC,KAAK;SACjB,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,IAAI,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;QAE1D,MAAM,OAAO,GAA2B,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;QACvE,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC7B,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAClE,CAAC;aAAM,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACvB,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1C,CAAC;QACD,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC/B,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;QAC/C,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,MAAM;YACN,OAAO;YACP,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9E,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,IAAI,IAAI,GAAY,IAAI,CAAC;QACzB,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC;gBACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC1B,CAAC;YAAC,MAAM,CAAC;gBACP,IAAI,GAAG,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,iBAAiB,CAAC,eAAe,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC7F,CAAC;QACD,OAAO,IAAS,CAAC;IACnB,CAAC;CACF;AAED,SAAS,eAAe,CAAC,MAAc,EAAE,IAAa;IACpD,MAAM,IAAI,GAAG,CAAC,IAAI,IAAI,IAAI,CAAoE,CAAC;IAC/F,MAAM,MAAM,GAAG,IAAI,EAAE,MAAM,CAAC;IAC5B,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC;IAC9C,oEAAoE;IACpE,IAAI,OAAO,IAAI,EAAE,OAAO,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,OAAO,CAAC;IAC3D,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,MAAM;aACjB,GAAG,CAAC,CAAC,CAAoC,EAAE,EAAE,CAC5C,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CACrD;aACA,MAAM,CAAC,OAAO,CAAC,CAAC;QACnB,IAAI,KAAK,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5C,CAAC;IACD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI;QAAE,OAAO,QAAQ,MAAM,KAAK,IAAI,EAAE,CAAC;IACvE,OAAO,QAAQ,MAAM,EAAE,CAAC;AAC1B,CAAC","sourcesContent":["import type {\n CharacterDraftBootstrapResult,\n CharacterVersionDiff,\n CharacterVersionDiffOptions,\n CharacterVersionInfo,\n CharacterVersionList,\n CharacterVersionManagerOptions,\n CharacterVersionRawDiff,\n CharacterVersionSemanticDiff,\n CreateCharacterVersionOptions,\n DiscardCharacterDraftResult,\n ForkCharacterVersionResult,\n ResolveCharacterVersionOptions,\n ResolvedCharacterVersion,\n RevertCharacterChangeOptions,\n RevertCharacterChangeResult,\n} from \"./types\";\nimport {\n isCharacterVersionSelector,\n parseCharacterReference,\n type CharacterVersionSelector,\n} from \"./characterReference\";\n\nexport const DEFAULT_CHARACTER_API_URL = \"https://api2.convai.com\";\n\n/**\n * Error raised when the Character REST platform answers with a non-2xx\n * status. `status` carries the HTTP code; `detail` carries the parsed body\n * (`{ detail: string }` for most failures, a validation list for 422).\n */\nexport class CharacterApiError extends Error {\n readonly status: number;\n readonly detail: unknown;\n\n constructor(message: string, status: number, detail: unknown) {\n super(message);\n this.name = \"CharacterApiError\";\n this.status = status;\n this.detail = detail;\n }\n}\n\n/**\n * Authoring client for character versions.\n *\n * Every character has an editable **draft** and, once released, a set of\n * immutable **tagged versions** (`1.0`, `1.1`, …). `latest` is a movable\n * pointer that the runtime follows when a client connects without a\n * selector. The lifecycle is:\n *\n * 1. edit the draft (Playground, `/character/update`, MCP);\n * 2. {@link diff} the draft against `latest` to review the change;\n * 3. {@link create} a tag from the draft, optionally making it latest;\n * 4. {@link promote} an older tag to roll back, or {@link discardDraft} to\n * throw unreleased edits away.\n *\n * Connect to any of these with `characterVersion` in `ConvaiConfig`.\n *\n * @example\n * ```typescript\n * const versions = new CharacterVersionManager({\n * apiKey: 'YOUR_API_KEY',\n * characterId: 'YOUR_CHARACTER_ID',\n * });\n * const { has_unpublished_changes } = await versions.list();\n * if (has_unpublished_changes) {\n * await versions.create('1.1', { makeLatest: true });\n * }\n * ```\n */\nexport class CharacterVersionManager {\n private readonly apiKey: string | null;\n private readonly personalAccessToken: string | null;\n private readonly baseUrl: string;\n private readonly workspaceId: string | null;\n readonly characterId: string;\n\n constructor(options: CharacterVersionManagerOptions) {\n const { characterId, apiKey, personalAccessToken, baseUrl, workspaceId } = options;\n if (!characterId) {\n throw new Error(\"Character ID is required\");\n }\n if (!apiKey && !personalAccessToken) {\n throw new Error(\"Either apiKey or personalAccessToken is required\");\n }\n // Accept a suffixed reference but talk to the API about the bare character.\n this.characterId = parseCharacterReference(characterId)?.characterId ?? characterId;\n this.apiKey = apiKey ?? null;\n this.personalAccessToken = personalAccessToken ?? null;\n this.baseUrl = (baseUrl || DEFAULT_CHARACTER_API_URL).replace(/\\/$/, \"\");\n this.workspaceId = workspaceId ?? null;\n }\n\n /** List released tags plus the current latest and draft revisions. */\n async list(): Promise<CharacterVersionList> {\n return this.request<CharacterVersionList>(\"GET\", \"/character/versions/list\");\n }\n\n /**\n * Resolve a reference to the configuration snapshot the runtime would run.\n * Omit `version` to resolve the effective latest, or pass `draft`,\n * `latest`, or a tag.\n */\n async resolve(\n version?: CharacterVersionSelector | null,\n options: ResolveCharacterVersionOptions = {},\n ): Promise<ResolvedCharacterVersion> {\n const reference = version ? `${this.characterId}-${this.assertSelector(version)}` : this.characterId;\n return this.request<ResolvedCharacterVersion>(\"GET\", \"/character/versions/resolve\", {\n query: {\n character_id: reference,\n ...(options.includeRuntimeSettings ? { include_runtime_settings: \"true\" } : {}),\n },\n });\n }\n\n /**\n * Give a character that predates versioning an editable draft. Safe to call\n * repeatedly — `created` is false when a draft already existed.\n */\n async bootstrap(): Promise<CharacterDraftBootstrapResult> {\n return this.request<CharacterDraftBootstrapResult>(\"POST\", \"/character/versions/bootstrap\");\n }\n\n /**\n * Compare two references. Each side is `draft`, `latest`, or a tag.\n * The raw view lists JSON paths; the semantic view groups them into\n * labelled changes that {@link revert} can undo one at a time.\n */\n diff(from: string, to: string, options?: { view?: \"raw\" }): Promise<CharacterVersionRawDiff>;\n diff(from: string, to: string, options: { view: \"semantic\" }): Promise<CharacterVersionSemanticDiff>;\n async diff(from: string, to: string, options: CharacterVersionDiffOptions = {}): Promise<CharacterVersionDiff> {\n return this.request<CharacterVersionDiff>(\"GET\", \"/character/versions/diff\", {\n query: {\n from: this.assertSelector(from),\n to: this.assertSelector(to),\n ...(options.view ? { view: options.view } : {}),\n },\n });\n }\n\n /**\n * Release the current draft as an immutable tagged version.\n * @param version - New tag, `major.minor` or `major.minor.patch`\n */\n async create(version: string, options: CreateCharacterVersionOptions = {}): Promise<CharacterVersionInfo> {\n return this.request<CharacterVersionInfo>(\"POST\", \"/character/versions/create\", {\n body: {\n version: this.assertTag(version),\n ...(options.makeLatest !== undefined ? { make_latest: options.makeLatest } : {}),\n },\n });\n }\n\n /** Point `latest` at an already released tag — the way to roll back. */\n async promote(version: string): Promise<CharacterVersionInfo> {\n return this.request<CharacterVersionInfo>(\"POST\", \"/character/versions/promote\", {\n body: { version: this.assertTag(version) },\n });\n }\n\n /**\n * Discard every saved draft change and restore the draft from its released\n * parent. Pass the draft revision you last saw so a concurrent edit is\n * refused instead of silently thrown away.\n */\n async discardDraft(expectedDraftRevisionId: string): Promise<DiscardCharacterDraftResult> {\n if (!expectedDraftRevisionId) {\n throw new Error(\"expectedDraftRevisionId is required\");\n }\n return this.request<DiscardCharacterDraftResult>(\"POST\", \"/character/versions/discard-draft\", {\n body: { expected_draft_revision_id: expectedDraftRevisionId },\n });\n }\n\n /** Undo one semantic change in the draft, identified by a semantic diff's `change_id`. */\n async revert(options: RevertCharacterChangeOptions): Promise<RevertCharacterChangeResult> {\n const { from, changeId, expectedDraftRevisionId } = options;\n if (!changeId || !expectedDraftRevisionId) {\n throw new Error(\"changeId and expectedDraftRevisionId are required\");\n }\n return this.request<RevertCharacterChangeResult>(\"POST\", \"/character/versions/revert\", {\n body: {\n from: this.assertSelector(from),\n change_id: changeId,\n expected_draft_revision_id: expectedDraftRevisionId,\n },\n });\n }\n\n /** Mark a tag deprecated, or restore it with `deprecated: false`. Deprecated tags stay connectable. */\n async deprecate(version: string, deprecated = true): Promise<CharacterVersionInfo> {\n return this.request<CharacterVersionInfo>(\"POST\", \"/character/versions/deprecate\", {\n body: { version: this.assertTag(version), deprecated },\n });\n }\n\n /**\n * Replace the draft with the contents of a released tag, to branch new work\n * from an older version. `expectedDraftRevisionId` guards against clobbering\n * a draft someone else just changed.\n */\n async fork(version: string, expectedDraftRevisionId?: string): Promise<ForkCharacterVersionResult> {\n return this.request<ForkCharacterVersionResult>(\"POST\", \"/character/versions/fork\", {\n body: {\n version: this.assertTag(version),\n ...(expectedDraftRevisionId ? { expected_draft_revision_id: expectedDraftRevisionId } : {}),\n },\n });\n }\n\n private assertSelector(value: string): string {\n if (!isCharacterVersionSelector(value)) {\n throw new Error(\n `Expected \"draft\", \"latest\", or a major.minor[.patch] tag; received ${JSON.stringify(value)}`,\n );\n }\n return value;\n }\n\n private assertTag(value: string): string {\n if (!isCharacterVersionSelector(value) || value === \"draft\" || value === \"latest\") {\n throw new Error(\n `Expected a major.minor[.patch] version tag; received ${JSON.stringify(value)}`,\n );\n }\n return value;\n }\n\n private async request<T>(\n method: \"GET\" | \"POST\",\n path: string,\n options: { query?: Record<string, string>; body?: unknown } = {},\n ): Promise<T> {\n const params = new URLSearchParams({\n character_id: this.characterId,\n ...(this.workspaceId ? { workspace_id: this.workspaceId } : {}),\n ...options.query,\n });\n const url = `${this.baseUrl}${path}?${params.toString()}`;\n\n const headers: Record<string, string> = { Accept: \"application/json\" };\n if (this.personalAccessToken) {\n headers[\"Authorization\"] = `Bearer ${this.personalAccessToken}`;\n } else if (this.apiKey) {\n headers[\"CONVAI-API-KEY\"] = this.apiKey;\n }\n if (options.body !== undefined) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n const response = await fetch(url, {\n method,\n headers,\n ...(options.body !== undefined ? { body: JSON.stringify(options.body) } : {}),\n });\n\n const text = await response.text();\n let data: unknown = null;\n if (text) {\n try {\n data = JSON.parse(text);\n } catch {\n data = text;\n }\n }\n\n if (!response.ok) {\n throw new CharacterApiError(describeFailure(response.status, data), response.status, data);\n }\n return data as T;\n }\n}\n\nfunction describeFailure(status: number, data: unknown): string {\n const body = (data ?? null) as { detail?: unknown; message?: unknown; error?: unknown } | null;\n const detail = body?.detail;\n if (typeof detail === \"string\") return detail;\n // Access denials use `{ error, message }` rather than `{ detail }`.\n if (typeof body?.message === \"string\") return body.message;\n if (Array.isArray(detail)) {\n const parts = detail\n .map((e: { loc?: unknown[]; msg?: string }) =>\n [e.loc?.join(\".\"), e.msg].filter(Boolean).join(\": \"),\n )\n .filter(Boolean);\n if (parts.length) return parts.join(\"; \");\n }\n if (typeof data === \"string\" && data) return `HTTP ${status}: ${data}`;\n return `HTTP ${status}`;\n}\n"]}
@@ -3,6 +3,8 @@ import { ConvaiConfig, ConvaiClientState, ChatMessage, IConvaiClient, AudioContr
3
3
  import { EventEmitter } from "./EventEmitter.js";
4
4
  import { BlendshapeQueue } from "./BlendshapeQueue.js";
5
5
  import { MemoryManager } from "./MemoryManager.js";
6
+ import { CharacterVersionManager } from "./CharacterVersionManager.js";
7
+ import { type CharacterVersionSelector } from "./characterReference.js";
6
8
  /**
7
9
  * Main Convai client class for managing AI voice assistant connections
8
10
  * Provides complete interface for connecting to Convai's voice assistants,
@@ -46,6 +48,10 @@ export declare class ConvaiClient extends EventEmitter implements IConvaiClient
46
48
  private _apiKey;
47
49
  private _authToken;
48
50
  private _characterId;
51
+ private _characterVersion;
52
+ private _characterReference;
53
+ private _characterVersionManager;
54
+ private _characterVersionManagerKey;
49
55
  private _characterSessionId;
50
56
  private _isBotReady;
51
57
  private _participantSid;
@@ -88,6 +94,15 @@ export declare class ConvaiClient extends EventEmitter implements IConvaiClient
88
94
  get apiKey(): string | null;
89
95
  get authToken(): string | null;
90
96
  get characterId(): string | null;
97
+ get characterVersion(): CharacterVersionSelector | null;
98
+ get characterReference(): string | null;
99
+ /**
100
+ * Character version manager for the configured character. Built from the
101
+ * live connection when there is one, otherwise from the stored config, so
102
+ * versions can be listed and released before connecting. Null without an
103
+ * API key (the Character REST platform does not accept realtime auth tokens).
104
+ */
105
+ get characterVersions(): CharacterVersionManager | null;
91
106
  get room(): Room;
92
107
  get chatMessages(): ChatMessage[];
93
108
  get userTranscription(): string;
@@ -1 +1 @@
1
- {"version":3,"file":"ConvaiClient.d.ts","sourceRoot":"","sources":["../../src/core/ConvaiClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ConvaiClient.d.ts","sourceRoot":"","sources":["../../src/core/ConvaiClient.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,8 @@ import { MessageHandler } from "./MessageHandler.js";
8
8
  import { SDK_VERSION } from "../version.js";
9
9
  import { EventEmitter } from "./EventEmitter.js";
10
10
  import { MemoryManager } from "./MemoryManager.js";
11
+ import { CharacterVersionManager } from "./CharacterVersionManager.js";
12
+ import { resolveCharacterReference, } from "./characterReference.js";
11
13
  import { ConnectionStateHandler } from "./ConnectionStateHandler.js";
12
14
  import { buildActionConnectConfig, buildBlendshapeConnectConfig, buildEmotionConnectConfig, } from "./connectRequest.js";
13
15
  import { shouldPreemptForContextUpdateResponse, shouldPreemptForExplicitRespondMode, } from "./contextUpdateRequest.js";
@@ -81,6 +83,10 @@ export class ConvaiClient extends EventEmitter {
81
83
  this._apiKey = null;
82
84
  this._authToken = null;
83
85
  this._characterId = null;
86
+ this._characterVersion = null;
87
+ this._characterReference = null;
88
+ this._characterVersionManager = null;
89
+ this._characterVersionManagerKey = null;
84
90
  this._characterSessionId = "-1";
85
91
  this._isBotReady = false;
86
92
  this._participantSid = "";
@@ -169,6 +175,42 @@ export class ConvaiClient extends EventEmitter {
169
175
  get characterId() {
170
176
  return this._characterId;
171
177
  }
178
+ get characterVersion() {
179
+ return this._characterVersion;
180
+ }
181
+ get characterReference() {
182
+ return this._characterReference;
183
+ }
184
+ /**
185
+ * Character version manager for the configured character. Built from the
186
+ * live connection when there is one, otherwise from the stored config, so
187
+ * versions can be listed and released before connecting. Null without an
188
+ * API key (the Character REST platform does not accept realtime auth tokens).
189
+ */
190
+ get characterVersions() {
191
+ const apiKey = this._apiKey ?? this._storedConfig?.apiKey ?? null;
192
+ const rawCharacterId = this._characterId ?? this._storedConfig?.characterId ?? null;
193
+ if (!apiKey || !rawCharacterId)
194
+ return null;
195
+ let characterId = rawCharacterId;
196
+ try {
197
+ characterId = resolveCharacterReference(rawCharacterId).characterId;
198
+ }
199
+ catch {
200
+ // A malformed id is reported by connect(); use it verbatim here.
201
+ }
202
+ const baseUrl = this._storedConfig?.characterApiUrl ?? undefined;
203
+ const key = `${apiKey}\u0000${characterId}\u0000${baseUrl ?? ""}`;
204
+ if (this._characterVersionManagerKey !== key) {
205
+ this._characterVersionManager = new CharacterVersionManager({
206
+ apiKey,
207
+ characterId,
208
+ baseUrl,
209
+ });
210
+ this._characterVersionManagerKey = key;
211
+ }
212
+ return this._characterVersionManager;
213
+ }
172
214
  get room() {
173
215
  return this._room;
174
216
  }
@@ -430,6 +472,8 @@ export class ConvaiClient extends EventEmitter {
430
472
  this._apiKey = configWithDefaults.apiKey ?? null;
431
473
  this._authToken = configWithDefaults.authToken ?? null;
432
474
  this._characterId = configWithDefaults.characterId;
475
+ this._characterVersion = configWithDefaults.characterVersion ?? null;
476
+ this._characterReference = configWithDefaults.characterReference;
433
477
  // Determine connection type based on enableVideo
434
478
  const connType = configWithDefaults.enableVideo ? "video" : "audio";
435
479
  this._connectionType = connType;
@@ -453,7 +497,7 @@ export class ConvaiClient extends EventEmitter {
453
497
  this._sseSession = new SSESession({
454
498
  interactionApiUrl: configWithDefaults.interactionApiUrl,
455
499
  authorization: configWithDefaults.authToken ?? configWithDefaults.apiKey,
456
- characterId: configWithDefaults.characterId,
500
+ characterId: configWithDefaults.characterReference,
457
501
  getCharacterSessionId: () => this._characterSessionId,
458
502
  takeStateOfMind: () => {
459
503
  const stateOfMind = this._stateOfMind;
@@ -496,7 +540,7 @@ export class ConvaiClient extends EventEmitter {
496
540
  // Prepare request body with required parameters
497
541
  const characterSessionIdToSend = configWithDefaults.characterSessionId ?? this._characterSessionId;
498
542
  const requestBody = {
499
- character_id: configWithDefaults.characterId,
543
+ character_id: configWithDefaults.characterReference,
500
544
  ...(stateOfMind ? { state_of_mind: stateOfMind } : {}),
501
545
  ...(configWithDefaults.endUserId && {
502
546
  end_user_id: configWithDefaults.endUserId,
@@ -686,7 +730,16 @@ export class ConvaiClient extends EventEmitter {
686
730
  if (missingCredential || !configWithDefaults.characterId) {
687
731
  throw new Error("Either apiKey or authToken is required, and characterId is required");
688
732
  }
689
- return configWithDefaults;
733
+ // Split the character id from its version selector. The bare UUID names
734
+ // the character everywhere inside the SDK (memory, character info); the
735
+ // joined reference is what the runtime receives.
736
+ const reference = resolveCharacterReference(configWithDefaults.characterId, configWithDefaults.characterVersion);
737
+ return {
738
+ ...configWithDefaults,
739
+ characterId: reference.characterId,
740
+ characterVersion: reference.version,
741
+ characterReference: reference.reference,
742
+ };
690
743
  }
691
744
  /**
692
745
  * Consume a /connect response and bring up the transport.
@@ -718,6 +771,8 @@ export class ConvaiClient extends EventEmitter {
718
771
  this._apiKey = configWithDefaults.apiKey ?? null;
719
772
  this._authToken = configWithDefaults.authToken ?? null;
720
773
  this._characterId = configWithDefaults.characterId;
774
+ this._characterVersion = configWithDefaults.characterVersion ?? null;
775
+ this._characterReference = configWithDefaults.characterReference;
721
776
  const connType = configWithDefaults.enableVideo ? "video" : "audio";
722
777
  this._connectionType = connType;
723
778
  const transportType = configWithDefaults.transport ?? "livekit";
@@ -1016,6 +1071,8 @@ export class ConvaiClient extends EventEmitter {
1016
1071
  this._apiKey = null;
1017
1072
  this._authToken = null;
1018
1073
  this._characterId = null;
1074
+ this._characterVersion = null;
1075
+ this._characterReference = null;
1019
1076
  this._endUserId = null;
1020
1077
  this._endUserMetadata = null;
1021
1078
  this._memoryManager = null; // Clear memory manager on disconnect