@rtsdk/topia 0.19.4 → 0.19.6
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 +61 -43
- package/dist/index.cjs +78 -6
- package/dist/index.d.ts +111 -34
- package/dist/index.js +78 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -240,44 +240,70 @@ export const getDroppedAssetAndVisitor = async (req: Request, res: Response) =>
|
|
|
240
240
|
};
|
|
241
241
|
```
|
|
242
242
|
|
|
243
|
-
<br/><br/>
|
|
244
|
-
|
|
245
243
|
## Data Objects
|
|
246
244
|
|
|
247
245
|
Data Objects can be used to store information such as game state, configurations, themes, and analytics.
|
|
248
246
|
There are three types of Data Objects:
|
|
249
247
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
248
|
+
### World:
|
|
249
|
+
|
|
250
|
+
The data object attached to the world will store information for every instance of the app in a given world by keyAssetId or sceneDropId and will persist even if a specific instance is removed from world. Data stored in the World data object should be minimal to avoid running into limits.
|
|
251
|
+
|
|
252
|
+
#### Example - Update two specific data points:
|
|
253
|
+
|
|
254
|
+
```ts
|
|
255
|
+
await world.updateDataObject({
|
|
256
|
+
[sceneDropId]: { keyAssetId: droppedAsset.id, themeId: "custom", totalInteractions: 1 },
|
|
257
|
+
});
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
#### Example - Increment a specific value within the data object by 1:
|
|
261
|
+
|
|
262
|
+
```ts
|
|
263
|
+
await world.incrementDataObjectValue([`${sceneDropId}.totalInteractions`], 1);
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Dropped Asset:
|
|
267
|
+
|
|
268
|
+
The Dropped Asset data object should only store what is unique to the specific instance of the app in the world such as game state. If the Dropped Asset is deleted, the data object would be lost as well so be sure to only store information here the doesn't need to persist!
|
|
269
|
+
|
|
270
|
+
#### Example - Initialize data object with default data and keyAssetId:
|
|
271
|
+
|
|
272
|
+
```ts
|
|
273
|
+
await droppedAsset.setDataObject(
|
|
274
|
+
{
|
|
275
|
+
...defaultGameData,
|
|
276
|
+
keyAssetId: droppedAsset.id,
|
|
277
|
+
},
|
|
278
|
+
{ lock: { lockId, releaseLock: true } },
|
|
279
|
+
);
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
#### Example - Update lastInteraction date and playerCount:
|
|
283
|
+
|
|
284
|
+
```ts
|
|
285
|
+
await droppedAsset.updateDataObject({ lastInteraction: new Date(), playerCount: playerCount + 1 });
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### User:
|
|
289
|
+
|
|
290
|
+
The data object attached to the visitor should store information related specifically to the visitor i.e. progress. For tracking across multiple world/instances use `${urlSlug}_${sceneDropId}` as a unique key.
|
|
291
|
+
|
|
292
|
+
#### Example - Initialize data object with default data and keyAssetId:
|
|
293
|
+
|
|
294
|
+
```ts
|
|
295
|
+
await visitor.setDataObject(
|
|
296
|
+
{
|
|
297
|
+
[`${urlSlug}_${sceneDropId}`]: {
|
|
298
|
+
currentStreak: 0,
|
|
299
|
+
lastCollectedDate: null,
|
|
300
|
+
longestStreak: 0,
|
|
301
|
+
totalCollected: 0,
|
|
302
|
+
},
|
|
303
|
+
},
|
|
304
|
+
{ lock: { lockId, releaseLock: true } },
|
|
305
|
+
);
|
|
306
|
+
```
|
|
281
307
|
|
|
282
308
|
### Data Object Locking
|
|
283
309
|
|
|
@@ -324,7 +350,7 @@ await world.setDataObject({ hello: "world" }, { analytics: [{ analyticName: "res
|
|
|
324
350
|
|
|
325
351
|
await world.updateDataObject({}, { analytics: [ {analyticName: "matches", uniqueKey: `${playerOneProfileId}-${playerTwoProfileId}`, urlSlug }], });
|
|
326
352
|
|
|
327
|
-
await world.incrementDataObjectValue(
|
|
353
|
+
await world.incrementDataObjectValue(`${sceneDropId}.completions`, 1, { analytics: [{ analyticName:"completions", incrementBy: 2, profileId, uniqueKey: profileId, urlSlug }] });
|
|
328
354
|
```
|
|
329
355
|
|
|
330
356
|
Examples leveraging Visitor data objects calls:
|
|
@@ -345,7 +371,7 @@ await visitor.incrementDataObjectValue(`completions`, 1, {
|
|
|
345
371
|
});
|
|
346
372
|
```
|
|
347
373
|
|
|
348
|
-
Note: passing an empty object does NOT impact the data objects themselves but rather allows you to track custom analytics
|
|
374
|
+
Note: passing an empty object does NOT impact the data objects themselves but rather allows you to track custom analytics across all instances of your application with a given Public Key.
|
|
349
375
|
|
|
350
376
|
<br>
|
|
351
377
|
|
|
@@ -353,26 +379,18 @@ Note: passing an empty object does NOT impact the data objects themselves but ra
|
|
|
353
379
|
|
|
354
380
|
<hr/>
|
|
355
381
|
|
|
356
|
-
<br>
|
|
357
|
-
|
|
358
382
|
## Get Started
|
|
359
383
|
|
|
360
384
|
Run `gh repo clone metaversecloud-com/mc-sdk-js`
|
|
361
385
|
|
|
362
|
-
<br>
|
|
363
|
-
|
|
364
386
|
## Issues
|
|
365
387
|
|
|
366
388
|
We've added an Issue template to help standardize Issues and ensure they have enough detail for a developer to start work and help prevent contributors from forgetting to add an important piece of information.
|
|
367
389
|
|
|
368
|
-
<br>
|
|
369
|
-
|
|
370
390
|
## Pull Requests
|
|
371
391
|
|
|
372
392
|
We've added a Pull Request template to help make it easier for developers to clarify what the proposed changes will do. This helps facilitate clear communication between all contributors of the SDK and ensures that we are all on the same page!
|
|
373
393
|
|
|
374
|
-
<br>
|
|
375
|
-
|
|
376
394
|
## Documentation
|
|
377
395
|
|
|
378
396
|
### Styles
|
package/dist/index.cjs
CHANGED
|
@@ -39727,11 +39727,6 @@ class SDKController {
|
|
|
39727
39727
|
*
|
|
39728
39728
|
* @keywords error, exception, handler, debugging, api error, http error
|
|
39729
39729
|
*
|
|
39730
|
-
* @param error - The error object from the failed operation (AxiosError, Error, or unknown)
|
|
39731
|
-
* @param message - Optional custom error message (defaults to generic message)
|
|
39732
|
-
* @param params - Optional parameters that were passed to the failed method
|
|
39733
|
-
* @param sdkMethod - Optional name of the SDK method that failed (e.g., "World.fetchDetails")
|
|
39734
|
-
*
|
|
39735
39730
|
* @returns {object} Standardized error object with properties: data, message, method, params, sdkMethod, stack, status, success, url
|
|
39736
39731
|
*/
|
|
39737
39732
|
errorHandler({ error, message = "Something went wrong. Please try again or contact support.", params = {}, sdkMethod, }) {
|
|
@@ -43670,7 +43665,13 @@ class Visitor extends User {
|
|
|
43670
43665
|
createNpc(userInventoryItemId, options) {
|
|
43671
43666
|
return __awaiter(this, void 0, void 0, function* () {
|
|
43672
43667
|
try {
|
|
43673
|
-
const response = yield this.topiaPublicApi().post(`/world/${this.urlSlug}/visitors/${this.id}/create-npc`, {
|
|
43668
|
+
const response = yield this.topiaPublicApi().post(`/world/${this.urlSlug}/visitors/${this.id}/create-npc`, {
|
|
43669
|
+
userInventoryItemId,
|
|
43670
|
+
showNameplate: options === null || options === void 0 ? void 0 : options.showNameplate,
|
|
43671
|
+
stationary: options === null || options === void 0 ? void 0 : options.stationary,
|
|
43672
|
+
replace: options === null || options === void 0 ? void 0 : options.replace,
|
|
43673
|
+
spawnEffect: options === null || options === void 0 ? void 0 : options.spawnEffect,
|
|
43674
|
+
}, this.requestOptions);
|
|
43674
43675
|
return new Visitor(this.topia, response.data.player.playerId, this.urlSlug, {
|
|
43675
43676
|
attributes: response.data,
|
|
43676
43677
|
credentials: this.credentials,
|
|
@@ -43715,6 +43716,77 @@ class Visitor extends User {
|
|
|
43715
43716
|
}
|
|
43716
43717
|
});
|
|
43717
43718
|
}
|
|
43719
|
+
/**
|
|
43720
|
+
* Start an AI voice session for this visitor's NPC.
|
|
43721
|
+
*
|
|
43722
|
+
* @remarks
|
|
43723
|
+
* Establishes a real-time voice connection between the visitor and an AI backend
|
|
43724
|
+
* (currently OpenAI Realtime API) through the NPC. The NPC must already be spawned
|
|
43725
|
+
* via `createNpc()` before calling this method.
|
|
43726
|
+
*
|
|
43727
|
+
* The voice session occupies a video slot in the visitor's peer video grid, showing
|
|
43728
|
+
* the NPC's avatar image. Audio streams bidirectionally between the visitor's microphone
|
|
43729
|
+
* and the AI model. Only the NPC's owner hears the AI audio.
|
|
43730
|
+
*
|
|
43731
|
+
* Topia automatically prepends non-removable child safety guardrails to the instructions.
|
|
43732
|
+
* Only one voice session is allowed per visitor per world at a time.
|
|
43733
|
+
*
|
|
43734
|
+
* @keywords voice, npc, ai, chat, audio, realtime, session, start, speech
|
|
43735
|
+
*
|
|
43736
|
+
* @category NPCs
|
|
43737
|
+
*
|
|
43738
|
+
* @param config - Voice session configuration including ephemeral key and AI instructions
|
|
43739
|
+
*
|
|
43740
|
+
* @example
|
|
43741
|
+
* ```ts
|
|
43742
|
+
* const ephemeralKey = await generateOpenAIEphemeralKey();
|
|
43743
|
+
*
|
|
43744
|
+
* await visitor.startNpcVoiceSession({
|
|
43745
|
+
* ephemeralKey,
|
|
43746
|
+
* voice: "alloy",
|
|
43747
|
+
* instructions: "You are a friendly science tutor helping with photosynthesis.",
|
|
43748
|
+
* model: "gpt-4o-realtime-preview",
|
|
43749
|
+
* });
|
|
43750
|
+
* ```
|
|
43751
|
+
*
|
|
43752
|
+
* @returns {Promise<void | ResponseType>} Returns `{ success: true }` or an error.
|
|
43753
|
+
*/
|
|
43754
|
+
startNpcVoiceSession(config) {
|
|
43755
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
43756
|
+
try {
|
|
43757
|
+
const response = yield this.topiaPublicApi().put(`/world/${this.urlSlug}/visitors/${this.id}/start-npc-voice-session`, { voiceConfig: config }, this.requestOptions);
|
|
43758
|
+
return response.data;
|
|
43759
|
+
}
|
|
43760
|
+
catch (error) {
|
|
43761
|
+
throw this.errorHandler({ error, params: config, sdkMethod: "Visitor.startNpcVoiceSession" });
|
|
43762
|
+
}
|
|
43763
|
+
});
|
|
43764
|
+
}
|
|
43765
|
+
/**
|
|
43766
|
+
* Stop the active AI voice session for this visitor's NPC.
|
|
43767
|
+
*
|
|
43768
|
+
* @keywords voice, npc, ai, chat, audio, realtime, session, stop, end
|
|
43769
|
+
*
|
|
43770
|
+
* @category NPCs
|
|
43771
|
+
*
|
|
43772
|
+
* @example
|
|
43773
|
+
* ```ts
|
|
43774
|
+
* await visitor.stopNpcVoiceSession();
|
|
43775
|
+
* ```
|
|
43776
|
+
*
|
|
43777
|
+
* @returns {Promise<void | ResponseType>} Returns `{ success: true }` or an error.
|
|
43778
|
+
*/
|
|
43779
|
+
stopNpcVoiceSession() {
|
|
43780
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
43781
|
+
try {
|
|
43782
|
+
const response = yield this.topiaPublicApi().put(`/world/${this.urlSlug}/visitors/${this.id}/stop-npc-voice-session`, {}, this.requestOptions);
|
|
43783
|
+
return response.data;
|
|
43784
|
+
}
|
|
43785
|
+
catch (error) {
|
|
43786
|
+
throw this.errorHandler({ error, sdkMethod: "Visitor.stopNpcVoiceSession" });
|
|
43787
|
+
}
|
|
43788
|
+
});
|
|
43789
|
+
}
|
|
43718
43790
|
/**
|
|
43719
43791
|
* Retrieves all inventory items owned by this visitor and app's key.
|
|
43720
43792
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -74,7 +74,7 @@ type DroppedAssetLinkType = {
|
|
|
74
74
|
linkSamlQueryParams?: string;
|
|
75
75
|
};
|
|
76
76
|
|
|
77
|
-
type InteractiveCredentials = {
|
|
77
|
+
type InteractiveCredentials$1 = {
|
|
78
78
|
apiKey?: string;
|
|
79
79
|
assetId?: string;
|
|
80
80
|
interactiveNonce?: string;
|
|
@@ -88,22 +88,22 @@ type InteractiveCredentials = {
|
|
|
88
88
|
|
|
89
89
|
type AssetOptions = {
|
|
90
90
|
attributes?: AssetInterface | undefined;
|
|
91
|
-
credentials?: InteractiveCredentials | undefined;
|
|
91
|
+
credentials?: InteractiveCredentials$1 | undefined;
|
|
92
92
|
};
|
|
93
93
|
type DroppedAssetOptions = {
|
|
94
94
|
attributes?: DroppedAssetInterface | undefined;
|
|
95
|
-
credentials?: InteractiveCredentials | undefined;
|
|
95
|
+
credentials?: InteractiveCredentials$1 | undefined;
|
|
96
96
|
};
|
|
97
97
|
type UserOptions = {
|
|
98
|
-
credentials?: InteractiveCredentials | undefined;
|
|
98
|
+
credentials?: InteractiveCredentials$1 | undefined;
|
|
99
99
|
};
|
|
100
100
|
type VisitorOptions = {
|
|
101
101
|
attributes?: VisitorInterface | undefined;
|
|
102
|
-
credentials?: InteractiveCredentials | undefined;
|
|
102
|
+
credentials?: InteractiveCredentials$1 | undefined;
|
|
103
103
|
};
|
|
104
104
|
type WorldOptions = {
|
|
105
105
|
attributes?: WorldDetailsInterface | undefined;
|
|
106
|
-
credentials?: InteractiveCredentials | undefined;
|
|
106
|
+
credentials?: InteractiveCredentials$1 | undefined;
|
|
107
107
|
};
|
|
108
108
|
|
|
109
109
|
type ResponseType = {
|
|
@@ -2160,9 +2160,7 @@ declare class Visitor extends User implements VisitorInterface {
|
|
|
2160
2160
|
*
|
|
2161
2161
|
* @returns {Promise<Visitor>} Returns a Visitor object representing the created NPC. The NPC will automatically follow the visitor.
|
|
2162
2162
|
*/
|
|
2163
|
-
createNpc(userInventoryItemId: string, options?:
|
|
2164
|
-
showNameplate?: boolean;
|
|
2165
|
-
}): Promise<Visitor>;
|
|
2163
|
+
createNpc(userInventoryItemId: string, options?: CreateNpcOptions): Promise<Visitor>;
|
|
2166
2164
|
/**
|
|
2167
2165
|
* Deletes the NPC (Non-Player Character) this app has assigned to this visitor.
|
|
2168
2166
|
*
|
|
@@ -2188,6 +2186,57 @@ declare class Visitor extends User implements VisitorInterface {
|
|
|
2188
2186
|
* @returns {Promise<void>} Returns nothing if successful.
|
|
2189
2187
|
*/
|
|
2190
2188
|
deleteNpc(): Promise<void>;
|
|
2189
|
+
/**
|
|
2190
|
+
* Start an AI voice session for this visitor's NPC.
|
|
2191
|
+
*
|
|
2192
|
+
* @remarks
|
|
2193
|
+
* Establishes a real-time voice connection between the visitor and an AI backend
|
|
2194
|
+
* (currently OpenAI Realtime API) through the NPC. The NPC must already be spawned
|
|
2195
|
+
* via `createNpc()` before calling this method.
|
|
2196
|
+
*
|
|
2197
|
+
* The voice session occupies a video slot in the visitor's peer video grid, showing
|
|
2198
|
+
* the NPC's avatar image. Audio streams bidirectionally between the visitor's microphone
|
|
2199
|
+
* and the AI model. Only the NPC's owner hears the AI audio.
|
|
2200
|
+
*
|
|
2201
|
+
* Topia automatically prepends non-removable child safety guardrails to the instructions.
|
|
2202
|
+
* Only one voice session is allowed per visitor per world at a time.
|
|
2203
|
+
*
|
|
2204
|
+
* @keywords voice, npc, ai, chat, audio, realtime, session, start, speech
|
|
2205
|
+
*
|
|
2206
|
+
* @category NPCs
|
|
2207
|
+
*
|
|
2208
|
+
* @param config - Voice session configuration including ephemeral key and AI instructions
|
|
2209
|
+
*
|
|
2210
|
+
* @example
|
|
2211
|
+
* ```ts
|
|
2212
|
+
* const ephemeralKey = await generateOpenAIEphemeralKey();
|
|
2213
|
+
*
|
|
2214
|
+
* await visitor.startNpcVoiceSession({
|
|
2215
|
+
* ephemeralKey,
|
|
2216
|
+
* voice: "alloy",
|
|
2217
|
+
* instructions: "You are a friendly science tutor helping with photosynthesis.",
|
|
2218
|
+
* model: "gpt-4o-realtime-preview",
|
|
2219
|
+
* });
|
|
2220
|
+
* ```
|
|
2221
|
+
*
|
|
2222
|
+
* @returns {Promise<void | ResponseType>} Returns `{ success: true }` or an error.
|
|
2223
|
+
*/
|
|
2224
|
+
startNpcVoiceSession(config: NpcVoiceConfigInterface): Promise<void | ResponseType>;
|
|
2225
|
+
/**
|
|
2226
|
+
* Stop the active AI voice session for this visitor's NPC.
|
|
2227
|
+
*
|
|
2228
|
+
* @keywords voice, npc, ai, chat, audio, realtime, session, stop, end
|
|
2229
|
+
*
|
|
2230
|
+
* @category NPCs
|
|
2231
|
+
*
|
|
2232
|
+
* @example
|
|
2233
|
+
* ```ts
|
|
2234
|
+
* await visitor.stopNpcVoiceSession();
|
|
2235
|
+
* ```
|
|
2236
|
+
*
|
|
2237
|
+
* @returns {Promise<void | ResponseType>} Returns `{ success: true }` or an error.
|
|
2238
|
+
*/
|
|
2239
|
+
stopNpcVoiceSession(): Promise<void | ResponseType>;
|
|
2191
2240
|
/**
|
|
2192
2241
|
* Retrieves all inventory items owned by this visitor and app's key.
|
|
2193
2242
|
*
|
|
@@ -2294,7 +2343,7 @@ declare enum WorldActivityType {
|
|
|
2294
2343
|
}
|
|
2295
2344
|
|
|
2296
2345
|
interface SDKInterface {
|
|
2297
|
-
credentials?: InteractiveCredentials;
|
|
2346
|
+
credentials?: InteractiveCredentials$1;
|
|
2298
2347
|
jwt?: string;
|
|
2299
2348
|
requestOptions: object;
|
|
2300
2349
|
topia: Topia;
|
|
@@ -2331,7 +2380,7 @@ interface AssetInterface extends SDKInterface {
|
|
|
2331
2380
|
}
|
|
2332
2381
|
type AssetOptionalInterface = {
|
|
2333
2382
|
attributes?: AssetInterface | object;
|
|
2334
|
-
credentials?: InteractiveCredentials;
|
|
2383
|
+
credentials?: InteractiveCredentials$1;
|
|
2335
2384
|
};
|
|
2336
2385
|
|
|
2337
2386
|
interface DroppedAssetInterface extends AssetInterface {
|
|
@@ -2453,7 +2502,7 @@ interface DroppedAssetOptionalInterface {
|
|
|
2453
2502
|
text?: string;
|
|
2454
2503
|
urlSlug?: string;
|
|
2455
2504
|
};
|
|
2456
|
-
credentials?: InteractiveCredentials | object;
|
|
2505
|
+
credentials?: InteractiveCredentials$1 | object;
|
|
2457
2506
|
}
|
|
2458
2507
|
interface UpdateBroadcastInterface {
|
|
2459
2508
|
assetBroadcast?: boolean;
|
|
@@ -2545,7 +2594,7 @@ interface EcosystemInterface extends SDKInterface {
|
|
|
2545
2594
|
incrementDataObjectValue(path: string, amount: number, options: object): Promise<void | ResponseType>;
|
|
2546
2595
|
}
|
|
2547
2596
|
interface EcosystemOptionalInterface {
|
|
2548
|
-
credentials?: InteractiveCredentials;
|
|
2597
|
+
credentials?: InteractiveCredentials$1;
|
|
2549
2598
|
}
|
|
2550
2599
|
|
|
2551
2600
|
interface SceneInterface {
|
|
@@ -2573,7 +2622,7 @@ interface SceneInterface {
|
|
|
2573
2622
|
}
|
|
2574
2623
|
type SceneOptionalInterface = {
|
|
2575
2624
|
attributes?: SceneInterface | object;
|
|
2576
|
-
credentials?: InteractiveCredentials;
|
|
2625
|
+
credentials?: InteractiveCredentials$1;
|
|
2577
2626
|
};
|
|
2578
2627
|
|
|
2579
2628
|
interface FireToastInterface {
|
|
@@ -2621,7 +2670,7 @@ interface UserInterface {
|
|
|
2621
2670
|
dataObject?: object | null;
|
|
2622
2671
|
}
|
|
2623
2672
|
interface UserOptionalInterface {
|
|
2624
|
-
credentials?: InteractiveCredentials;
|
|
2673
|
+
credentials?: InteractiveCredentials$1;
|
|
2625
2674
|
profileId?: string | null;
|
|
2626
2675
|
visitorId?: number | null;
|
|
2627
2676
|
urlSlug?: string;
|
|
@@ -2649,11 +2698,11 @@ interface VisitorInterface extends SDKInterface {
|
|
|
2649
2698
|
grantInventoryItem(item: InventoryItemInterface, quantity: number): Promise<UserInventoryItem>;
|
|
2650
2699
|
modifyInventoryItemQuantity(item: UserInventoryItemInterface | InventoryItemInterface, quantity: number): Promise<UserInventoryItem>;
|
|
2651
2700
|
fetchInventoryItem(item: InventoryItemInterface): Promise<UserInventoryItem>;
|
|
2652
|
-
createNpc(userInventoryItemId: string, options?:
|
|
2653
|
-
showNameplate?: boolean;
|
|
2654
|
-
}): Promise<Visitor>;
|
|
2701
|
+
createNpc(userInventoryItemId: string, options?: CreateNpcOptions): Promise<Visitor>;
|
|
2655
2702
|
deleteNpc(): Promise<void>;
|
|
2656
2703
|
getNpc(): Promise<Visitor | null>;
|
|
2704
|
+
startNpcVoiceSession(config: NpcVoiceConfigInterface): Promise<void | ResponseType>;
|
|
2705
|
+
stopNpcVoiceSession(): Promise<void | ResponseType>;
|
|
2657
2706
|
triggerParticle({ id, name, duration, }: {
|
|
2658
2707
|
id?: string;
|
|
2659
2708
|
name?: string;
|
|
@@ -2697,7 +2746,7 @@ interface VisitorInterface extends SDKInterface {
|
|
|
2697
2746
|
}
|
|
2698
2747
|
interface VisitorOptionalInterface {
|
|
2699
2748
|
attributes?: VisitorInterface | object;
|
|
2700
|
-
credentials?: InteractiveCredentials;
|
|
2749
|
+
credentials?: InteractiveCredentials$1;
|
|
2701
2750
|
}
|
|
2702
2751
|
interface MoveVisitorInterface {
|
|
2703
2752
|
shouldTeleportVisitor: boolean;
|
|
@@ -2710,6 +2759,39 @@ interface OpenIframeInterface {
|
|
|
2710
2759
|
shouldOpenInDrawer?: boolean;
|
|
2711
2760
|
title?: string;
|
|
2712
2761
|
}
|
|
2762
|
+
interface SpawnEffectConfig {
|
|
2763
|
+
type?: "portal" | "none";
|
|
2764
|
+
colors?: number[];
|
|
2765
|
+
glowColor?: number;
|
|
2766
|
+
glowOpacity?: number;
|
|
2767
|
+
centerColor?: number;
|
|
2768
|
+
duration?: number;
|
|
2769
|
+
sectorCount?: number;
|
|
2770
|
+
gridSize?: number;
|
|
2771
|
+
}
|
|
2772
|
+
interface CreateNpcOptions {
|
|
2773
|
+
showNameplate?: boolean;
|
|
2774
|
+
stationary?: boolean;
|
|
2775
|
+
replace?: boolean;
|
|
2776
|
+
spawnEffect?: SpawnEffectConfig;
|
|
2777
|
+
}
|
|
2778
|
+
interface NpcVoiceConfigInterface {
|
|
2779
|
+
/** OpenAI ephemeral key (ek_*). Generated server-side, used once to establish WebRTC connection. */
|
|
2780
|
+
ephemeralKey: string;
|
|
2781
|
+
/** OpenAI voice ID (e.g., "alloy", "echo", "shimmer"). */
|
|
2782
|
+
voice: string;
|
|
2783
|
+
/** System prompt including curriculum context and behavioral instructions. */
|
|
2784
|
+
instructions: string;
|
|
2785
|
+
/** OpenAI model ID. Defaults to "gpt-4o-realtime-preview". */
|
|
2786
|
+
model?: string;
|
|
2787
|
+
/** Voice activity detection configuration. */
|
|
2788
|
+
turnDetection?: {
|
|
2789
|
+
type: "server_vad";
|
|
2790
|
+
threshold?: number;
|
|
2791
|
+
prefix_padding_ms?: number;
|
|
2792
|
+
silence_duration_ms?: number;
|
|
2793
|
+
};
|
|
2794
|
+
}
|
|
2713
2795
|
|
|
2714
2796
|
interface WebhookInterface {
|
|
2715
2797
|
webhookId?: string;
|
|
@@ -2730,12 +2812,12 @@ interface WebRTCConnectorInterface {
|
|
|
2730
2812
|
getTwilioConfig(): Promise<void | ResponseType>;
|
|
2731
2813
|
}
|
|
2732
2814
|
interface WebRTCConnectorOptionalInterface {
|
|
2733
|
-
credentials?: InteractiveCredentials;
|
|
2815
|
+
credentials?: InteractiveCredentials$1;
|
|
2734
2816
|
twilioConfig?: object;
|
|
2735
2817
|
}
|
|
2736
2818
|
|
|
2737
2819
|
interface WorldActivityOptionalInterface {
|
|
2738
|
-
credentials?: InteractiveCredentials;
|
|
2820
|
+
credentials?: InteractiveCredentials$1;
|
|
2739
2821
|
}
|
|
2740
2822
|
interface MoveAllVisitorsInterface {
|
|
2741
2823
|
shouldFetchVisitors?: boolean;
|
|
@@ -2825,13 +2907,13 @@ interface WorldInterface extends SDKInterface, WorldDetailsInterface {
|
|
|
2825
2907
|
}
|
|
2826
2908
|
interface WorldOptionalInterface {
|
|
2827
2909
|
attributes?: WorldDetailsInterface | object;
|
|
2828
|
-
credentials?: InteractiveCredentials;
|
|
2910
|
+
credentials?: InteractiveCredentials$1;
|
|
2829
2911
|
}
|
|
2830
2912
|
interface WorldWebhooksInterface {
|
|
2831
2913
|
webhooks: Array<WebhookInterface>;
|
|
2832
2914
|
}
|
|
2833
2915
|
|
|
2834
|
-
type InteractiveCredentials
|
|
2916
|
+
type InteractiveCredentials = {
|
|
2835
2917
|
apiKey?: string;
|
|
2836
2918
|
assetId?: string;
|
|
2837
2919
|
interactiveNonce?: string;
|
|
@@ -2862,7 +2944,7 @@ interface InventoryItemInterface extends SDKInterface {
|
|
|
2862
2944
|
}
|
|
2863
2945
|
type InventoryItemOptionalInterface = {
|
|
2864
2946
|
attributes?: InventoryItemInterface | object;
|
|
2865
|
-
credentials?: InteractiveCredentials
|
|
2947
|
+
credentials?: InteractiveCredentials;
|
|
2866
2948
|
};
|
|
2867
2949
|
|
|
2868
2950
|
/**
|
|
@@ -2880,7 +2962,7 @@ interface UserInventoryItemInterface extends InventoryItemInterface {
|
|
|
2880
2962
|
}
|
|
2881
2963
|
type UserInventoryItemOptionalInterface = {
|
|
2882
2964
|
attributes?: UserInventoryItemInterface | object;
|
|
2883
|
-
credentials?: InteractiveCredentials
|
|
2965
|
+
credentials?: InteractiveCredentials;
|
|
2884
2966
|
};
|
|
2885
2967
|
type UserInventoryItemMetadataType = {
|
|
2886
2968
|
id: string;
|
|
@@ -2959,11 +3041,11 @@ declare class Topia implements TopiaInterface {
|
|
|
2959
3041
|
* ```
|
|
2960
3042
|
*/
|
|
2961
3043
|
declare abstract class SDKController implements SDKInterface {
|
|
2962
|
-
credentials: InteractiveCredentials | undefined;
|
|
3044
|
+
credentials: InteractiveCredentials$1 | undefined;
|
|
2963
3045
|
jwt?: string;
|
|
2964
3046
|
requestOptions: object;
|
|
2965
3047
|
topia: Topia;
|
|
2966
|
-
constructor(topia: Topia, credentials?: InteractiveCredentials);
|
|
3048
|
+
constructor(topia: Topia, credentials?: InteractiveCredentials$1);
|
|
2967
3049
|
/**
|
|
2968
3050
|
* Returns the configured Axios instance for making API calls to Topia's Public API.
|
|
2969
3051
|
*
|
|
@@ -2991,11 +3073,6 @@ declare abstract class SDKController implements SDKInterface {
|
|
|
2991
3073
|
*
|
|
2992
3074
|
* @keywords error, exception, handler, debugging, api error, http error
|
|
2993
3075
|
*
|
|
2994
|
-
* @param error - The error object from the failed operation (AxiosError, Error, or unknown)
|
|
2995
|
-
* @param message - Optional custom error message (defaults to generic message)
|
|
2996
|
-
* @param params - Optional parameters that were passed to the failed method
|
|
2997
|
-
* @param sdkMethod - Optional name of the SDK method that failed (e.g., "World.fetchDetails")
|
|
2998
|
-
*
|
|
2999
3076
|
* @returns {object} Standardized error object with properties: data, message, method, params, sdkMethod, stack, status, success, url
|
|
3000
3077
|
*/
|
|
3001
3078
|
errorHandler({ error, message, params, sdkMethod, }: {
|
|
@@ -3608,7 +3685,7 @@ declare class DroppedAssetFactory extends SDKController {
|
|
|
3608
3685
|
*
|
|
3609
3686
|
* @returns {Promise<DroppedAsset>} Returns a new DroppedAsset object with all properties already fetched.
|
|
3610
3687
|
*/
|
|
3611
|
-
getWithUniqueName(uniqueName: string, urlSlug: string, interactiveSecret: string, credentials: InteractiveCredentials): Promise<DroppedAsset>;
|
|
3688
|
+
getWithUniqueName(uniqueName: string, urlSlug: string, interactiveSecret: string, credentials: InteractiveCredentials$1): Promise<DroppedAsset>;
|
|
3612
3689
|
/**
|
|
3613
3690
|
* Drops an asset in a world and returns a new instance of DroppedAsset class with all properties.
|
|
3614
3691
|
*
|
|
@@ -4190,4 +4267,4 @@ declare class WorldFactory extends SDKController {
|
|
|
4190
4267
|
}>;
|
|
4191
4268
|
}
|
|
4192
4269
|
|
|
4193
|
-
export { AnalyticType, AnimationMetaType, Asset, AssetFactory, AssetInterface, AssetOptionalInterface, AssetOptions, AssetType, DroppedAsset, DroppedAssetClickType, DroppedAssetFactory, DroppedAssetInterface, DroppedAssetLinkType, DroppedAssetMediaType, DroppedAssetMediaVolumeRadius, DroppedAssetOptionalInterface, DroppedAssetOptions, Ecosystem, EcosystemFactory, EcosystemInterface, EcosystemOptionalInterface, FireToastInterface, FrameType, InteractiveCredentials, InventoryItemInterface, InventoryItemOptionalInterface, MoveAllVisitorsInterface, MoveVisitorInterface, OpenIframeInterface, RemoveClickableLinkInterface, ResponseType, SDKController, SDKInterface, Scene, SceneFactory, SceneInterface, SceneOptionalInterface, SetClickableLinkMultiInterface, Topia, TopiaInterface, UpdateBroadcastInterface, UpdateClickTypeInterface, UpdateClickableLinkMultiInterface, UpdateDroppedAssetInterface, UpdateMediaTypeInterface, UpdatePrivateZoneInterface, User, UserFactory, UserInterface, UserInventoryItemInterface, UserInventoryItemMetadataType, UserInventoryItemOptionalInterface, UserOptionalInterface, UserOptions, Visitor, VisitorFactory, VisitorInterface, VisitorOptionalInterface, VisitorOptions, VisitorType, VisitorsToMoveArrayType, VisitorsToMoveType, WebRTCConnector, WebRTCConnectorFactory, WebRTCConnectorInterface, WebRTCConnectorOptionalInterface, WebhookInterface, World, WorldActivity, WorldActivityFactory, WorldActivityOptionalInterface, WorldActivityType, WorldDetailsInterface, WorldFactory, WorldInterface, WorldOptionalInterface, WorldOptions, WorldWebhooksInterface };
|
|
4270
|
+
export { AnalyticType, AnimationMetaType, Asset, AssetFactory, AssetInterface, AssetOptionalInterface, AssetOptions, AssetType, CreateNpcOptions, DroppedAsset, DroppedAssetClickType, DroppedAssetFactory, DroppedAssetInterface, DroppedAssetLinkType, DroppedAssetMediaType, DroppedAssetMediaVolumeRadius, DroppedAssetOptionalInterface, DroppedAssetOptions, Ecosystem, EcosystemFactory, EcosystemInterface, EcosystemOptionalInterface, FireToastInterface, FrameType, InteractiveCredentials$1 as InteractiveCredentials, InventoryItemInterface, InventoryItemOptionalInterface, MoveAllVisitorsInterface, MoveVisitorInterface, NpcVoiceConfigInterface, OpenIframeInterface, RemoveClickableLinkInterface, ResponseType, SDKController, SDKInterface, Scene, SceneFactory, SceneInterface, SceneOptionalInterface, SetClickableLinkMultiInterface, SpawnEffectConfig, Topia, TopiaInterface, UpdateBroadcastInterface, UpdateClickTypeInterface, UpdateClickableLinkMultiInterface, UpdateDroppedAssetInterface, UpdateMediaTypeInterface, UpdatePrivateZoneInterface, User, UserFactory, UserInterface, UserInventoryItemInterface, UserInventoryItemMetadataType, UserInventoryItemOptionalInterface, UserOptionalInterface, UserOptions, Visitor, VisitorFactory, VisitorInterface, VisitorOptionalInterface, VisitorOptions, VisitorType, VisitorsToMoveArrayType, VisitorsToMoveType, WebRTCConnector, WebRTCConnectorFactory, WebRTCConnectorInterface, WebRTCConnectorOptionalInterface, WebhookInterface, World, WorldActivity, WorldActivityFactory, WorldActivityOptionalInterface, WorldActivityType, WorldDetailsInterface, WorldFactory, WorldInterface, WorldOptionalInterface, WorldOptions, WorldWebhooksInterface };
|
package/dist/index.js
CHANGED
|
@@ -39725,11 +39725,6 @@ class SDKController {
|
|
|
39725
39725
|
*
|
|
39726
39726
|
* @keywords error, exception, handler, debugging, api error, http error
|
|
39727
39727
|
*
|
|
39728
|
-
* @param error - The error object from the failed operation (AxiosError, Error, or unknown)
|
|
39729
|
-
* @param message - Optional custom error message (defaults to generic message)
|
|
39730
|
-
* @param params - Optional parameters that were passed to the failed method
|
|
39731
|
-
* @param sdkMethod - Optional name of the SDK method that failed (e.g., "World.fetchDetails")
|
|
39732
|
-
*
|
|
39733
39728
|
* @returns {object} Standardized error object with properties: data, message, method, params, sdkMethod, stack, status, success, url
|
|
39734
39729
|
*/
|
|
39735
39730
|
errorHandler({ error, message = "Something went wrong. Please try again or contact support.", params = {}, sdkMethod, }) {
|
|
@@ -43668,7 +43663,13 @@ class Visitor extends User {
|
|
|
43668
43663
|
createNpc(userInventoryItemId, options) {
|
|
43669
43664
|
return __awaiter(this, void 0, void 0, function* () {
|
|
43670
43665
|
try {
|
|
43671
|
-
const response = yield this.topiaPublicApi().post(`/world/${this.urlSlug}/visitors/${this.id}/create-npc`, {
|
|
43666
|
+
const response = yield this.topiaPublicApi().post(`/world/${this.urlSlug}/visitors/${this.id}/create-npc`, {
|
|
43667
|
+
userInventoryItemId,
|
|
43668
|
+
showNameplate: options === null || options === void 0 ? void 0 : options.showNameplate,
|
|
43669
|
+
stationary: options === null || options === void 0 ? void 0 : options.stationary,
|
|
43670
|
+
replace: options === null || options === void 0 ? void 0 : options.replace,
|
|
43671
|
+
spawnEffect: options === null || options === void 0 ? void 0 : options.spawnEffect,
|
|
43672
|
+
}, this.requestOptions);
|
|
43672
43673
|
return new Visitor(this.topia, response.data.player.playerId, this.urlSlug, {
|
|
43673
43674
|
attributes: response.data,
|
|
43674
43675
|
credentials: this.credentials,
|
|
@@ -43713,6 +43714,77 @@ class Visitor extends User {
|
|
|
43713
43714
|
}
|
|
43714
43715
|
});
|
|
43715
43716
|
}
|
|
43717
|
+
/**
|
|
43718
|
+
* Start an AI voice session for this visitor's NPC.
|
|
43719
|
+
*
|
|
43720
|
+
* @remarks
|
|
43721
|
+
* Establishes a real-time voice connection between the visitor and an AI backend
|
|
43722
|
+
* (currently OpenAI Realtime API) through the NPC. The NPC must already be spawned
|
|
43723
|
+
* via `createNpc()` before calling this method.
|
|
43724
|
+
*
|
|
43725
|
+
* The voice session occupies a video slot in the visitor's peer video grid, showing
|
|
43726
|
+
* the NPC's avatar image. Audio streams bidirectionally between the visitor's microphone
|
|
43727
|
+
* and the AI model. Only the NPC's owner hears the AI audio.
|
|
43728
|
+
*
|
|
43729
|
+
* Topia automatically prepends non-removable child safety guardrails to the instructions.
|
|
43730
|
+
* Only one voice session is allowed per visitor per world at a time.
|
|
43731
|
+
*
|
|
43732
|
+
* @keywords voice, npc, ai, chat, audio, realtime, session, start, speech
|
|
43733
|
+
*
|
|
43734
|
+
* @category NPCs
|
|
43735
|
+
*
|
|
43736
|
+
* @param config - Voice session configuration including ephemeral key and AI instructions
|
|
43737
|
+
*
|
|
43738
|
+
* @example
|
|
43739
|
+
* ```ts
|
|
43740
|
+
* const ephemeralKey = await generateOpenAIEphemeralKey();
|
|
43741
|
+
*
|
|
43742
|
+
* await visitor.startNpcVoiceSession({
|
|
43743
|
+
* ephemeralKey,
|
|
43744
|
+
* voice: "alloy",
|
|
43745
|
+
* instructions: "You are a friendly science tutor helping with photosynthesis.",
|
|
43746
|
+
* model: "gpt-4o-realtime-preview",
|
|
43747
|
+
* });
|
|
43748
|
+
* ```
|
|
43749
|
+
*
|
|
43750
|
+
* @returns {Promise<void | ResponseType>} Returns `{ success: true }` or an error.
|
|
43751
|
+
*/
|
|
43752
|
+
startNpcVoiceSession(config) {
|
|
43753
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
43754
|
+
try {
|
|
43755
|
+
const response = yield this.topiaPublicApi().put(`/world/${this.urlSlug}/visitors/${this.id}/start-npc-voice-session`, { voiceConfig: config }, this.requestOptions);
|
|
43756
|
+
return response.data;
|
|
43757
|
+
}
|
|
43758
|
+
catch (error) {
|
|
43759
|
+
throw this.errorHandler({ error, params: config, sdkMethod: "Visitor.startNpcVoiceSession" });
|
|
43760
|
+
}
|
|
43761
|
+
});
|
|
43762
|
+
}
|
|
43763
|
+
/**
|
|
43764
|
+
* Stop the active AI voice session for this visitor's NPC.
|
|
43765
|
+
*
|
|
43766
|
+
* @keywords voice, npc, ai, chat, audio, realtime, session, stop, end
|
|
43767
|
+
*
|
|
43768
|
+
* @category NPCs
|
|
43769
|
+
*
|
|
43770
|
+
* @example
|
|
43771
|
+
* ```ts
|
|
43772
|
+
* await visitor.stopNpcVoiceSession();
|
|
43773
|
+
* ```
|
|
43774
|
+
*
|
|
43775
|
+
* @returns {Promise<void | ResponseType>} Returns `{ success: true }` or an error.
|
|
43776
|
+
*/
|
|
43777
|
+
stopNpcVoiceSession() {
|
|
43778
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
43779
|
+
try {
|
|
43780
|
+
const response = yield this.topiaPublicApi().put(`/world/${this.urlSlug}/visitors/${this.id}/stop-npc-voice-session`, {}, this.requestOptions);
|
|
43781
|
+
return response.data;
|
|
43782
|
+
}
|
|
43783
|
+
catch (error) {
|
|
43784
|
+
throw this.errorHandler({ error, sdkMethod: "Visitor.stopNpcVoiceSession" });
|
|
43785
|
+
}
|
|
43786
|
+
});
|
|
43787
|
+
}
|
|
43716
43788
|
/**
|
|
43717
43789
|
* Retrieves all inventory items owned by this visitor and app's key.
|
|
43718
43790
|
*
|
package/package.json
CHANGED