@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 +25 -0
- package/dist/core/CharacterVersionManager.d.ts +100 -0
- package/dist/core/CharacterVersionManager.d.ts.map +1 -0
- package/dist/core/CharacterVersionManager.js +227 -0
- package/dist/core/CharacterVersionManager.js.map +1 -0
- package/dist/core/ConvaiClient.d.ts +15 -0
- package/dist/core/ConvaiClient.d.ts.map +1 -1
- package/dist/core/ConvaiClient.js +60 -3
- package/dist/core/ConvaiClient.js.map +1 -1
- package/dist/core/characterReference.d.ts +40 -0
- package/dist/core/characterReference.d.ts.map +1 -0
- package/dist/core/characterReference.js +72 -0
- package/dist/core/characterReference.js.map +1 -0
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +3 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/types.d.ts +255 -2
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/react/hooks/useConvaiClient.d.ts.map +1 -1
- package/dist/react/hooks/useConvaiClient.js +7 -2
- package/dist/react/hooks/useConvaiClient.js.map +1 -1
- package/dist/vanilla/index.d.ts +1 -0
- package/dist/vanilla/index.d.ts.map +1 -1
- package/dist/vanilla/index.js +1 -0
- package/dist/vanilla/index.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
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":"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","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":"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,cAAc,EACd,0BAA0B,EAC3B,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;
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|