@space3-npm/cybersoul-client 1.3.7 → 1.3.9
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/client.d.ts +4 -5
- package/dist/client.js +57 -26
- package/dist/types.d.ts +1 -0
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CyberSoulClientConfig, InteractParams, ProactiveParams, ProactiveResponse, OndemandEventParams, OndemandEventResponse, DispatcherIntent, InteractResponse, CharacterState, CoreMemory, UserCodex, LikedPicture } from "./types.js";
|
|
1
|
+
import { CyberSoulClientConfig, InteractParams, ProactiveParams, ProactiveResponse, OndemandEventParams, OndemandEventResponse, DispatcherIntent, InteractResponse, CharacterState, CoreMemory, UserCodex, HistoryEntry, LikedPicture } from "./types.js";
|
|
2
2
|
export declare class CyberSoulClient {
|
|
3
3
|
private config;
|
|
4
4
|
private llm;
|
|
@@ -16,6 +16,7 @@ export declare class CyberSoulClient {
|
|
|
16
16
|
private generatePrimitive;
|
|
17
17
|
private _updateDynamicContextInternal;
|
|
18
18
|
private normalizeRequestTypes;
|
|
19
|
+
private getElapsedTimeInfo;
|
|
19
20
|
private buildStateContextPrompt;
|
|
20
21
|
private normalizeOngoingSceneState;
|
|
21
22
|
private getImageSchemaParams;
|
|
@@ -41,6 +42,7 @@ export declare class CyberSoulClient {
|
|
|
41
42
|
* If the payload is already the inner args object (no voiceArgs wrapper), uses it as-is.
|
|
42
43
|
*/
|
|
43
44
|
private extractVoiceArgsFromLlmResponse;
|
|
45
|
+
private formatHistoryEntries;
|
|
44
46
|
private buildHistoryTranscript;
|
|
45
47
|
interact(params: InteractParams): Promise<InteractResponse>;
|
|
46
48
|
/**
|
|
@@ -96,10 +98,7 @@ export declare class CyberSoulClient {
|
|
|
96
98
|
* Automatically detect and summarize the story from the current chat history.
|
|
97
99
|
* It takes raw message history and returns a narrative paragraph representing the current story segment.
|
|
98
100
|
*/
|
|
99
|
-
summarizeHistory(history:
|
|
100
|
-
role: string;
|
|
101
|
-
content: string;
|
|
102
|
-
}[]): Promise<string>;
|
|
101
|
+
summarizeHistory(history: HistoryEntry[]): Promise<string>;
|
|
103
102
|
/**
|
|
104
103
|
* Save the recent story moment to the character's backend database to be picked up by the core memory consolidation.
|
|
105
104
|
*/
|
package/dist/client.js
CHANGED
|
@@ -154,6 +154,23 @@ export class CyberSoulClient {
|
|
|
154
154
|
}
|
|
155
155
|
return normalized;
|
|
156
156
|
}
|
|
157
|
+
getElapsedTimeInfo(currentTimeMs, lastInteractionAt) {
|
|
158
|
+
const elapsedMs = Math.max(0, currentTimeMs - new Date(lastInteractionAt).getTime());
|
|
159
|
+
const elapsedMins = elapsedMs / (1000 * 60);
|
|
160
|
+
const elapsedHours = elapsedMins / 60;
|
|
161
|
+
const elapsedDays = elapsedHours / 24;
|
|
162
|
+
const elapsedYears = elapsedDays / 365;
|
|
163
|
+
let displayStr = "";
|
|
164
|
+
if (elapsedYears >= 1)
|
|
165
|
+
displayStr = `${elapsedYears.toFixed(1)} years`;
|
|
166
|
+
else if (elapsedDays >= 1)
|
|
167
|
+
displayStr = `${elapsedDays.toFixed(1)} days`;
|
|
168
|
+
else if (elapsedHours >= 1)
|
|
169
|
+
displayStr = `${elapsedHours.toFixed(1)} hours`;
|
|
170
|
+
else
|
|
171
|
+
displayStr = `${Math.floor(elapsedMins)} mins`;
|
|
172
|
+
return { elapsedMs, elapsedMins, elapsedHours, elapsedDays, elapsedYears, displayStr };
|
|
173
|
+
}
|
|
157
174
|
buildStateContextPrompt(state, isProactive = false) {
|
|
158
175
|
const dyn = state.dynamic_context || {};
|
|
159
176
|
const stage = state.relationship_stage || "NEUTRAL";
|
|
@@ -180,28 +197,18 @@ Current time: ${new Date(currentTimeMs).toLocaleString("zh-CN", { timeZone: "Asi
|
|
|
180
197
|
const scenePrefix = "Last Known Scene";
|
|
181
198
|
let timeAgoStr = scenePrefix;
|
|
182
199
|
let isOutdated = false;
|
|
183
|
-
let
|
|
200
|
+
let timeDisplayStr = "";
|
|
184
201
|
if (dyn.lastInteractionAt) {
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
const elapsedYears = elapsedDays / 365;
|
|
190
|
-
if (elapsedYears >= 1)
|
|
191
|
-
timeAgoStr = `${scenePrefix} ${elapsedYears.toFixed(1)} years ago`;
|
|
192
|
-
else if (elapsedDays >= 1)
|
|
193
|
-
timeAgoStr = `${scenePrefix} ${elapsedDays.toFixed(1)} days ago`;
|
|
194
|
-
else if (elapsedHours >= 1)
|
|
195
|
-
timeAgoStr = `${scenePrefix} ${elapsedHours.toFixed(1)} hours ago`;
|
|
196
|
-
else
|
|
197
|
-
timeAgoStr = `${scenePrefix} ${Math.floor(elapsedMins)} mins ago`;
|
|
198
|
-
if (elapsedHours > 1) {
|
|
202
|
+
const timeInfo = this.getElapsedTimeInfo(currentTimeMs, dyn.lastInteractionAt);
|
|
203
|
+
timeDisplayStr = timeInfo.displayStr;
|
|
204
|
+
timeAgoStr = `${scenePrefix} ${timeDisplayStr} ago`;
|
|
205
|
+
if (timeInfo.elapsedHours > 1) {
|
|
199
206
|
isOutdated = true;
|
|
200
207
|
}
|
|
201
208
|
}
|
|
202
209
|
const lastKnownSceneLine = `${timeAgoStr}: ${ongoingScene.scene} | Outfit: ${ongoingScene.outfit}`;
|
|
203
210
|
if (isOutdated) {
|
|
204
|
-
contextParts.push(
|
|
211
|
+
contextParts.push(`Previous Activity (Ended ${timeDisplayStr} ago): ${ongoingScene.scene}\n[SCENE RESET]: A significant amount of time has passed. The previous activity is completely over. You are now in a fresh, natural state based on your current Wardrobe and Time. Do NOT continue the previous actions.`);
|
|
205
212
|
}
|
|
206
213
|
else {
|
|
207
214
|
contextParts.push(`${lastKnownSceneLine} (Evaluate whether this scene is still valid based on how much time has passed since it was last updated.)`);
|
|
@@ -335,7 +342,7 @@ ${isProactive
|
|
|
335
342
|
return `When generating a triggerEvent, you MUST provide a suitable 'triggerEvent.outfitId' if the VERY LAST USER MESSAGE explicitly asks for an outfit change, OR if the new activity implies a context/location shift that conflicts with the current outfit (e.g., currently in SLEEPWEAR at home but going outside). Otherwise, keep it null. When changing outfits, match it to the event's activity, environment, and relationship stage (e.g., CASUAL, COSTUME, INTIMATE, SLEEPWEAR, etc.).`;
|
|
336
343
|
}
|
|
337
344
|
getTriggerEventPolicyPrompt() {
|
|
338
|
-
return `- Include 'triggerEvent' only if the VERY LAST USER MESSAGE proposes a new activity/hangout, explicitly requests an outfit change, or proposes intimate/romantic actions; ignore older history. ${this.getOutfitSelectionPrompt()}`;
|
|
345
|
+
return `- Include 'triggerEvent' only if the VERY LAST USER MESSAGE proposes a new activity/hangout AND you accept the invitation, explicitly requests an outfit change AND you agree, or proposes intimate/romantic actions AND you agree; ignore older history. DO NOT include it if you decline or reject the proposal. ${this.getOutfitSelectionPrompt()}`;
|
|
339
346
|
}
|
|
340
347
|
getOutfitAcquisitionPolicyPrompt() {
|
|
341
348
|
return `- Outfit acquisition (VERY LAST USER MESSAGE only): set giftOutfit for gift/buy/add-clothes intent; otherwise null. giftOutfit format: { "descriptionText": "short outfit description" }.`;
|
|
@@ -400,20 +407,44 @@ ${isProactive
|
|
|
400
407
|
}
|
|
401
408
|
return payload;
|
|
402
409
|
}
|
|
410
|
+
formatHistoryEntries(history, userName, agentName, promptDirective = "") {
|
|
411
|
+
const contextLines = [];
|
|
412
|
+
for (let i = 0; i < history.length; i++) {
|
|
413
|
+
const msg = history[i];
|
|
414
|
+
if (i > 0 && history[i - 1].timestamp && msg.timestamp) {
|
|
415
|
+
const prevTime = new Date(history[i - 1].timestamp).getTime();
|
|
416
|
+
const currTime = new Date(msg.timestamp).getTime();
|
|
417
|
+
const timeInfo = this.getElapsedTimeInfo(currTime, prevTime);
|
|
418
|
+
if (timeInfo.elapsedHours > 1) {
|
|
419
|
+
contextLines.push(`\n[--- ${timeInfo.displayStr} later ---${promptDirective ? " " + promptDirective : ""} ---]\n`);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
const speaker = msg.role === 'user' ? userName : (msg.role === 'assistant' || msg.role === 'agent' ? agentName : msg.role);
|
|
423
|
+
const content = typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content);
|
|
424
|
+
const action = msg.actionText ? ` (${msg.actionText})` : "";
|
|
425
|
+
const media = msg.mediaHint ? ` [${msg.mediaHint}]` : "";
|
|
426
|
+
contextLines.push(`${speaker}:${action} ${content}${media}`);
|
|
427
|
+
}
|
|
428
|
+
return contextLines.join('\n');
|
|
429
|
+
}
|
|
403
430
|
buildHistoryTranscript(history, state) {
|
|
404
431
|
if (!history || history.length === 0)
|
|
405
432
|
return "";
|
|
406
433
|
const recentHistory = history.slice(-20);
|
|
407
434
|
const agentName = state.dynamic_context?.agentNickname || state.name || "Agent";
|
|
408
435
|
const userName = state.dynamic_context?.userNickname || "User";
|
|
409
|
-
const
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
436
|
+
const directive = "The previous chat history is completely outdated by the time passage. Do not continue its immediate action flow.";
|
|
437
|
+
const transcript = this.formatHistoryEntries(recentHistory, userName, agentName, directive);
|
|
438
|
+
let historyContent = `[CHAT HISTORY]\n${transcript}\n`;
|
|
439
|
+
// If there is a massive time gap between the chat history and the VERY LAST USER MESSAGE
|
|
440
|
+
if (state.dynamic_context?.lastInteractionAt) {
|
|
441
|
+
const currentTimeMs = state.current_time ? new Date(state.current_time).getTime() : Date.now();
|
|
442
|
+
const timeInfo = this.getElapsedTimeInfo(currentTimeMs, state.dynamic_context.lastInteractionAt);
|
|
443
|
+
if (timeInfo.elapsedHours > 1) {
|
|
444
|
+
historyContent += `\n[--- ${timeInfo.displayStr} later --- The previous chat history is completely outdated by the time passage. Do not continue its immediate action flow. ---]\n`;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
return historyContent + "\n";
|
|
417
448
|
}
|
|
418
449
|
async interact(params) {
|
|
419
450
|
try {
|
|
@@ -1016,7 +1047,7 @@ Output strictly valid JSON ONLY. No markdown, no conversational filler. Return e
|
|
|
1016
1047
|
const state = await this.getState();
|
|
1017
1048
|
const userName = state.dynamic_context?.userNickname || "User";
|
|
1018
1049
|
const agentName = state.dynamic_context?.agentNickname || "Character";
|
|
1019
|
-
const transcript =
|
|
1050
|
+
const transcript = this.formatHistoryEntries(history, userName, agentName);
|
|
1020
1051
|
const promptMessages = [
|
|
1021
1052
|
{
|
|
1022
1053
|
role: "system",
|
package/dist/types.d.ts
CHANGED