@space3-npm/cybersoul-client 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -2
- package/dist/client.d.ts +8 -1
- package/dist/client.js +158 -11
- package/dist/providers/minimax.provider.js +1 -1
- package/dist/types.d.ts +29 -0
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -19,6 +19,8 @@ Cyber-Soul Service transforms static text-based virtual companions into fully re
|
|
|
19
19
|
|
|
20
20
|
## Installation
|
|
21
21
|
|
|
22
|
+
**Prerequisites:** This SDK uses the native `fetch` API and requires **Node.js 18 or higher** (or a modern browser environment).
|
|
23
|
+
|
|
22
24
|
You can install the SDK locally or via npm:
|
|
23
25
|
|
|
24
26
|
```bash
|
|
@@ -34,7 +36,7 @@ import { CyberSoulClient } from '@space3-npm/cybersoul-client';
|
|
|
34
36
|
|
|
35
37
|
const client = new CyberSoulClient({
|
|
36
38
|
characterKey: 'YOUR_CHARACTER_KEY_HASH', // Ties requests to your specific Cyber-Soul persona
|
|
37
|
-
backendUrl: '
|
|
39
|
+
backendUrl: 'https://space3.cloud', // The Cyber-Soul core service URL (e.g., http://localhost:3002 for local dev)
|
|
38
40
|
llmConfig: {
|
|
39
41
|
provider: 'minimax',
|
|
40
42
|
apiKey: 'YOUR_MINIMAX_API_KEY',
|
|
@@ -104,4 +106,6 @@ The SDK perfectly mirrors the underlying Cyber-Soul backend capabilities via typ
|
|
|
104
106
|
- `giftOutfit(descriptionText)`: Provisions a new explicit outfit descriptor to the character's backend inventory.
|
|
105
107
|
- `bootstrapCharacter(workspaceFiles)`: Automates character profile and prompt setup directly from local markdown configuration files.
|
|
106
108
|
- `generateDailyScript()`: Cron-job helper instructing the AI scheduling system to compute the next block of dynamic events and plans.
|
|
107
|
-
- `interact(params)`: The primary orchestrated multi-modal dialogue endpoint processing standard human <-> agent chat requests.
|
|
109
|
+
- `interact(params)`: The primary orchestrated multi-modal dialogue endpoint processing standard human <-> agent chat requests.
|
|
110
|
+
- `ondemandEvent(params)`: Evaluates and triggers an on-demand event, using the LLM to intelligently decide if the character accepts the event and whether an outfit change is appropriate.
|
|
111
|
+
- `consolidateCoreMemory(input)`: Uses edge LLM logic to merge recent events with the character's core memory and synchronizes the updated memory to the remote database.
|
package/dist/client.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { CyberSoulClientConfig, InteractParams, DispatcherIntent, InteractResponse, CharacterState, CoreMemory } from "./types.js";
|
|
1
|
+
import { CyberSoulClientConfig, InteractParams, OndemandEventParams, OndemandEventResponse, DispatcherIntent, InteractResponse, CharacterState, CoreMemory } from "./types.js";
|
|
2
2
|
export declare class CyberSoulClient {
|
|
3
3
|
private config;
|
|
4
4
|
private llm;
|
|
5
|
+
private cachedWardrobeStr;
|
|
6
|
+
private cachedWardrobeTime;
|
|
5
7
|
constructor(config: CyberSoulClientConfig);
|
|
6
8
|
/**
|
|
7
9
|
* Internal wrapper for fetch that automatically injects the backend URL and Character Auth token.
|
|
@@ -27,6 +29,10 @@ export declare class CyberSoulClient {
|
|
|
27
29
|
* If the payload is already the inner args object (no voiceArgs wrapper), uses it as-is.
|
|
28
30
|
*/
|
|
29
31
|
private extractVoiceArgsFromLlmResponse;
|
|
32
|
+
/**
|
|
33
|
+
* Evaluates and triggers an on-demand event, intelligently deciding if an outfit change is needed.
|
|
34
|
+
*/
|
|
35
|
+
ondemandEvent(params: OndemandEventParams): Promise<OndemandEventResponse>;
|
|
30
36
|
/**
|
|
31
37
|
* Fetches the current dynamic context and daily state.
|
|
32
38
|
*/
|
|
@@ -68,6 +74,7 @@ export declare class CyberSoulClient {
|
|
|
68
74
|
*/
|
|
69
75
|
generateDailyScript(): Promise<void>;
|
|
70
76
|
private fetchRemoteState;
|
|
77
|
+
private getWardrobePromptStr;
|
|
71
78
|
private _updateDynamicContextInternal;
|
|
72
79
|
private generatePrimitive;
|
|
73
80
|
private normalizeRequestTypes;
|
package/dist/client.js
CHANGED
|
@@ -4,6 +4,8 @@ import { MinimaxProvider } from "./providers/minimax.provider.js";
|
|
|
4
4
|
export class CyberSoulClient {
|
|
5
5
|
config;
|
|
6
6
|
llm;
|
|
7
|
+
cachedWardrobeStr = null;
|
|
8
|
+
cachedWardrobeTime = 0;
|
|
7
9
|
constructor(config) {
|
|
8
10
|
this.config = config;
|
|
9
11
|
// Setup Provider
|
|
@@ -61,7 +63,7 @@ EMOTIONAL INERTIA RULES:
|
|
|
61
63
|
getImageSchemaParams() {
|
|
62
64
|
return `"imageParams": {
|
|
63
65
|
"mode": "structured | full-prompt (use 'full-prompt' for highly dynamic actions)",
|
|
64
|
-
"full_prompt": "Use only if mode is full-prompt. Highly detailed visual description in ENGLISH.",
|
|
66
|
+
"full_prompt": "Use only if mode is full-prompt. Highly detailed visual description in ENGLISH. MUST align with the character's current Active Wardrobe unless the context/exposure explicitly demands otherwise (e.g., naked for intimate scenes).",
|
|
65
67
|
"expression": "seductive | cute | happy | sleepy | dazed | pleased | default (Strictly choose ONE from this exact list. DO NOT invent new words like 'shy'.)",
|
|
66
68
|
"condition": "normal | sweaty | wet | messy | oily (Strictly choose ONE from this exact list.)",
|
|
67
69
|
"view_angle": "front | side | high_angle | from_below | boyfriend_view | selfie | mirror (Strictly choose ONE from this exact list.)",
|
|
@@ -122,6 +124,95 @@ EMOTIONAL INERTIA RULES:
|
|
|
122
124
|
}
|
|
123
125
|
return payload;
|
|
124
126
|
}
|
|
127
|
+
/**
|
|
128
|
+
* Evaluates and triggers an on-demand event, intelligently deciding if an outfit change is needed.
|
|
129
|
+
*/
|
|
130
|
+
async ondemandEvent(params) {
|
|
131
|
+
try {
|
|
132
|
+
// 1. Fetch current state and wardrobe items
|
|
133
|
+
const [state, availableOutfits] = await Promise.all([
|
|
134
|
+
this.fetchRemoteState(),
|
|
135
|
+
this.getWardrobePromptStr()
|
|
136
|
+
]);
|
|
137
|
+
// 2. Build local Prompt
|
|
138
|
+
const systemPrompt = `${this.buildStateContextPrompt(state, params.interactParams?.localContext)}
|
|
139
|
+
|
|
140
|
+
The user proposes a new event for you to participate in: "${params.eventDescription}".
|
|
141
|
+
Evaluate this based on your current state and relationship stage.
|
|
142
|
+
Decide if you will accept the event, and whether it requires changing your outfit.
|
|
143
|
+
|
|
144
|
+
Available Wardrobe Outfits:
|
|
145
|
+
${availableOutfits || "None available"}
|
|
146
|
+
|
|
147
|
+
You MUST output ONLY a valid JSON object matching this exact structure:
|
|
148
|
+
{
|
|
149
|
+
"acceptEvent": true,
|
|
150
|
+
"reason": "string (Why you accepted or declined, speaking in character)",
|
|
151
|
+
"requiresOutfitChange": false,
|
|
152
|
+
"selectedOutfitId": null
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
Example Valid Answer:
|
|
156
|
+
{
|
|
157
|
+
"acceptEvent": true,
|
|
158
|
+
"reason": "Sure, I'd love to go to the cafe. It sounds relaxing.",
|
|
159
|
+
"requiresOutfitChange": false,
|
|
160
|
+
"selectedOutfitId": null
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
CRITICAL: Output MUST be ONLY valid JSON with no markdown block wrappers. Do NOT wrap the JSON in \`\`\`json or add conversational text.`;
|
|
164
|
+
const promptMessages = [
|
|
165
|
+
{ role: "system", content: systemPrompt },
|
|
166
|
+
...(params.interactParams?.history || []).map((msg) => ({
|
|
167
|
+
role: msg.role,
|
|
168
|
+
content: typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content)
|
|
169
|
+
})),
|
|
170
|
+
{
|
|
171
|
+
role: "user",
|
|
172
|
+
content: `${params.interactParams?.userMessage || `Event Proposal: ${params.eventDescription}`}\n\n**CRITICAL REMINDER**: You MUST output your final response exactly in the JSON format specified in the system prompt. DO NOT output plain text directly.`,
|
|
173
|
+
},
|
|
174
|
+
];
|
|
175
|
+
// 3. Evaluate with LLM
|
|
176
|
+
const rawLlmResponse = await this.llm.generate(promptMessages, 800, 0.5);
|
|
177
|
+
// console.debug("[CyberSoulClient ondemandEvent] Raw LLM Response:", rawLlmResponse);
|
|
178
|
+
let decisionData = {};
|
|
179
|
+
try {
|
|
180
|
+
decisionData = robustJsonParse(rawLlmResponse, "OndemandEvent fallback");
|
|
181
|
+
}
|
|
182
|
+
catch (e) {
|
|
183
|
+
throw new Error(`Failed to parse LLM decision for ondemandEvent. Raw response: ${rawLlmResponse}`);
|
|
184
|
+
}
|
|
185
|
+
// 4. API call if accepted
|
|
186
|
+
if (decisionData.acceptEvent === true) {
|
|
187
|
+
const payload = {
|
|
188
|
+
eventDescription: params.eventDescription,
|
|
189
|
+
durationMins: params.durationMins || 60,
|
|
190
|
+
outfitId: decisionData.requiresOutfitChange ? decisionData.selectedOutfitId : undefined,
|
|
191
|
+
};
|
|
192
|
+
const backendRes = await this.apiFetch("/api/v1/cyber-soul/characters/ondemand-event", {
|
|
193
|
+
method: "POST",
|
|
194
|
+
body: JSON.stringify(payload),
|
|
195
|
+
});
|
|
196
|
+
if (!backendRes.ok) {
|
|
197
|
+
throw new Error("Backend failed to schedule the on-demand event");
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return {
|
|
201
|
+
status: "success",
|
|
202
|
+
acceptEvent: decisionData.acceptEvent,
|
|
203
|
+
reason: decisionData.reason,
|
|
204
|
+
requiresOutfitChange: decisionData.requiresOutfitChange,
|
|
205
|
+
selectedOutfitId: decisionData.selectedOutfitId,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
console.error("[CyberSoulClient] ondemandEvent Error: ", error);
|
|
210
|
+
return {
|
|
211
|
+
status: "error",
|
|
212
|
+
error: error.message,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
}
|
|
125
216
|
/**
|
|
126
217
|
* Fetches the current dynamic context and daily state.
|
|
127
218
|
*/
|
|
@@ -156,7 +247,7 @@ Output strictly valid JSON ONLY. No markdown, no conversational filler. Return e
|
|
|
156
247
|
},
|
|
157
248
|
];
|
|
158
249
|
const llmRes = await this.llm.generate(promptMessages, 800, 0.4);
|
|
159
|
-
console.
|
|
250
|
+
// console.debug("[CyberSoulClient ImageGen] Raw LLM Response:", llmRes);
|
|
160
251
|
try {
|
|
161
252
|
const parsedImageArgs = robustJsonParse(llmRes, "generateImage args fallback");
|
|
162
253
|
imageParams = parsedImageArgs.imageParams || parsedImageArgs;
|
|
@@ -191,7 +282,7 @@ Output strictly valid JSON ONLY. No markdown, no conversational filler. Return e
|
|
|
191
282
|
},
|
|
192
283
|
];
|
|
193
284
|
const llmRes = await this.llm.generate(promptMessages, 800, 0.3);
|
|
194
|
-
console.
|
|
285
|
+
// console.debug("[CyberSoulClient VoiceGen] Raw LLM Response:", llmRes);
|
|
195
286
|
try {
|
|
196
287
|
const parsedVoicePayload = robustJsonParse(llmRes, "generateVoice args fallback");
|
|
197
288
|
dynamicArgs = this.extractVoiceArgsFromLlmResponse(parsedVoicePayload);
|
|
@@ -248,6 +339,33 @@ Output strictly valid JSON ONLY. No markdown, no conversational filler. Return e
|
|
|
248
339
|
const json = await res.json();
|
|
249
340
|
return json.data;
|
|
250
341
|
}
|
|
342
|
+
async getWardrobePromptStr() {
|
|
343
|
+
const now = Date.now();
|
|
344
|
+
if (this.cachedWardrobeStr && (now - this.cachedWardrobeTime <= 5 * 60 * 1000)) {
|
|
345
|
+
return this.cachedWardrobeStr;
|
|
346
|
+
}
|
|
347
|
+
let availableOutfits = "None available";
|
|
348
|
+
try {
|
|
349
|
+
const wardrobeRes = await this.apiFetch("/api/v1/cyber-soul/wardrobe");
|
|
350
|
+
if (wardrobeRes.ok) {
|
|
351
|
+
let wardrobesPayload = {};
|
|
352
|
+
try {
|
|
353
|
+
wardrobesPayload = await wardrobeRes.json();
|
|
354
|
+
}
|
|
355
|
+
catch (e) { }
|
|
356
|
+
const wardrobes = wardrobesPayload.data || [];
|
|
357
|
+
if (wardrobes.length > 0) {
|
|
358
|
+
availableOutfits = wardrobes
|
|
359
|
+
.map((w) => `- ID: ${w.id} | Name: ${w.itemName} | Category: ${w.category}`)
|
|
360
|
+
.join("\n");
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
catch (e) { }
|
|
365
|
+
this.cachedWardrobeStr = availableOutfits;
|
|
366
|
+
this.cachedWardrobeTime = now;
|
|
367
|
+
return availableOutfits;
|
|
368
|
+
}
|
|
251
369
|
async _updateDynamicContextInternal(stateUpdate) {
|
|
252
370
|
if (!stateUpdate)
|
|
253
371
|
return;
|
|
@@ -267,8 +385,17 @@ Output strictly valid JSON ONLY. No markdown, no conversational filler. Return e
|
|
|
267
385
|
method: "POST",
|
|
268
386
|
body: JSON.stringify(payload),
|
|
269
387
|
});
|
|
270
|
-
if (!res.ok)
|
|
271
|
-
|
|
388
|
+
if (!res.ok) {
|
|
389
|
+
let errData;
|
|
390
|
+
try {
|
|
391
|
+
errData = await res.json();
|
|
392
|
+
}
|
|
393
|
+
catch (e) { }
|
|
394
|
+
const msg = errData?.message || errData?.error || `Status ${res.status}`;
|
|
395
|
+
const err = new Error(`Failed to generate ${type}: ${msg}`);
|
|
396
|
+
err.code = errData?.code || "UNKNOWN_ERROR";
|
|
397
|
+
throw err;
|
|
398
|
+
}
|
|
272
399
|
return res.json();
|
|
273
400
|
}
|
|
274
401
|
normalizeRequestTypes(requestTypes) {
|
|
@@ -284,13 +411,19 @@ Output strictly valid JSON ONLY. No markdown, no conversational filler. Return e
|
|
|
284
411
|
}
|
|
285
412
|
async interact(params) {
|
|
286
413
|
try {
|
|
287
|
-
// 1. Sync remote context
|
|
288
|
-
|
|
414
|
+
// 1. Sync remote context and wardrobe (for event triggering)
|
|
415
|
+
// We cache the wardrobe payload for 5 minutes to avoid huge payloads on every chat turn
|
|
416
|
+
const [state, availableOutfits] = await Promise.all([
|
|
417
|
+
this.fetchRemoteState(),
|
|
418
|
+
this.getWardrobePromptStr()
|
|
419
|
+
]);
|
|
289
420
|
// 2. Build local Prompt
|
|
290
421
|
const types = this.normalizeRequestTypes(params.requestTypes);
|
|
291
422
|
const isAuto = types.includes(InteractRequestType.AUTO);
|
|
292
423
|
// Combine state info into a clean descriptive context
|
|
293
424
|
const systemPrompt = `${this.buildStateContextPrompt(state, params.localContext)}
|
|
425
|
+
Available Wardrobe Outfits (For event triggers):
|
|
426
|
+
${availableOutfits}
|
|
294
427
|
|
|
295
428
|
The user has sent a message. You must evaluate the context and the user's message, and return a JSON object (no markdown formatting) that dictates the character's multi-modal response.
|
|
296
429
|
|
|
@@ -298,7 +431,8 @@ ${isAuto
|
|
|
298
431
|
? `Analyze the user's message to determine the appropriate response modalities (text, image, voice).
|
|
299
432
|
- Always include 'textResponse'.
|
|
300
433
|
- If the user explicitly asks to see a photo, look at you, or describing an action that warrants a photo, include 'imageParams'.
|
|
301
|
-
- If the user wants to hear you, or if appropriate for a voice message, include 'voiceArgs'
|
|
434
|
+
- If the user wants to hear you, or if appropriate for a voice message, include 'voiceArgs'.
|
|
435
|
+
- If the user proposes a new activity or hangout (e.g., "let's go to the cafe", "do you want to watch a movie?"), include 'triggerEvent' to schedule it.`
|
|
302
436
|
: `Requested types to fulfill: ${types.join(", ")}`}
|
|
303
437
|
If the user's message shifts the emotional mood, establishes new nicknames, or warrants a relationship temperature change, you MUST include a 'stateUpdate' block. Temperature goes from 0 (cold/angry) to 100 (obsessively in love).
|
|
304
438
|
Voice direction for voiceArgs: ${this.getVoiceDirectorInstruction(state)}
|
|
@@ -307,10 +441,11 @@ Output JSON Schema:
|
|
|
307
441
|
{
|
|
308
442
|
"textResponse": "The direct spoken dialogue in Chinese",
|
|
309
443
|
"stateUpdate": { "temperatureDelta": "+1 to -1", "userNickname": "What you now call the user", "agentNickname": "What the user calls you", "talkingStyle": "Current mood/style of talking" },
|
|
444
|
+
"triggerEvent": { "eventDescription": "Going to a cafe", "durationMins": 60, "outfitId": "optional wardrobe ID to change into if appropriate" },
|
|
310
445
|
${this.getImageSchemaParams()},
|
|
311
446
|
${this.getVoiceSchemaFromState(state)}
|
|
312
447
|
}
|
|
313
|
-
Note: If "imageParams", "voiceArgs", or "
|
|
448
|
+
Note: If "imageParams", "voiceArgs", "stateUpdate", or "triggerEvent" are not needed, set their values to null instead of omitting the keys completely (e.g., "imageParams": null). Output MUST be ONLY valid JSON with no markdown block wrappers. CRITICAL: Ensure your JSON has exactly one root object \`{\` and ends with exactly one \`}\` without any trailing garbage or extra brackets.`;
|
|
314
449
|
const promptMessages = [
|
|
315
450
|
{ role: "system", content: systemPrompt },
|
|
316
451
|
...(params.history || []),
|
|
@@ -322,7 +457,7 @@ Note: If "imageParams", "voiceArgs", or "stateUpdate" are not needed, set their
|
|
|
322
457
|
];
|
|
323
458
|
// 3. Local Execute LLM
|
|
324
459
|
const rawLlmResponse = await this.llm.generate(promptMessages, 1500, 0.7);
|
|
325
|
-
console.
|
|
460
|
+
// console.debug("[CyberSoulClient] Raw LLM Response:", rawLlmResponse);
|
|
326
461
|
let parsedIntent;
|
|
327
462
|
try {
|
|
328
463
|
parsedIntent = robustJsonParse(rawLlmResponse, "Dispatcher fallback");
|
|
@@ -334,7 +469,7 @@ Note: If "imageParams", "voiceArgs", or "stateUpdate" are not needed, set their
|
|
|
334
469
|
textResponse: rawLlmResponse.replace(/^[\`\s]+|[\`\s]+$/g, "").trim(),
|
|
335
470
|
};
|
|
336
471
|
}
|
|
337
|
-
console.
|
|
472
|
+
// console.debug("[CyberSoulClient] Parsed Intent:", parsedIntent);
|
|
338
473
|
// 4. Update Backend State async
|
|
339
474
|
if (parsedIntent && parsedIntent.stateUpdate) {
|
|
340
475
|
this._updateDynamicContextInternal(parsedIntent.stateUpdate);
|
|
@@ -348,6 +483,17 @@ Note: If "imageParams", "voiceArgs", or "stateUpdate" are not needed, set their
|
|
|
348
483
|
let finalImageUrl = undefined;
|
|
349
484
|
let finalAudioUrl = undefined;
|
|
350
485
|
let finalDurationSec = undefined;
|
|
486
|
+
// Output Event Trigger
|
|
487
|
+
if (isAuto && parsedIntent.triggerEvent) {
|
|
488
|
+
mediaTasks.push(this.apiFetch("/api/v1/cyber-soul/characters/ondemand-event", {
|
|
489
|
+
method: "POST",
|
|
490
|
+
body: JSON.stringify({
|
|
491
|
+
eventDescription: parsedIntent.triggerEvent.eventDescription,
|
|
492
|
+
durationMins: parsedIntent.triggerEvent.durationMins || 60,
|
|
493
|
+
outfitId: parsedIntent.triggerEvent.outfitId || undefined,
|
|
494
|
+
}),
|
|
495
|
+
}).catch(e => console.error("[CyberSoulClient] Auto-triggered ondemandEvent failed:", e)));
|
|
496
|
+
}
|
|
351
497
|
const shouldGenerateImage = types.includes(InteractRequestType.IMAGE) ||
|
|
352
498
|
(isAuto && !!parsedIntent.imageParams);
|
|
353
499
|
if (shouldGenerateImage) {
|
|
@@ -377,6 +523,7 @@ Note: If "imageParams", "voiceArgs", or "stateUpdate" are not needed, set their
|
|
|
377
523
|
imageUrl: finalImageUrl,
|
|
378
524
|
audioUrl: finalAudioUrl,
|
|
379
525
|
durationSec: finalDurationSec,
|
|
526
|
+
triggeredEvent: parsedIntent.triggerEvent || undefined,
|
|
380
527
|
};
|
|
381
528
|
}
|
|
382
529
|
catch (error) {
|
|
@@ -28,7 +28,7 @@ export class MinimaxProvider {
|
|
|
28
28
|
throw new Error(`MiniMax API returned status: ${response.status}`);
|
|
29
29
|
}
|
|
30
30
|
const data = await response.json();
|
|
31
|
-
console.
|
|
31
|
+
// console.debug("[MinimaxProvider] API Response Payload:", data);
|
|
32
32
|
if (data?.base_resp?.status_code && data.base_resp.status_code !== 0) {
|
|
33
33
|
throw new Error(`MiniMax SDK Error [${data.base_resp.status_code}]: ${data.base_resp.status_msg}`);
|
|
34
34
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -24,12 +24,36 @@ export interface InteractParams {
|
|
|
24
24
|
}[];
|
|
25
25
|
onTextReady?: (textResponse: string) => void;
|
|
26
26
|
}
|
|
27
|
+
export interface OndemandEventParams {
|
|
28
|
+
eventDescription: string;
|
|
29
|
+
durationMins?: number;
|
|
30
|
+
interactParams?: InteractParams;
|
|
31
|
+
}
|
|
32
|
+
export interface OndemandEventResponse {
|
|
33
|
+
status: 'success' | 'error';
|
|
34
|
+
acceptEvent?: boolean;
|
|
35
|
+
reason?: string;
|
|
36
|
+
requiresOutfitChange?: boolean;
|
|
37
|
+
selectedOutfitId?: string;
|
|
38
|
+
error?: string;
|
|
39
|
+
}
|
|
40
|
+
export interface WardrobeItem {
|
|
41
|
+
id: string;
|
|
42
|
+
itemName: string;
|
|
43
|
+
category: string;
|
|
44
|
+
promptModifier: string;
|
|
45
|
+
}
|
|
27
46
|
export interface InteractResponse {
|
|
28
47
|
status: 'success' | 'error';
|
|
29
48
|
textResponse: string;
|
|
30
49
|
imageUrl?: string;
|
|
31
50
|
audioUrl?: string;
|
|
32
51
|
durationSec?: number;
|
|
52
|
+
triggeredEvent?: {
|
|
53
|
+
eventDescription: string;
|
|
54
|
+
durationMins?: number;
|
|
55
|
+
outfitId?: string | null;
|
|
56
|
+
};
|
|
33
57
|
error?: string;
|
|
34
58
|
}
|
|
35
59
|
export interface DispatcherIntent {
|
|
@@ -42,6 +66,11 @@ export interface DispatcherIntent {
|
|
|
42
66
|
agentNickname?: string;
|
|
43
67
|
talkingStyle?: string;
|
|
44
68
|
};
|
|
69
|
+
triggerEvent?: {
|
|
70
|
+
eventDescription: string;
|
|
71
|
+
durationMins?: number;
|
|
72
|
+
outfitId?: string | null;
|
|
73
|
+
} | null;
|
|
45
74
|
}
|
|
46
75
|
export interface CoreMemory {
|
|
47
76
|
relationshipStatus: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@space3-npm/cybersoul-client",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -28,6 +28,9 @@
|
|
|
28
28
|
"author": "Space3 Digital Media Tech Studio",
|
|
29
29
|
"license": "MIT",
|
|
30
30
|
"description": "Cyber-Soul multimodal character interaction SDK by Space3 Digital Media Tech Studio",
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=18.0.0"
|
|
33
|
+
},
|
|
31
34
|
"devDependencies": {
|
|
32
35
|
"@types/node": "^25.6.0",
|
|
33
36
|
"ts-node": "^10.9.2",
|