@space3-npm/cybersoul-client 1.1.1 → 1.1.2
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 +3 -1
- package/dist/client.js +133 -34
- package/dist/types.d.ts +65 -1
- package/package.json +2 -2
package/dist/client.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ export declare class CyberSoulClient {
|
|
|
4
4
|
private llm;
|
|
5
5
|
private cachedWardrobeStr;
|
|
6
6
|
private cachedWardrobeTime;
|
|
7
|
+
private requestTimeoutMs;
|
|
8
|
+
private maxRetries;
|
|
7
9
|
constructor(config: CyberSoulClientConfig);
|
|
8
10
|
/**
|
|
9
11
|
* Internal wrapper for fetch that automatically injects the backend URL and Character Auth token.
|
|
@@ -40,7 +42,7 @@ export declare class CyberSoulClient {
|
|
|
40
42
|
/**
|
|
41
43
|
* Updates the character's relationship temperature or mood.
|
|
42
44
|
*/
|
|
43
|
-
updateDynamicContext(stateUpdate: DispatcherIntent["stateUpdate"]): Promise<void>;
|
|
45
|
+
updateDynamicContext(stateUpdate: DispatcherIntent["stateUpdate"], userAnalysis?: DispatcherIntent["userAnalysis"]): Promise<void>;
|
|
44
46
|
/**
|
|
45
47
|
* Manually generate an image of the character outside of chat flow.
|
|
46
48
|
*/
|
package/dist/client.js
CHANGED
|
@@ -6,8 +6,12 @@ export class CyberSoulClient {
|
|
|
6
6
|
llm;
|
|
7
7
|
cachedWardrobeStr = null;
|
|
8
8
|
cachedWardrobeTime = 0;
|
|
9
|
+
requestTimeoutMs;
|
|
10
|
+
maxRetries;
|
|
9
11
|
constructor(config) {
|
|
10
12
|
this.config = config;
|
|
13
|
+
this.requestTimeoutMs = config.requestTimeoutMs ?? 15000;
|
|
14
|
+
this.maxRetries = Math.max(0, config.maxRetries ?? 1);
|
|
11
15
|
// Setup Provider
|
|
12
16
|
if (config.llmConfig.provider === "minimax") {
|
|
13
17
|
this.llm = new MinimaxProvider(config.llmConfig);
|
|
@@ -26,39 +30,112 @@ export class CyberSoulClient {
|
|
|
26
30
|
"Content-Type": "application/json",
|
|
27
31
|
...(options.headers || {}),
|
|
28
32
|
};
|
|
29
|
-
|
|
33
|
+
const method = (options.method || "GET").toUpperCase();
|
|
34
|
+
const isIdempotent = method === "GET" || method === "HEAD";
|
|
35
|
+
const retryLimit = isIdempotent ? this.maxRetries : 0;
|
|
36
|
+
let lastError;
|
|
37
|
+
for (let attempt = 0; attempt <= retryLimit; attempt++) {
|
|
38
|
+
const controller = new AbortController();
|
|
39
|
+
const timeout = setTimeout(() => controller.abort(), this.requestTimeoutMs);
|
|
40
|
+
try {
|
|
41
|
+
const response = await fetch(url, {
|
|
42
|
+
...options,
|
|
43
|
+
headers,
|
|
44
|
+
signal: controller.signal,
|
|
45
|
+
});
|
|
46
|
+
// Retry transient server-side failures only for idempotent methods.
|
|
47
|
+
if (response.status >= 500 && attempt < retryLimit) {
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
return response;
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
lastError = error;
|
|
54
|
+
if (attempt >= retryLimit) {
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
finally {
|
|
59
|
+
clearTimeout(timeout);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
throw lastError instanceof Error
|
|
63
|
+
? lastError
|
|
64
|
+
: new Error("Request failed unexpectedly");
|
|
30
65
|
}
|
|
31
66
|
buildStateContextPrompt(state, localContext) {
|
|
67
|
+
const dyn = state.dynamic_context || {};
|
|
68
|
+
const stage = state.relationship_stage || "NEUTRAL";
|
|
69
|
+
const temperature = dyn.temperature ?? 50;
|
|
32
70
|
const contextParts = [];
|
|
71
|
+
// [1] CORE IDENTITY & PHYSICAL CONTEXT
|
|
72
|
+
contextParts.push(`[CORE IDENTITY]
|
|
73
|
+
Name: ${state.name}
|
|
74
|
+
Demographics: Age ${state.age || "unknown"}, Gender ${state.gender || "unknown"}, Occupation ${state.occupation || "unknown"}
|
|
75
|
+
Hobby: ${state.hobby || "unknown"}
|
|
76
|
+
Personality Traits: ${state.personality_traits || "None"}
|
|
77
|
+
Communication Style: ${state.communication_style || "None"}
|
|
78
|
+
Interaction Boundaries: ${state.interaction_boundaries || "None"}`);
|
|
79
|
+
// [2] SITUATIONAL CONTEXT
|
|
80
|
+
contextParts.push(`\n[SITUATIONAL CONTEXT]
|
|
81
|
+
Current time: ${new Date(state.current_time || Date.now()).toLocaleString("zh-CN", { timeZone: "Asia/Shanghai" })}`);
|
|
33
82
|
if (state.active_event) {
|
|
34
|
-
contextParts.push(
|
|
83
|
+
contextParts.push(`Active Event: ${state.active_event.title} (${state.active_event.narrative_context})`);
|
|
35
84
|
}
|
|
36
85
|
if (state.next_event) {
|
|
37
|
-
contextParts.push(
|
|
86
|
+
contextParts.push(`Next Event: ${state.next_event.title} at ${state.next_event.start_time} (in ${state.next_event.time_until_mins} mins)`);
|
|
38
87
|
}
|
|
39
88
|
if (state.active_wardrobe) {
|
|
40
|
-
contextParts.push(
|
|
89
|
+
contextParts.push(`Wardrobe: ${state.active_wardrobe.name || state.active_wardrobe.id || "Current"}`);
|
|
41
90
|
}
|
|
42
|
-
const dyn = state.dynamic_context || {};
|
|
43
|
-
const stage = state.relationship_stage || "NEUTRAL";
|
|
44
|
-
contextParts.push(`- Relationship Info (Stage: ${stage}): You call the user '${dyn.userNickname || "User"}'. The user calls you '${dyn.agentNickname || "Agent"}'. Mood: ${dyn.talkingStyle || "Normal"}. Temp (0-100): ${dyn.temperature || 50}.`);
|
|
45
91
|
if (localContext) {
|
|
46
|
-
contextParts.push(
|
|
92
|
+
contextParts.push(`Additional Context: ${localContext}`);
|
|
93
|
+
}
|
|
94
|
+
// [3] USER CODEX (Relationships dynamically evaluated)
|
|
95
|
+
if (state.user_codex) {
|
|
96
|
+
const { basicInfo, psychological, familiarityScore = 0 } = state.user_codex;
|
|
97
|
+
contextParts.push(`\n[USER CODEX] (What you know about the user)
|
|
98
|
+
Familiarity Score: ${Math.round(familiarityScore)}/100 (0=Stranger, >10=Acquaintance, >40=Warm, >60=Intimate)
|
|
99
|
+
Occupation: ${basicInfo?.occupation || "Unknown"}
|
|
100
|
+
Age/Gender: ${basicInfo?.age || "Unknown"} / ${basicInfo?.gender || "Unknown"}
|
|
101
|
+
Comm Style: ${psychological?.communicationStyle || "Unknown"}
|
|
102
|
+
Hobbies: ${(psychological?.hobbies || []).join(", ") || "Unknown"}
|
|
103
|
+
Traits/Boundaries: ${(psychological?.traits || []).join(", ") || "Unknown"} / ${(psychological?.boundaries || []).join(", ") || "Unknown"}`);
|
|
104
|
+
// CURIOSITY DRIVE: Find what's missing, but ONLY IF we are on generally warm speaking terms
|
|
105
|
+
// Paradox avoidance: A cold/angry character shouldn't enthusiastically fish for hobbies.
|
|
106
|
+
if (temperature >= 40 && stage !== "COLD" && stage !== "STRANGER") {
|
|
107
|
+
const missingFacts = [];
|
|
108
|
+
if (!basicInfo?.occupation)
|
|
109
|
+
missingFacts.push("their job or occupation");
|
|
110
|
+
if (!psychological?.hobbies || psychological.hobbies.length === 0)
|
|
111
|
+
missingFacts.push("their hobbies or what they do for fun");
|
|
112
|
+
if (!basicInfo?.age || !basicInfo?.gender)
|
|
113
|
+
missingFacts.push("some basic personal details about them");
|
|
114
|
+
if (!psychological?.traits || psychological.traits.length === 0)
|
|
115
|
+
missingFacts.push("their personality traits");
|
|
116
|
+
if (missingFacts.length > 0) {
|
|
117
|
+
contextParts.push(`\n[CURIOUSITY DRIVE]
|
|
118
|
+
Because you are warm and curious, whenever natural in conversation, subtly ask about or fish for info regarding: ${missingFacts.slice(0, 2).join(" and ")}.`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
47
121
|
}
|
|
122
|
+
// [4] RELATIONAL DYNAMICS & INERTIA
|
|
123
|
+
contextParts.push(`\n[RELATIONSHIP DYNAMICS]
|
|
124
|
+
Stage: ${stage}
|
|
125
|
+
Temperature (Mood): ${temperature}/100 (0=Angry/Cold, 50=Normal, 100=Passionate)
|
|
126
|
+
Addressing: You call them '${dyn.userNickname || "User"}'. They call you '${dyn.agentNickname || "Agent"}'.
|
|
127
|
+
Current Mood Constraint: ${dyn.talkingStyle || "Normal"}`);
|
|
48
128
|
const scenarioContext = contextParts.join("\n");
|
|
49
|
-
return `You are ${state.name}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
Relationship stage: ${state.relationship_stage}
|
|
54
|
-
Personality Traits: ${state.personality_traits || "None"}
|
|
55
|
-
Interaction Boundaries: ${state.interaction_boundaries || "None"}
|
|
56
|
-
Communication Style: ${state.communication_style || "None"}
|
|
129
|
+
return `You are ${state.name}. You are a real person with your own thoughts, feelings, and life.
|
|
130
|
+
You are NOT an AI, an assistant, or a language model. NEVER break character, and NEVER refer to yourself as an AI, bot, or virtual assistant.
|
|
131
|
+
|
|
132
|
+
${scenarioContext}
|
|
57
133
|
|
|
58
|
-
|
|
59
|
-
1.
|
|
60
|
-
2.
|
|
61
|
-
3.
|
|
134
|
+
[CRITICAL ROLEPLAY & INERTIA RULES]
|
|
135
|
+
1. RULE OF TEMPERATURE OVERRIDES FAMILIARITY (Identity vs Mood): Familiarity determines HOW MUCH you know about them. Temperature determines HOW YOU FEEL right now. If Familiarity is 100 but Temperature is 10, you know everything about them but are currently ice-cold or annoyed. Act distant. Do NOT act warm just because you know them well.
|
|
136
|
+
2. CONVERSATIONAL VERBOSITY: If Temperature is low (< 40) or Stage is STRANGER/COLD, KEEP IT BRIEF. Reply with simple, short, or single-word answers. An angry or distant person does not write long paragraphs.
|
|
137
|
+
3. EMOTIONAL INERTIA: React strictly according to the current Stage and Temperature. If the user expresses sudden high affection (e.g. "I miss you") but your Stage/Temperature is COLD, you MUST react with skepticism or deflection. Do NOT instantly melt or become warm.
|
|
138
|
+
4. NATURAL PACE: Emotional mood shifts (temperature changes) must be slow. The 'temperatureDelta' should rarely exceed +/- 5 points per turn.`;
|
|
62
139
|
}
|
|
63
140
|
getImageSchemaParams() {
|
|
64
141
|
return `"imageParams": {
|
|
@@ -222,8 +299,8 @@ CRITICAL: Output MUST be ONLY valid JSON with no markdown block wrappers. Do NOT
|
|
|
222
299
|
/**
|
|
223
300
|
* Updates the character's relationship temperature or mood.
|
|
224
301
|
*/
|
|
225
|
-
async updateDynamicContext(stateUpdate) {
|
|
226
|
-
return this._updateDynamicContextInternal(stateUpdate);
|
|
302
|
+
async updateDynamicContext(stateUpdate, userAnalysis) {
|
|
303
|
+
return this._updateDynamicContextInternal(stateUpdate, userAnalysis);
|
|
227
304
|
}
|
|
228
305
|
/**
|
|
229
306
|
* Manually generate an image of the character outside of chat flow.
|
|
@@ -366,11 +443,14 @@ Output strictly valid JSON ONLY. No markdown, no conversational filler. Return e
|
|
|
366
443
|
this.cachedWardrobeTime = now;
|
|
367
444
|
return availableOutfits;
|
|
368
445
|
}
|
|
369
|
-
async _updateDynamicContextInternal(stateUpdate) {
|
|
370
|
-
if (!stateUpdate)
|
|
446
|
+
async _updateDynamicContextInternal(stateUpdate, userAnalysis) {
|
|
447
|
+
if (!stateUpdate && !userAnalysis)
|
|
371
448
|
return;
|
|
372
449
|
// Map TS schema intent (temperatureDelta) to match Backend payload schema (temperature)
|
|
373
450
|
const payload = { ...stateUpdate };
|
|
451
|
+
if (userAnalysis) {
|
|
452
|
+
payload.userAnalysis = userAnalysis;
|
|
453
|
+
}
|
|
374
454
|
if (payload.temperatureDelta !== undefined) {
|
|
375
455
|
payload.temperature = payload.temperatureDelta;
|
|
376
456
|
delete payload.temperatureDelta;
|
|
@@ -434,18 +514,21 @@ ${isAuto
|
|
|
434
514
|
- If the user wants to hear you, or if appropriate for a voice message, include 'voiceArgs'.
|
|
435
515
|
- 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.`
|
|
436
516
|
: `Requested types to fulfill: ${types.join(", ")}`}
|
|
437
|
-
|
|
517
|
+
Every turn of positive or engaging interaction should slightly increase trust (+1). If the interaction is negative, -1. If strictly neutral, 0. You MUST ALWAYS include a 'stateUpdate' block with a 'temperatureDelta', updating nicknames or talkingStyle if needed. Temperature goes from 0 (cold/angry) to 100 (obsessively in love). For 'temperatureDelta', output an integer (e.g. 1, -2, 0).
|
|
518
|
+
Also, if you learn any new factual information about the user in this turn (e.g. their job, nickname, age, hobbies, boundaries), include it in the 'userAnalysis.newFactsLearned' array. Use categories: 'nickname', 'occupation', 'age', 'gender', 'hobby', 'trait', 'communicationStyle', 'boundary'. Only include NEW facts just learned right now.
|
|
519
|
+
|
|
438
520
|
Voice direction for voiceArgs: ${this.getVoiceDirectorInstruction(state)}
|
|
439
521
|
|
|
440
522
|
Output JSON Schema:
|
|
441
523
|
{
|
|
442
524
|
"textResponse": "The direct spoken dialogue in Chinese",
|
|
443
|
-
"stateUpdate": { "temperatureDelta":
|
|
525
|
+
"stateUpdate": { "temperatureDelta": 1, "userNickname": "What you now call the user", "agentNickname": "What the user calls you", "talkingStyle": "Current mood/style of talking" },
|
|
526
|
+
"userAnalysis": { "newFactsLearned": [{ "category": "occupation", "value": "Software Engineer" }] },
|
|
444
527
|
"triggerEvent": { "eventDescription": "Going to a cafe", "durationMins": 60, "outfitId": "optional wardrobe ID to change into if appropriate" },
|
|
445
528
|
${this.getImageSchemaParams()},
|
|
446
529
|
${this.getVoiceSchemaFromState(state)}
|
|
447
530
|
}
|
|
448
|
-
Note: If "imageParams", "voiceArgs", "
|
|
531
|
+
Note: If "imageParams", "voiceArgs", "triggerEvent", or "userAnalysis" are not needed, set their values to null instead of omitting the keys. 'stateUpdate' MUST NEVER BE 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.`;
|
|
449
532
|
const promptMessages = [
|
|
450
533
|
{ role: "system", content: systemPrompt },
|
|
451
534
|
...(params.history || []),
|
|
@@ -471,12 +554,16 @@ Note: If "imageParams", "voiceArgs", "stateUpdate", or "triggerEvent" are not ne
|
|
|
471
554
|
}
|
|
472
555
|
// console.debug("[CyberSoulClient] Parsed Intent:", parsedIntent);
|
|
473
556
|
// 4. Update Backend State async
|
|
474
|
-
if (parsedIntent && parsedIntent.stateUpdate) {
|
|
475
|
-
this._updateDynamicContextInternal(parsedIntent.stateUpdate);
|
|
557
|
+
if (parsedIntent && (parsedIntent.stateUpdate || parsedIntent.userAnalysis)) {
|
|
558
|
+
this._updateDynamicContextInternal(parsedIntent.stateUpdate, parsedIntent.userAnalysis);
|
|
476
559
|
}
|
|
560
|
+
const resolvedTextResponse = typeof parsedIntent.textResponse === "string" &&
|
|
561
|
+
parsedIntent.textResponse.trim().length > 0
|
|
562
|
+
? parsedIntent.textResponse
|
|
563
|
+
: params.userMessage;
|
|
477
564
|
// Fire text ready callback if provided
|
|
478
|
-
if (params.onTextReady &&
|
|
479
|
-
params.onTextReady(
|
|
565
|
+
if (params.onTextReady && resolvedTextResponse) {
|
|
566
|
+
params.onTextReady(resolvedTextResponse);
|
|
480
567
|
}
|
|
481
568
|
// 5. Build Final Media Calls parallel
|
|
482
569
|
const mediaTasks = [];
|
|
@@ -497,7 +584,13 @@ Note: If "imageParams", "voiceArgs", "stateUpdate", or "triggerEvent" are not ne
|
|
|
497
584
|
const shouldGenerateImage = types.includes(InteractRequestType.IMAGE) ||
|
|
498
585
|
(isAuto && !!parsedIntent.imageParams);
|
|
499
586
|
if (shouldGenerateImage) {
|
|
500
|
-
|
|
587
|
+
const imagePayload = parsedIntent.imageParams && typeof parsedIntent.imageParams === "object"
|
|
588
|
+
? parsedIntent.imageParams
|
|
589
|
+
: {
|
|
590
|
+
mode: "full-prompt",
|
|
591
|
+
full_prompt: resolvedTextResponse,
|
|
592
|
+
};
|
|
593
|
+
mediaTasks.push(this.generatePrimitive("image", imagePayload).then((res) => {
|
|
501
594
|
finalImageUrl = res.image_url;
|
|
502
595
|
}));
|
|
503
596
|
}
|
|
@@ -507,8 +600,12 @@ Note: If "imageParams", "voiceArgs", "stateUpdate", or "triggerEvent" are not ne
|
|
|
507
600
|
const normalizedVoiceArgs = parsedIntent.voiceArgs && typeof parsedIntent.voiceArgs === "object"
|
|
508
601
|
? parsedIntent.voiceArgs
|
|
509
602
|
: {};
|
|
603
|
+
const textForVoice = typeof resolvedTextResponse === "string" &&
|
|
604
|
+
resolvedTextResponse.trim().length > 0
|
|
605
|
+
? resolvedTextResponse
|
|
606
|
+
: "...";
|
|
510
607
|
mediaTasks.push(this.generatePrimitive("voice", {
|
|
511
|
-
text:
|
|
608
|
+
text: textForVoice,
|
|
512
609
|
dynamicArgs: normalizedVoiceArgs,
|
|
513
610
|
}).then((res) => {
|
|
514
611
|
finalAudioUrl = res.audio_url;
|
|
@@ -519,11 +616,13 @@ Note: If "imageParams", "voiceArgs", "stateUpdate", or "triggerEvent" are not ne
|
|
|
519
616
|
await Promise.all(mediaTasks);
|
|
520
617
|
return {
|
|
521
618
|
status: "success",
|
|
522
|
-
textResponse:
|
|
619
|
+
textResponse: resolvedTextResponse || "...",
|
|
523
620
|
imageUrl: finalImageUrl,
|
|
524
621
|
audioUrl: finalAudioUrl,
|
|
525
622
|
durationSec: finalDurationSec,
|
|
526
623
|
triggeredEvent: parsedIntent.triggerEvent || undefined,
|
|
624
|
+
stateUpdate: parsedIntent.stateUpdate,
|
|
625
|
+
userAnalysis: parsedIntent.userAnalysis,
|
|
527
626
|
};
|
|
528
627
|
}
|
|
529
628
|
catch (error) {
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export interface LLMConfig {
|
|
2
|
-
provider: 'minimax'
|
|
2
|
+
provider: 'minimax';
|
|
3
3
|
apiKey: string;
|
|
4
4
|
model: string;
|
|
5
5
|
}
|
|
@@ -7,6 +7,8 @@ export interface CyberSoulClientConfig {
|
|
|
7
7
|
characterKey: string;
|
|
8
8
|
backendUrl: string;
|
|
9
9
|
llmConfig: LLMConfig;
|
|
10
|
+
requestTimeoutMs?: number;
|
|
11
|
+
maxRetries?: number;
|
|
10
12
|
}
|
|
11
13
|
export declare enum InteractRequestType {
|
|
12
14
|
AUTO = "auto",
|
|
@@ -54,12 +56,20 @@ export interface InteractResponse {
|
|
|
54
56
|
durationMins?: number;
|
|
55
57
|
outfitId?: string | null;
|
|
56
58
|
};
|
|
59
|
+
stateUpdate?: DispatcherIntent['stateUpdate'];
|
|
60
|
+
userAnalysis?: DispatcherIntent['userAnalysis'];
|
|
57
61
|
error?: string;
|
|
58
62
|
}
|
|
59
63
|
export interface DispatcherIntent {
|
|
60
64
|
textResponse?: string;
|
|
61
65
|
imageParams?: any;
|
|
62
66
|
voiceArgs?: VoiceArgs | null;
|
|
67
|
+
userAnalysis?: {
|
|
68
|
+
newFactsLearned: {
|
|
69
|
+
category: "nickname" | "occupation" | "age" | "gender" | "hobby" | "trait" | "communicationStyle" | "boundary";
|
|
70
|
+
value: string;
|
|
71
|
+
}[];
|
|
72
|
+
};
|
|
63
73
|
stateUpdate?: {
|
|
64
74
|
temperatureDelta?: string | number;
|
|
65
75
|
userNickname?: string;
|
|
@@ -122,6 +132,7 @@ export interface CharacterState {
|
|
|
122
132
|
personality_traits?: string;
|
|
123
133
|
interaction_boundaries?: string;
|
|
124
134
|
communication_style?: string;
|
|
135
|
+
user_codex?: any;
|
|
125
136
|
}
|
|
126
137
|
export interface BaseLLMProvider {
|
|
127
138
|
generate(messages: {
|
|
@@ -129,3 +140,56 @@ export interface BaseLLMProvider {
|
|
|
129
140
|
content: string;
|
|
130
141
|
}[], maxTokens?: number, temperature?: number): Promise<string>;
|
|
131
142
|
}
|
|
143
|
+
export type ModelCustomConfigValueType = 'string' | 'stringArray' | 'number' | 'integer' | 'boolean' | 'enum';
|
|
144
|
+
export interface IModelCustomConfigField {
|
|
145
|
+
key: string;
|
|
146
|
+
label: string;
|
|
147
|
+
valueType: ModelCustomConfigValueType;
|
|
148
|
+
customerFacing?: boolean;
|
|
149
|
+
isFile?: boolean;
|
|
150
|
+
description?: string;
|
|
151
|
+
required?: boolean;
|
|
152
|
+
defaultValue?: string | number | boolean | string[];
|
|
153
|
+
minItems?: number;
|
|
154
|
+
maxItems?: number;
|
|
155
|
+
min?: number;
|
|
156
|
+
max?: number;
|
|
157
|
+
step?: number;
|
|
158
|
+
enumOptions?: string[];
|
|
159
|
+
options?: string[];
|
|
160
|
+
}
|
|
161
|
+
export interface IVoiceModel {
|
|
162
|
+
id: string;
|
|
163
|
+
name: string;
|
|
164
|
+
ttsProvider: string;
|
|
165
|
+
voiceConfigPayload: Record<string, unknown>;
|
|
166
|
+
dynamicParamPromptTemplate: string;
|
|
167
|
+
dynamicParams: Array<{
|
|
168
|
+
name: string;
|
|
169
|
+
description: string;
|
|
170
|
+
type: string;
|
|
171
|
+
required: boolean;
|
|
172
|
+
default?: unknown;
|
|
173
|
+
}>;
|
|
174
|
+
voiceOptions: Array<{
|
|
175
|
+
id: string;
|
|
176
|
+
name: string;
|
|
177
|
+
description?: string;
|
|
178
|
+
configPatch: Record<string, unknown>;
|
|
179
|
+
dynamicParamPromptTemplate?: string;
|
|
180
|
+
sampleUrl?: string;
|
|
181
|
+
}>;
|
|
182
|
+
voiceCustomConfigDefinition?: IModelCustomConfigField[];
|
|
183
|
+
isPublic: boolean;
|
|
184
|
+
pointsPerGeneration: number;
|
|
185
|
+
}
|
|
186
|
+
export interface ICharacterProfile {
|
|
187
|
+
id: string;
|
|
188
|
+
name: string;
|
|
189
|
+
voiceModelId?: string;
|
|
190
|
+
voiceModelOptionId?: string;
|
|
191
|
+
voiceCustomConfig?: Record<string, Record<string, unknown>>;
|
|
192
|
+
visualModelId?: string;
|
|
193
|
+
visualCustomConfig?: Record<string, Record<string, unknown>>;
|
|
194
|
+
[key: string]: unknown;
|
|
195
|
+
}
|
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.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"scripts": {
|
|
18
18
|
"build": "tsc",
|
|
19
19
|
"prepare": "npm run build",
|
|
20
|
-
"test": "
|
|
20
|
+
"test": "node -e \"console.log('No tests defined yet')\""
|
|
21
21
|
},
|
|
22
22
|
"keywords": [
|
|
23
23
|
"cybersoul",
|