@rtsdk/topia 0.19.5 → 0.19.7
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/dist/index.cjs +100 -10
- package/dist/index.d.ts +89 -7
- package/dist/index.js +100 -10
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -39751,6 +39751,11 @@ class SDKController {
|
|
|
39751
39751
|
errorMessage = (error === null || error === void 0 ? void 0 : error.message) || message;
|
|
39752
39752
|
stack = `${error.stack}\n${stackTrace.stack}`;
|
|
39753
39753
|
}
|
|
39754
|
+
else if (error !== undefined && error !== null) {
|
|
39755
|
+
// Handle bare string throws and other non-Error types
|
|
39756
|
+
errorMessage = typeof error === "string" ? error : JSON.stringify(error);
|
|
39757
|
+
stack = stackTrace.stack || "empty";
|
|
39758
|
+
}
|
|
39754
39759
|
return {
|
|
39755
39760
|
data,
|
|
39756
39761
|
message: errorMessage,
|
|
@@ -42258,6 +42263,7 @@ AI RULES for code assistants
|
|
|
42258
42263
|
*/
|
|
42259
42264
|
class User extends SDKController {
|
|
42260
42265
|
constructor(topia, options = { profileId: null, credentials: {} }) {
|
|
42266
|
+
var _a;
|
|
42261
42267
|
super(topia, Object.assign({ profileId: options === null || options === void 0 ? void 0 : options.profileId }, options.credentials));
|
|
42262
42268
|
_User_userInventoryItems.set(this, void 0);
|
|
42263
42269
|
_User_adminWorldsMap.set(this, void 0);
|
|
@@ -42265,6 +42271,13 @@ class User extends SDKController {
|
|
|
42265
42271
|
_User_scenesMap.set(this, void 0);
|
|
42266
42272
|
_User_worldsMap.set(this, void 0);
|
|
42267
42273
|
this.profileId = options === null || options === void 0 ? void 0 : options.profileId;
|
|
42274
|
+
// Warn devs about common mistake: passing profileId only inside credentials
|
|
42275
|
+
if (!this.profileId && ((_a = options === null || options === void 0 ? void 0 : options.credentials) === null || _a === void 0 ? void 0 : _a.profileId)) {
|
|
42276
|
+
console.warn(`[@rtsdk/topia] User created without top-level profileId. ` +
|
|
42277
|
+
`You passed profileId inside credentials but not in options. ` +
|
|
42278
|
+
`Methods like grantInventoryItem will fail. ` +
|
|
42279
|
+
`Fix: User.create({ profileId: "${options.credentials.profileId}", credentials: { ... } })`);
|
|
42280
|
+
}
|
|
42268
42281
|
this.dataObject = {};
|
|
42269
42282
|
this.profile = {};
|
|
42270
42283
|
__classPrivateFieldSet(this, _User_adminWorldsMap, {}, "f");
|
|
@@ -42778,7 +42791,7 @@ class User extends SDKController {
|
|
|
42778
42791
|
return __awaiter(this, void 0, void 0, function* () {
|
|
42779
42792
|
try {
|
|
42780
42793
|
if (!this.profileId)
|
|
42781
|
-
throw "This method requires the use of a profileId";
|
|
42794
|
+
throw new Error("This method requires the use of a profileId. Pass profileId as a top-level option: User.create({ profileId, credentials: { ... } })");
|
|
42782
42795
|
let query = "";
|
|
42783
42796
|
if (appPublicKey)
|
|
42784
42797
|
query = `?appPublicKey=${appPublicKey}&appJWT=${appJWT}`;
|
|
@@ -42818,7 +42831,7 @@ class User extends SDKController {
|
|
|
42818
42831
|
return __awaiter(this, void 0, void 0, function* () {
|
|
42819
42832
|
try {
|
|
42820
42833
|
if (!this.profileId)
|
|
42821
|
-
throw "This method requires the use of a profileId";
|
|
42834
|
+
throw new Error("This method requires the use of a profileId. Pass profileId as a top-level option: User.create({ profileId, credentials: { ... } })");
|
|
42822
42835
|
yield this.topiaPublicApi().put(`/user/dataObjects/${this.profileId}/set-data-object`, Object.assign(Object.assign({}, options), { dataObject: dataObject || this.dataObject }), this.requestOptions);
|
|
42823
42836
|
this.dataObject = dataObject || this.dataObject;
|
|
42824
42837
|
}
|
|
@@ -42852,7 +42865,7 @@ class User extends SDKController {
|
|
|
42852
42865
|
return __awaiter(this, void 0, void 0, function* () {
|
|
42853
42866
|
try {
|
|
42854
42867
|
if (!this.profileId)
|
|
42855
|
-
throw "This method requires the use of a profileId";
|
|
42868
|
+
throw new Error("This method requires the use of a profileId. Pass profileId as a top-level option: User.create({ profileId, credentials: { ... } })");
|
|
42856
42869
|
yield this.topiaPublicApi().put(`/user/dataObjects/${this.profileId}/update-data-object`, Object.assign(Object.assign({}, options), { dataObject: dataObject || this.dataObject }), this.requestOptions);
|
|
42857
42870
|
this.dataObject = Object.assign(Object.assign({}, (this.dataObject || {})), (dataObject || {}));
|
|
42858
42871
|
}
|
|
@@ -42902,7 +42915,7 @@ class User extends SDKController {
|
|
|
42902
42915
|
return __awaiter(this, void 0, void 0, function* () {
|
|
42903
42916
|
try {
|
|
42904
42917
|
if (!this.profileId)
|
|
42905
|
-
throw "This method requires the use of a profileId";
|
|
42918
|
+
throw new Error("This method requires the use of a profileId. Pass profileId as a top-level option: User.create({ profileId, credentials: { ... } })");
|
|
42906
42919
|
const response = yield this.topiaPublicApi().get(`/user/inventory/${this.profileId}/get-user-inventory-items`, this.requestOptions);
|
|
42907
42920
|
// TODO: Replace 'object' with InventoryItem and instantiate InventoryItem objects if needed
|
|
42908
42921
|
const tempItems = [];
|
|
@@ -42915,7 +42928,7 @@ class User extends SDKController {
|
|
|
42915
42928
|
__classPrivateFieldSet(this, _User_userInventoryItems, tempItems, "f");
|
|
42916
42929
|
}
|
|
42917
42930
|
catch (error) {
|
|
42918
|
-
throw this.errorHandler({ error, sdkMethod: "
|
|
42931
|
+
throw this.errorHandler({ error, sdkMethod: "User.fetchInventoryItems" });
|
|
42919
42932
|
}
|
|
42920
42933
|
});
|
|
42921
42934
|
}
|
|
@@ -42939,7 +42952,7 @@ class User extends SDKController {
|
|
|
42939
42952
|
return __awaiter(this, void 0, void 0, function* () {
|
|
42940
42953
|
try {
|
|
42941
42954
|
if (!this.profileId)
|
|
42942
|
-
throw "This method requires the use of a profileId";
|
|
42955
|
+
throw new Error("This method requires the use of a profileId. Pass profileId as a top-level option: User.create({ profileId, credentials: { ... } })");
|
|
42943
42956
|
const response = yield this.topiaPublicApi().put(`/user/inventory/${this.profileId}/grant-user-inventory-item`, { itemId: item.id, quantity }, this.requestOptions);
|
|
42944
42957
|
const userInventoryItemFactory = new UserInventoryItemFactory(this.topia);
|
|
42945
42958
|
const { inventoryItem, user_id, quantity: newQuantity } = response.data;
|
|
@@ -42949,7 +42962,7 @@ class User extends SDKController {
|
|
|
42949
42962
|
});
|
|
42950
42963
|
}
|
|
42951
42964
|
catch (error) {
|
|
42952
|
-
throw this.errorHandler({ error, sdkMethod: "
|
|
42965
|
+
throw this.errorHandler({ error, sdkMethod: "User.grantInventoryItem" });
|
|
42953
42966
|
}
|
|
42954
42967
|
});
|
|
42955
42968
|
}
|
|
@@ -42970,7 +42983,7 @@ class User extends SDKController {
|
|
|
42970
42983
|
return __awaiter(this, void 0, void 0, function* () {
|
|
42971
42984
|
try {
|
|
42972
42985
|
if (!this.profileId)
|
|
42973
|
-
throw "This method requires the use of a profileId";
|
|
42986
|
+
throw new Error("This method requires the use of a profileId. Pass profileId as a top-level option: User.create({ profileId, credentials: { ... } })");
|
|
42974
42987
|
const response = yield this.topiaPublicApi().put(`/user/inventory/${this.profileId}/update-user-inventory-item-quantity`, { userItemId: item.id, itemId: item.item_id, quantity }, this.requestOptions);
|
|
42975
42988
|
const userInventoryItemFactory = new UserInventoryItemFactory(this.topia);
|
|
42976
42989
|
const { inventoryItem, user_id, quantity: newQuantity } = response.data;
|
|
@@ -42980,7 +42993,7 @@ class User extends SDKController {
|
|
|
42980
42993
|
});
|
|
42981
42994
|
}
|
|
42982
42995
|
catch (error) {
|
|
42983
|
-
throw this.errorHandler({ error, sdkMethod: "
|
|
42996
|
+
throw this.errorHandler({ error, sdkMethod: "User.modifyInventoryItemQuantity" });
|
|
42984
42997
|
}
|
|
42985
42998
|
});
|
|
42986
42999
|
}
|
|
@@ -43665,7 +43678,13 @@ class Visitor extends User {
|
|
|
43665
43678
|
createNpc(userInventoryItemId, options) {
|
|
43666
43679
|
return __awaiter(this, void 0, void 0, function* () {
|
|
43667
43680
|
try {
|
|
43668
|
-
const response = yield this.topiaPublicApi().post(`/world/${this.urlSlug}/visitors/${this.id}/create-npc`, {
|
|
43681
|
+
const response = yield this.topiaPublicApi().post(`/world/${this.urlSlug}/visitors/${this.id}/create-npc`, {
|
|
43682
|
+
userInventoryItemId,
|
|
43683
|
+
showNameplate: options === null || options === void 0 ? void 0 : options.showNameplate,
|
|
43684
|
+
stationary: options === null || options === void 0 ? void 0 : options.stationary,
|
|
43685
|
+
replace: options === null || options === void 0 ? void 0 : options.replace,
|
|
43686
|
+
spawnEffect: options === null || options === void 0 ? void 0 : options.spawnEffect,
|
|
43687
|
+
}, this.requestOptions);
|
|
43669
43688
|
return new Visitor(this.topia, response.data.player.playerId, this.urlSlug, {
|
|
43670
43689
|
attributes: response.data,
|
|
43671
43690
|
credentials: this.credentials,
|
|
@@ -43710,6 +43729,77 @@ class Visitor extends User {
|
|
|
43710
43729
|
}
|
|
43711
43730
|
});
|
|
43712
43731
|
}
|
|
43732
|
+
/**
|
|
43733
|
+
* Start an AI voice session for this visitor's NPC.
|
|
43734
|
+
*
|
|
43735
|
+
* @remarks
|
|
43736
|
+
* Establishes a real-time voice connection between the visitor and an AI backend
|
|
43737
|
+
* (currently OpenAI Realtime API) through the NPC. The NPC must already be spawned
|
|
43738
|
+
* via `createNpc()` before calling this method.
|
|
43739
|
+
*
|
|
43740
|
+
* The voice session occupies a video slot in the visitor's peer video grid, showing
|
|
43741
|
+
* the NPC's avatar image. Audio streams bidirectionally between the visitor's microphone
|
|
43742
|
+
* and the AI model. Only the NPC's owner hears the AI audio.
|
|
43743
|
+
*
|
|
43744
|
+
* Topia automatically prepends non-removable child safety guardrails to the instructions.
|
|
43745
|
+
* Only one voice session is allowed per visitor per world at a time.
|
|
43746
|
+
*
|
|
43747
|
+
* @keywords voice, npc, ai, chat, audio, realtime, session, start, speech
|
|
43748
|
+
*
|
|
43749
|
+
* @category NPCs
|
|
43750
|
+
*
|
|
43751
|
+
* @param config - Voice session configuration including ephemeral key and AI instructions
|
|
43752
|
+
*
|
|
43753
|
+
* @example
|
|
43754
|
+
* ```ts
|
|
43755
|
+
* const ephemeralKey = await generateOpenAIEphemeralKey();
|
|
43756
|
+
*
|
|
43757
|
+
* await visitor.startNpcVoiceSession({
|
|
43758
|
+
* ephemeralKey,
|
|
43759
|
+
* voice: "alloy",
|
|
43760
|
+
* instructions: "You are a friendly science tutor helping with photosynthesis.",
|
|
43761
|
+
* model: "gpt-4o-realtime-preview",
|
|
43762
|
+
* });
|
|
43763
|
+
* ```
|
|
43764
|
+
*
|
|
43765
|
+
* @returns {Promise<void | ResponseType>} Returns `{ success: true }` or an error.
|
|
43766
|
+
*/
|
|
43767
|
+
startNpcVoiceSession(config) {
|
|
43768
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
43769
|
+
try {
|
|
43770
|
+
const response = yield this.topiaPublicApi().put(`/world/${this.urlSlug}/visitors/${this.id}/start-npc-voice-session`, { voiceConfig: config }, this.requestOptions);
|
|
43771
|
+
return response.data;
|
|
43772
|
+
}
|
|
43773
|
+
catch (error) {
|
|
43774
|
+
throw this.errorHandler({ error, params: config, sdkMethod: "Visitor.startNpcVoiceSession" });
|
|
43775
|
+
}
|
|
43776
|
+
});
|
|
43777
|
+
}
|
|
43778
|
+
/**
|
|
43779
|
+
* Stop the active AI voice session for this visitor's NPC.
|
|
43780
|
+
*
|
|
43781
|
+
* @keywords voice, npc, ai, chat, audio, realtime, session, stop, end
|
|
43782
|
+
*
|
|
43783
|
+
* @category NPCs
|
|
43784
|
+
*
|
|
43785
|
+
* @example
|
|
43786
|
+
* ```ts
|
|
43787
|
+
* await visitor.stopNpcVoiceSession();
|
|
43788
|
+
* ```
|
|
43789
|
+
*
|
|
43790
|
+
* @returns {Promise<void | ResponseType>} Returns `{ success: true }` or an error.
|
|
43791
|
+
*/
|
|
43792
|
+
stopNpcVoiceSession() {
|
|
43793
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
43794
|
+
try {
|
|
43795
|
+
const response = yield this.topiaPublicApi().put(`/world/${this.urlSlug}/visitors/${this.id}/stop-npc-voice-session`, {}, this.requestOptions);
|
|
43796
|
+
return response.data;
|
|
43797
|
+
}
|
|
43798
|
+
catch (error) {
|
|
43799
|
+
throw this.errorHandler({ error, sdkMethod: "Visitor.stopNpcVoiceSession" });
|
|
43800
|
+
}
|
|
43801
|
+
});
|
|
43802
|
+
}
|
|
43713
43803
|
/**
|
|
43714
43804
|
* Retrieves all inventory items owned by this visitor and app's key.
|
|
43715
43805
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -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
|
*
|
|
@@ -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;
|
|
@@ -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;
|
|
@@ -4185,4 +4267,4 @@ declare class WorldFactory extends SDKController {
|
|
|
4185
4267
|
}>;
|
|
4186
4268
|
}
|
|
4187
4269
|
|
|
4188
|
-
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$1 as 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
|
@@ -39749,6 +39749,11 @@ class SDKController {
|
|
|
39749
39749
|
errorMessage = (error === null || error === void 0 ? void 0 : error.message) || message;
|
|
39750
39750
|
stack = `${error.stack}\n${stackTrace.stack}`;
|
|
39751
39751
|
}
|
|
39752
|
+
else if (error !== undefined && error !== null) {
|
|
39753
|
+
// Handle bare string throws and other non-Error types
|
|
39754
|
+
errorMessage = typeof error === "string" ? error : JSON.stringify(error);
|
|
39755
|
+
stack = stackTrace.stack || "empty";
|
|
39756
|
+
}
|
|
39752
39757
|
return {
|
|
39753
39758
|
data,
|
|
39754
39759
|
message: errorMessage,
|
|
@@ -42256,6 +42261,7 @@ AI RULES for code assistants
|
|
|
42256
42261
|
*/
|
|
42257
42262
|
class User extends SDKController {
|
|
42258
42263
|
constructor(topia, options = { profileId: null, credentials: {} }) {
|
|
42264
|
+
var _a;
|
|
42259
42265
|
super(topia, Object.assign({ profileId: options === null || options === void 0 ? void 0 : options.profileId }, options.credentials));
|
|
42260
42266
|
_User_userInventoryItems.set(this, void 0);
|
|
42261
42267
|
_User_adminWorldsMap.set(this, void 0);
|
|
@@ -42263,6 +42269,13 @@ class User extends SDKController {
|
|
|
42263
42269
|
_User_scenesMap.set(this, void 0);
|
|
42264
42270
|
_User_worldsMap.set(this, void 0);
|
|
42265
42271
|
this.profileId = options === null || options === void 0 ? void 0 : options.profileId;
|
|
42272
|
+
// Warn devs about common mistake: passing profileId only inside credentials
|
|
42273
|
+
if (!this.profileId && ((_a = options === null || options === void 0 ? void 0 : options.credentials) === null || _a === void 0 ? void 0 : _a.profileId)) {
|
|
42274
|
+
console.warn(`[@rtsdk/topia] User created without top-level profileId. ` +
|
|
42275
|
+
`You passed profileId inside credentials but not in options. ` +
|
|
42276
|
+
`Methods like grantInventoryItem will fail. ` +
|
|
42277
|
+
`Fix: User.create({ profileId: "${options.credentials.profileId}", credentials: { ... } })`);
|
|
42278
|
+
}
|
|
42266
42279
|
this.dataObject = {};
|
|
42267
42280
|
this.profile = {};
|
|
42268
42281
|
__classPrivateFieldSet(this, _User_adminWorldsMap, {}, "f");
|
|
@@ -42776,7 +42789,7 @@ class User extends SDKController {
|
|
|
42776
42789
|
return __awaiter(this, void 0, void 0, function* () {
|
|
42777
42790
|
try {
|
|
42778
42791
|
if (!this.profileId)
|
|
42779
|
-
throw "This method requires the use of a profileId";
|
|
42792
|
+
throw new Error("This method requires the use of a profileId. Pass profileId as a top-level option: User.create({ profileId, credentials: { ... } })");
|
|
42780
42793
|
let query = "";
|
|
42781
42794
|
if (appPublicKey)
|
|
42782
42795
|
query = `?appPublicKey=${appPublicKey}&appJWT=${appJWT}`;
|
|
@@ -42816,7 +42829,7 @@ class User extends SDKController {
|
|
|
42816
42829
|
return __awaiter(this, void 0, void 0, function* () {
|
|
42817
42830
|
try {
|
|
42818
42831
|
if (!this.profileId)
|
|
42819
|
-
throw "This method requires the use of a profileId";
|
|
42832
|
+
throw new Error("This method requires the use of a profileId. Pass profileId as a top-level option: User.create({ profileId, credentials: { ... } })");
|
|
42820
42833
|
yield this.topiaPublicApi().put(`/user/dataObjects/${this.profileId}/set-data-object`, Object.assign(Object.assign({}, options), { dataObject: dataObject || this.dataObject }), this.requestOptions);
|
|
42821
42834
|
this.dataObject = dataObject || this.dataObject;
|
|
42822
42835
|
}
|
|
@@ -42850,7 +42863,7 @@ class User extends SDKController {
|
|
|
42850
42863
|
return __awaiter(this, void 0, void 0, function* () {
|
|
42851
42864
|
try {
|
|
42852
42865
|
if (!this.profileId)
|
|
42853
|
-
throw "This method requires the use of a profileId";
|
|
42866
|
+
throw new Error("This method requires the use of a profileId. Pass profileId as a top-level option: User.create({ profileId, credentials: { ... } })");
|
|
42854
42867
|
yield this.topiaPublicApi().put(`/user/dataObjects/${this.profileId}/update-data-object`, Object.assign(Object.assign({}, options), { dataObject: dataObject || this.dataObject }), this.requestOptions);
|
|
42855
42868
|
this.dataObject = Object.assign(Object.assign({}, (this.dataObject || {})), (dataObject || {}));
|
|
42856
42869
|
}
|
|
@@ -42900,7 +42913,7 @@ class User extends SDKController {
|
|
|
42900
42913
|
return __awaiter(this, void 0, void 0, function* () {
|
|
42901
42914
|
try {
|
|
42902
42915
|
if (!this.profileId)
|
|
42903
|
-
throw "This method requires the use of a profileId";
|
|
42916
|
+
throw new Error("This method requires the use of a profileId. Pass profileId as a top-level option: User.create({ profileId, credentials: { ... } })");
|
|
42904
42917
|
const response = yield this.topiaPublicApi().get(`/user/inventory/${this.profileId}/get-user-inventory-items`, this.requestOptions);
|
|
42905
42918
|
// TODO: Replace 'object' with InventoryItem and instantiate InventoryItem objects if needed
|
|
42906
42919
|
const tempItems = [];
|
|
@@ -42913,7 +42926,7 @@ class User extends SDKController {
|
|
|
42913
42926
|
__classPrivateFieldSet(this, _User_userInventoryItems, tempItems, "f");
|
|
42914
42927
|
}
|
|
42915
42928
|
catch (error) {
|
|
42916
|
-
throw this.errorHandler({ error, sdkMethod: "
|
|
42929
|
+
throw this.errorHandler({ error, sdkMethod: "User.fetchInventoryItems" });
|
|
42917
42930
|
}
|
|
42918
42931
|
});
|
|
42919
42932
|
}
|
|
@@ -42937,7 +42950,7 @@ class User extends SDKController {
|
|
|
42937
42950
|
return __awaiter(this, void 0, void 0, function* () {
|
|
42938
42951
|
try {
|
|
42939
42952
|
if (!this.profileId)
|
|
42940
|
-
throw "This method requires the use of a profileId";
|
|
42953
|
+
throw new Error("This method requires the use of a profileId. Pass profileId as a top-level option: User.create({ profileId, credentials: { ... } })");
|
|
42941
42954
|
const response = yield this.topiaPublicApi().put(`/user/inventory/${this.profileId}/grant-user-inventory-item`, { itemId: item.id, quantity }, this.requestOptions);
|
|
42942
42955
|
const userInventoryItemFactory = new UserInventoryItemFactory(this.topia);
|
|
42943
42956
|
const { inventoryItem, user_id, quantity: newQuantity } = response.data;
|
|
@@ -42947,7 +42960,7 @@ class User extends SDKController {
|
|
|
42947
42960
|
});
|
|
42948
42961
|
}
|
|
42949
42962
|
catch (error) {
|
|
42950
|
-
throw this.errorHandler({ error, sdkMethod: "
|
|
42963
|
+
throw this.errorHandler({ error, sdkMethod: "User.grantInventoryItem" });
|
|
42951
42964
|
}
|
|
42952
42965
|
});
|
|
42953
42966
|
}
|
|
@@ -42968,7 +42981,7 @@ class User extends SDKController {
|
|
|
42968
42981
|
return __awaiter(this, void 0, void 0, function* () {
|
|
42969
42982
|
try {
|
|
42970
42983
|
if (!this.profileId)
|
|
42971
|
-
throw "This method requires the use of a profileId";
|
|
42984
|
+
throw new Error("This method requires the use of a profileId. Pass profileId as a top-level option: User.create({ profileId, credentials: { ... } })");
|
|
42972
42985
|
const response = yield this.topiaPublicApi().put(`/user/inventory/${this.profileId}/update-user-inventory-item-quantity`, { userItemId: item.id, itemId: item.item_id, quantity }, this.requestOptions);
|
|
42973
42986
|
const userInventoryItemFactory = new UserInventoryItemFactory(this.topia);
|
|
42974
42987
|
const { inventoryItem, user_id, quantity: newQuantity } = response.data;
|
|
@@ -42978,7 +42991,7 @@ class User extends SDKController {
|
|
|
42978
42991
|
});
|
|
42979
42992
|
}
|
|
42980
42993
|
catch (error) {
|
|
42981
|
-
throw this.errorHandler({ error, sdkMethod: "
|
|
42994
|
+
throw this.errorHandler({ error, sdkMethod: "User.modifyInventoryItemQuantity" });
|
|
42982
42995
|
}
|
|
42983
42996
|
});
|
|
42984
42997
|
}
|
|
@@ -43663,7 +43676,13 @@ class Visitor extends User {
|
|
|
43663
43676
|
createNpc(userInventoryItemId, options) {
|
|
43664
43677
|
return __awaiter(this, void 0, void 0, function* () {
|
|
43665
43678
|
try {
|
|
43666
|
-
const response = yield this.topiaPublicApi().post(`/world/${this.urlSlug}/visitors/${this.id}/create-npc`, {
|
|
43679
|
+
const response = yield this.topiaPublicApi().post(`/world/${this.urlSlug}/visitors/${this.id}/create-npc`, {
|
|
43680
|
+
userInventoryItemId,
|
|
43681
|
+
showNameplate: options === null || options === void 0 ? void 0 : options.showNameplate,
|
|
43682
|
+
stationary: options === null || options === void 0 ? void 0 : options.stationary,
|
|
43683
|
+
replace: options === null || options === void 0 ? void 0 : options.replace,
|
|
43684
|
+
spawnEffect: options === null || options === void 0 ? void 0 : options.spawnEffect,
|
|
43685
|
+
}, this.requestOptions);
|
|
43667
43686
|
return new Visitor(this.topia, response.data.player.playerId, this.urlSlug, {
|
|
43668
43687
|
attributes: response.data,
|
|
43669
43688
|
credentials: this.credentials,
|
|
@@ -43708,6 +43727,77 @@ class Visitor extends User {
|
|
|
43708
43727
|
}
|
|
43709
43728
|
});
|
|
43710
43729
|
}
|
|
43730
|
+
/**
|
|
43731
|
+
* Start an AI voice session for this visitor's NPC.
|
|
43732
|
+
*
|
|
43733
|
+
* @remarks
|
|
43734
|
+
* Establishes a real-time voice connection between the visitor and an AI backend
|
|
43735
|
+
* (currently OpenAI Realtime API) through the NPC. The NPC must already be spawned
|
|
43736
|
+
* via `createNpc()` before calling this method.
|
|
43737
|
+
*
|
|
43738
|
+
* The voice session occupies a video slot in the visitor's peer video grid, showing
|
|
43739
|
+
* the NPC's avatar image. Audio streams bidirectionally between the visitor's microphone
|
|
43740
|
+
* and the AI model. Only the NPC's owner hears the AI audio.
|
|
43741
|
+
*
|
|
43742
|
+
* Topia automatically prepends non-removable child safety guardrails to the instructions.
|
|
43743
|
+
* Only one voice session is allowed per visitor per world at a time.
|
|
43744
|
+
*
|
|
43745
|
+
* @keywords voice, npc, ai, chat, audio, realtime, session, start, speech
|
|
43746
|
+
*
|
|
43747
|
+
* @category NPCs
|
|
43748
|
+
*
|
|
43749
|
+
* @param config - Voice session configuration including ephemeral key and AI instructions
|
|
43750
|
+
*
|
|
43751
|
+
* @example
|
|
43752
|
+
* ```ts
|
|
43753
|
+
* const ephemeralKey = await generateOpenAIEphemeralKey();
|
|
43754
|
+
*
|
|
43755
|
+
* await visitor.startNpcVoiceSession({
|
|
43756
|
+
* ephemeralKey,
|
|
43757
|
+
* voice: "alloy",
|
|
43758
|
+
* instructions: "You are a friendly science tutor helping with photosynthesis.",
|
|
43759
|
+
* model: "gpt-4o-realtime-preview",
|
|
43760
|
+
* });
|
|
43761
|
+
* ```
|
|
43762
|
+
*
|
|
43763
|
+
* @returns {Promise<void | ResponseType>} Returns `{ success: true }` or an error.
|
|
43764
|
+
*/
|
|
43765
|
+
startNpcVoiceSession(config) {
|
|
43766
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
43767
|
+
try {
|
|
43768
|
+
const response = yield this.topiaPublicApi().put(`/world/${this.urlSlug}/visitors/${this.id}/start-npc-voice-session`, { voiceConfig: config }, this.requestOptions);
|
|
43769
|
+
return response.data;
|
|
43770
|
+
}
|
|
43771
|
+
catch (error) {
|
|
43772
|
+
throw this.errorHandler({ error, params: config, sdkMethod: "Visitor.startNpcVoiceSession" });
|
|
43773
|
+
}
|
|
43774
|
+
});
|
|
43775
|
+
}
|
|
43776
|
+
/**
|
|
43777
|
+
* Stop the active AI voice session for this visitor's NPC.
|
|
43778
|
+
*
|
|
43779
|
+
* @keywords voice, npc, ai, chat, audio, realtime, session, stop, end
|
|
43780
|
+
*
|
|
43781
|
+
* @category NPCs
|
|
43782
|
+
*
|
|
43783
|
+
* @example
|
|
43784
|
+
* ```ts
|
|
43785
|
+
* await visitor.stopNpcVoiceSession();
|
|
43786
|
+
* ```
|
|
43787
|
+
*
|
|
43788
|
+
* @returns {Promise<void | ResponseType>} Returns `{ success: true }` or an error.
|
|
43789
|
+
*/
|
|
43790
|
+
stopNpcVoiceSession() {
|
|
43791
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
43792
|
+
try {
|
|
43793
|
+
const response = yield this.topiaPublicApi().put(`/world/${this.urlSlug}/visitors/${this.id}/stop-npc-voice-session`, {}, this.requestOptions);
|
|
43794
|
+
return response.data;
|
|
43795
|
+
}
|
|
43796
|
+
catch (error) {
|
|
43797
|
+
throw this.errorHandler({ error, sdkMethod: "Visitor.stopNpcVoiceSession" });
|
|
43798
|
+
}
|
|
43799
|
+
});
|
|
43800
|
+
}
|
|
43711
43801
|
/**
|
|
43712
43802
|
* Retrieves all inventory items owned by this visitor and app's key.
|
|
43713
43803
|
*
|
package/package.json
CHANGED