briyah 1.1.5 → 1.1.8
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/data/common/config/image_models.json +141 -21
- package/data/common/config/image_models_full.json +135 -48
- package/data/common/config/markup +1 -1
- package/data/common/config/story_models.json +41 -38
- package/data/common/prompts/character/progress_character.prompt +4 -0
- package/data/common/prompts/character/update_portrait.prompt +31 -0
- package/data/common/prompts/narrator/perceive.prompt +23 -1
- package/data/common/prompts/narrator/progress_plot.prompt +1 -3
- package/data/common/prompts/story_moderator/moderate.json +36 -29
- package/data/common/prompts/story_moderator/moderate.prompt +63 -18
- package/dist-sdk/server/src/ai/LLM/base-ai.service.d.ts +5 -7
- package/dist-sdk/server/src/ai/LLM/base-ai.service.js +7 -1
- package/dist-sdk/server/src/ai/LLM/fal.service.d.ts +5 -1
- package/dist-sdk/server/src/ai/LLM/fal.service.js +93 -21
- package/dist-sdk/server/src/ai/LLM/googleai.service.d.ts +1 -1
- package/dist-sdk/server/src/ai/LLM/googleai.service.js +20 -29
- package/dist-sdk/server/src/ai/LLM/openai.service.d.ts +5 -1
- package/dist-sdk/server/src/ai/LLM/openai.service.js +58 -71
- package/dist-sdk/server/src/ai/LLM/together.service.d.ts +5 -1
- package/dist-sdk/server/src/ai/LLM/together.service.js +57 -31
- package/dist-sdk/server/src/ai/agent-config.d.ts +1 -0
- package/dist-sdk/server/src/ai/agent-store.service.js +4 -0
- package/dist-sdk/server/src/ai/agent.d.ts +8 -1
- package/dist-sdk/server/src/ai/agent.js +21 -3
- package/dist-sdk/server/src/ai/model_prices.js +21 -1
- package/dist-sdk/server/src/app.controller.d.ts +4 -0
- package/dist-sdk/server/src/app.controller.js +51 -1
- package/dist-sdk/server/src/app.service.d.ts +3 -1
- package/dist-sdk/server/src/app.service.js +22 -14
- package/dist-sdk/server/src/room/message.d.ts +1 -0
- package/dist-sdk/server/src/room/message.js +1 -0
- package/dist-sdk/server/src/room/room-store.service.d.ts +1 -0
- package/dist-sdk/server/src/room/room-store.service.js +3 -0
- package/dist-sdk/server/src/room/room.d.ts +3 -0
- package/dist-sdk/server/src/room/room.js +27 -7
- package/dist-sdk/server/src/sdk/briyah-config.d.ts +1 -0
- package/dist-sdk/server/src/sdk/briyah-config.js +4 -0
- package/dist-sdk/server/src/story/story-store.service.d.ts +1 -0
- package/dist-sdk/server/src/story/story-store.service.js +38 -0
- package/dist-sdk/server/src/story/story.service.d.ts +4 -1
- package/dist-sdk/server/src/story/story.service.js +233 -55
- package/dist-sdk/shared/types/app.types.d.ts +17 -0
- package/docs/assets/hierarchy.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/Agent.html +19 -15
- package/docs/classes/Briyah.html +12 -12
- package/docs/classes/BriyahConfigService.html +5 -5
- package/docs/classes/Room.html +26 -24
- package/docs/classes/RoomMessage.html +11 -10
- package/docs/enums/MessageAction.html +3 -3
- package/docs/hierarchy.html +1 -1
- package/docs/index.html +2 -2
- package/docs/interfaces/AgentInfo.html +2 -2
- package/docs/interfaces/AgentMessagesResponse.html +2 -2
- package/docs/interfaces/AppService.html +128 -113
- package/docs/interfaces/Artifact.html +3 -3
- package/docs/interfaces/ArtifactMetadata.html +2 -2
- package/docs/interfaces/AttachDocumentResponse.html +2 -2
- package/docs/interfaces/BriyahConfigOptions.html +9 -6
- package/docs/interfaces/ChapterInfo.html +2 -2
- package/docs/interfaces/Character.html +2 -2
- package/docs/interfaces/CreateAgentResponse.html +2 -2
- package/docs/interfaces/CreateRoomResponse.html +2 -2
- package/docs/interfaces/CreateStoryResponse.html +2 -2
- package/docs/interfaces/FileList.html +2 -2
- package/docs/interfaces/LoggingOptions.html +5 -5
- package/docs/interfaces/Message.html +2 -2
- package/docs/interfaces/ModelInfo.html +3 -2
- package/docs/interfaces/PreparedPromptResponse.html +2 -2
- package/docs/interfaces/ProcessTextResponse.html +2 -2
- package/docs/interfaces/PromptFile.html +2 -2
- package/docs/interfaces/PromptFileContent.html +2 -2
- package/docs/interfaces/PromptFilesResponse.html +2 -2
- package/docs/interfaces/PromptFolder.html +2 -2
- package/docs/interfaces/PromptFoldersResponse.html +2 -2
- package/docs/interfaces/RoomDetails.html +2 -2
- package/docs/interfaces/RoomInfo.html +2 -2
- package/docs/interfaces/RoomMessagesResponse.html +2 -2
- package/docs/interfaces/StoryErrorEvent.html +3 -3
- package/docs/interfaces/StoryIdea.html +2 -2
- package/docs/interfaces/StoryInfo.html +5 -3
- package/docs/interfaces/StoryIntroduceCharacterEvent.html +3 -3
- package/docs/interfaces/StoryProgressChapterEvent.html +3 -3
- package/docs/interfaces/StoryState.html +5 -5
- package/docs/interfaces/StoryStateEvent.html +3 -3
- package/docs/interfaces/Transaction.html +2 -2
- package/docs/interfaces/TransactionHistoryResponse.html +2 -2
- package/docs/modules.html +1 -1
- package/docs/types/PromptScope.html +1 -1
- package/package.json +1 -1
|
@@ -12,7 +12,11 @@ export declare class TogetherAiService extends BaseAiService {
|
|
|
12
12
|
textPrompt(agent: Agent, prompt: string, jsonSchema?: any, saveResponse?: boolean, promptInstructions?: string, _cacheConfig?: any, maxOutputChars?: number): Promise<any>;
|
|
13
13
|
private computeMessageCost;
|
|
14
14
|
private computeImageCost;
|
|
15
|
-
generateImage(agent: Agent, prompt: string,
|
|
15
|
+
generateImage(agent: Agent, prompt: string, imageProperties?: Record<string, any>): Promise<{
|
|
16
|
+
artifactId?: string;
|
|
17
|
+
error?: any;
|
|
18
|
+
}>;
|
|
19
|
+
editImage(agent: Agent, prompt: string, imageProperties?: Record<string, any>, referenceImageArtifactIds?: string[]): Promise<{
|
|
16
20
|
artifactId?: string;
|
|
17
21
|
error?: any;
|
|
18
22
|
}>;
|
|
@@ -182,10 +182,18 @@ let TogetherAiService = class TogetherAiService extends base_ai_service_1.BaseAi
|
|
|
182
182
|
agent.balanceService.decrementBalance(cost, markup);
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
|
-
computeImageCost(agent, usage) {
|
|
185
|
+
computeImageCost(agent, usage, centsPerImage) {
|
|
186
186
|
const modelInfo = (0, model_prices_1.getModelPrices)()[agent.modelName];
|
|
187
187
|
if (!modelInfo) {
|
|
188
|
-
|
|
188
|
+
if (centsPerImage != null) {
|
|
189
|
+
const cost = centsPerImage / 100;
|
|
190
|
+
agent.totalCost += cost;
|
|
191
|
+
logger_1.logger.log(`Image cost for ${agent.agentName}: $${cost.toFixed(4)}`);
|
|
192
|
+
if (agent.balanceService && cost > 0)
|
|
193
|
+
agent.balanceService.decrementBalance(cost, 0);
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
logger_1.logger.warn(`No price info found for model ${agent.modelName}. Skipping cost tracking.`);
|
|
189
197
|
return;
|
|
190
198
|
}
|
|
191
199
|
const inputImageTokens = usage.input_tokens_details?.image_tokens || 0;
|
|
@@ -235,7 +243,12 @@ let TogetherAiService = class TogetherAiService extends base_ai_service_1.BaseAi
|
|
|
235
243
|
agent.balanceService.decrementBalance(cost, markup);
|
|
236
244
|
}
|
|
237
245
|
}
|
|
238
|
-
async generateImage(agent, prompt,
|
|
246
|
+
async generateImage(agent, prompt, imageProperties) {
|
|
247
|
+
const { centsPerImage, ...apiProperties } = imageProperties ?? {};
|
|
248
|
+
const modelInfo = (0, model_prices_1.getModelPrices)()[agent.modelName];
|
|
249
|
+
if (!modelInfo && centsPerImage == null) {
|
|
250
|
+
return { error: `No pricing configured for image model "${agent.modelName}". Add a modelPrices entry or set centsPerImage in image_models.json.` };
|
|
251
|
+
}
|
|
239
252
|
if (agent.balanceService && !agent.disableBalanceCheck) {
|
|
240
253
|
const hasSufficientBalance = agent.balanceService.hasSufficientBalance();
|
|
241
254
|
if (!hasSufficientBalance) {
|
|
@@ -243,34 +256,13 @@ let TogetherAiService = class TogetherAiService extends base_ai_service_1.BaseAi
|
|
|
243
256
|
}
|
|
244
257
|
}
|
|
245
258
|
try {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
height: height,
|
|
254
|
-
width: width,
|
|
255
|
-
n: 1,
|
|
256
|
-
disable_safety_checker: true,
|
|
257
|
-
response_format: 'base64',
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
else {
|
|
261
|
-
imageResponse = await this.togetherClient.images.generate({
|
|
262
|
-
model: agent.modelName,
|
|
263
|
-
prompt: prompt,
|
|
264
|
-
height: height,
|
|
265
|
-
width: width,
|
|
266
|
-
n: 1,
|
|
267
|
-
disable_safety_checker: true,
|
|
268
|
-
response_format: 'base64',
|
|
269
|
-
});
|
|
270
|
-
}
|
|
271
|
-
if (imageResponse.usage) {
|
|
272
|
-
this.computeImageCost(agent, imageResponse.usage);
|
|
273
|
-
}
|
|
259
|
+
const imageResponse = await this.togetherClient.images.generate({
|
|
260
|
+
...apiProperties,
|
|
261
|
+
model: agent.modelName,
|
|
262
|
+
prompt,
|
|
263
|
+
n: 1,
|
|
264
|
+
});
|
|
265
|
+
this.computeImageCost(agent, imageResponse.usage, centsPerImage);
|
|
274
266
|
const base64Data = imageResponse.data[0].b64_json;
|
|
275
267
|
const artifactId = await this.saveImageAsArtifact(agent, base64Data, prompt);
|
|
276
268
|
return { artifactId };
|
|
@@ -281,6 +273,40 @@ let TogetherAiService = class TogetherAiService extends base_ai_service_1.BaseAi
|
|
|
281
273
|
return { error };
|
|
282
274
|
}
|
|
283
275
|
}
|
|
276
|
+
async editImage(agent, prompt, imageProperties, referenceImageArtifactIds) {
|
|
277
|
+
const { centsPerImage, ...apiProperties } = imageProperties ?? {};
|
|
278
|
+
const modelInfo = (0, model_prices_1.getModelPrices)()[agent.modelName];
|
|
279
|
+
if (!modelInfo && centsPerImage == null) {
|
|
280
|
+
return { error: `No pricing configured for image model "${agent.modelName}". Add a modelPrices entry or set centsPerImage in image_models.json.` };
|
|
281
|
+
}
|
|
282
|
+
if (agent.balanceService && !agent.disableBalanceCheck) {
|
|
283
|
+
const hasSufficientBalance = agent.balanceService.hasSufficientBalance();
|
|
284
|
+
if (!hasSufficientBalance) {
|
|
285
|
+
throw new errors_1.InsufficientBalanceError('Insufficient balance for image generation. Please add funds to continue.');
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
try {
|
|
289
|
+
const referenceImages = referenceImageArtifactIds?.length
|
|
290
|
+
? await this.loadReferenceImages(agent, referenceImageArtifactIds)
|
|
291
|
+
: [];
|
|
292
|
+
const imageResponse = await this.togetherClient.images.generate({
|
|
293
|
+
...apiProperties,
|
|
294
|
+
reference_image: referenceImages.length === 1 ? referenceImages[0] : referenceImages,
|
|
295
|
+
model: agent.modelName,
|
|
296
|
+
prompt,
|
|
297
|
+
n: 1,
|
|
298
|
+
});
|
|
299
|
+
this.computeImageCost(agent, imageResponse.usage, centsPerImage);
|
|
300
|
+
const base64Data = imageResponse.data[0].b64_json;
|
|
301
|
+
const artifactId = await this.saveImageAsArtifact(agent, base64Data, prompt);
|
|
302
|
+
return { artifactId };
|
|
303
|
+
}
|
|
304
|
+
catch (error) {
|
|
305
|
+
logger_1.logger.error('Error editing image:', error.error?.message || error.message);
|
|
306
|
+
logger_1.logger.log(prompt);
|
|
307
|
+
return { error };
|
|
308
|
+
}
|
|
309
|
+
}
|
|
284
310
|
};
|
|
285
311
|
exports.TogetherAiService = TogetherAiService;
|
|
286
312
|
exports.TogetherAiService = TogetherAiService = __decorate([
|
|
@@ -143,6 +143,7 @@ let AgentStoreService = class AgentStoreService {
|
|
|
143
143
|
instance.maxHistoryMessages = template.maxHistoryMessages;
|
|
144
144
|
instance.promptCacheTTL = template.promptCacheTTL;
|
|
145
145
|
instance.markupRate = template.markupRate;
|
|
146
|
+
instance.smallModelName = template.smallModelName;
|
|
146
147
|
this.storeAgent(instance);
|
|
147
148
|
return instanceId;
|
|
148
149
|
}
|
|
@@ -174,6 +175,7 @@ let AgentStoreService = class AgentStoreService {
|
|
|
174
175
|
instance.promptFolder = template.promptFolder;
|
|
175
176
|
instance.systemInstruction = template.systemInstruction;
|
|
176
177
|
instance.modelName = template.modelName;
|
|
178
|
+
instance.smallModelName = template.smallModelName;
|
|
177
179
|
instance.serviceName = template.serviceName;
|
|
178
180
|
instance.reasoningEffort = template.reasoningEffort;
|
|
179
181
|
instance.allowSearch = template.allowSearch;
|
|
@@ -234,6 +236,7 @@ let AgentStoreService = class AgentStoreService {
|
|
|
234
236
|
const agent = new agent_1.Agent(config.id, this.configService, this, this.balanceService, finalArtifactService, config.agentName, config.agentNickname || config.agentName, config.description, config.promptFolder, config.systemInstruction, config.history || [], config.modelName, config.serviceName, aiService, config.reasoningEffort, config.allowSearch, config.maxOutputTokens, config.beginInstruction || '', storageDir);
|
|
235
237
|
agent.createdAt = new Date(config.createdAt);
|
|
236
238
|
agent.configService = this.configService;
|
|
239
|
+
agent.smallModelName = config.smallModelName;
|
|
237
240
|
agent.totalInputTokens = config.totalInputTokens || 0;
|
|
238
241
|
agent.totalOutputTokens = config.totalOutputTokens || 0;
|
|
239
242
|
agent.totalCost = config.totalCost || 0;
|
|
@@ -305,6 +308,7 @@ let AgentStoreService = class AgentStoreService {
|
|
|
305
308
|
promptFolder: agent.promptFolder,
|
|
306
309
|
systemInstruction: agent.systemInstruction,
|
|
307
310
|
modelName: agent.modelName,
|
|
311
|
+
smallModelName: agent.smallModelName,
|
|
308
312
|
serviceName: agent.serviceName,
|
|
309
313
|
reasoningEffort: agent.reasoningEffort,
|
|
310
314
|
allowSearch: agent.allowSearch,
|
|
@@ -38,7 +38,9 @@ export declare class Agent {
|
|
|
38
38
|
systemInstruction: string;
|
|
39
39
|
maxHistoryMessages?: number;
|
|
40
40
|
modelName: string;
|
|
41
|
+
smallModelName?: string;
|
|
41
42
|
serviceName: string;
|
|
43
|
+
imageProperties?: Record<string, any>;
|
|
42
44
|
reasoningEffort: 'low' | 'medium' | 'high' | null;
|
|
43
45
|
allowSearch: boolean;
|
|
44
46
|
maxOutputTokens: number;
|
|
@@ -67,6 +69,7 @@ export declare class Agent {
|
|
|
67
69
|
trimHistoryIfNeeded(threshold?: number): void;
|
|
68
70
|
instructedPrompt(prompt: string, instructionFileName: string, variables: any, saveResponse?: boolean, cacheMessage?: boolean, maxOutputChars?: number): Promise<any>;
|
|
69
71
|
preparedPrompt(promptFileName: string, variables: any, saveResponse?: boolean, cacheMessage?: boolean): Promise<any>;
|
|
72
|
+
withSmallModel<T>(fn: () => Promise<T>): Promise<T>;
|
|
70
73
|
compact(): Promise<{
|
|
71
74
|
success: boolean;
|
|
72
75
|
originalLength: number;
|
|
@@ -75,7 +78,11 @@ export declare class Agent {
|
|
|
75
78
|
summary?: string;
|
|
76
79
|
}>;
|
|
77
80
|
textPrompt(prompt: string, jsonSchema?: any, saveResponse?: boolean, promptInstructions?: string, cacheMessage?: boolean, maxOutputChars?: number): Promise<any>;
|
|
78
|
-
generateImage(prompt: string
|
|
81
|
+
generateImage(prompt: string): Promise<{
|
|
82
|
+
artifactId?: string;
|
|
83
|
+
error?: any;
|
|
84
|
+
}>;
|
|
85
|
+
editImage(prompt: string, referenceImageArtifactIds?: string[]): Promise<{
|
|
79
86
|
artifactId?: string;
|
|
80
87
|
error?: any;
|
|
81
88
|
}>;
|
|
@@ -36,7 +36,9 @@ class Agent {
|
|
|
36
36
|
systemInstruction;
|
|
37
37
|
maxHistoryMessages;
|
|
38
38
|
modelName;
|
|
39
|
+
smallModelName;
|
|
39
40
|
serviceName;
|
|
41
|
+
imageProperties;
|
|
40
42
|
reasoningEffort;
|
|
41
43
|
allowSearch;
|
|
42
44
|
maxOutputTokens = 0;
|
|
@@ -164,6 +166,19 @@ class Agent {
|
|
|
164
166
|
async preparedPrompt(promptFileName, variables, saveResponse = true, cacheMessage = false) {
|
|
165
167
|
return await this.aiService.preparedPrompt(this, promptFileName, variables, saveResponse, this.aiService.getCacheConfig(this, cacheMessage));
|
|
166
168
|
}
|
|
169
|
+
async withSmallModel(fn) {
|
|
170
|
+
if (!this.smallModelName || this.smallModelName === this.modelName) {
|
|
171
|
+
return fn();
|
|
172
|
+
}
|
|
173
|
+
const original = this.modelName;
|
|
174
|
+
this.modelName = this.smallModelName;
|
|
175
|
+
try {
|
|
176
|
+
return await fn();
|
|
177
|
+
}
|
|
178
|
+
finally {
|
|
179
|
+
this.modelName = original;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
167
182
|
async compact() {
|
|
168
183
|
const originalHistory = [...(this.history || [])];
|
|
169
184
|
const originalLength = originalHistory.length;
|
|
@@ -178,7 +193,7 @@ class Agent {
|
|
|
178
193
|
const formattedHistory = this.getFormattedMessages(0);
|
|
179
194
|
try {
|
|
180
195
|
this.history = [];
|
|
181
|
-
const summaryResponse = await this.preparedPrompt('compact_agent', { agentName: this.agentNickname, formattedHistory }, false);
|
|
196
|
+
const summaryResponse = await this.withSmallModel(() => this.preparedPrompt('compact_agent', { agentName: this.agentNickname, formattedHistory }, false));
|
|
182
197
|
const summary = summaryResponse?.summary || summaryResponse;
|
|
183
198
|
this.addToConversationHistory(`[CONVERSATION HISTORY SUMMARY]\n\n${summary}`, true);
|
|
184
199
|
const newLength = this.history.length;
|
|
@@ -199,8 +214,11 @@ class Agent {
|
|
|
199
214
|
async textPrompt(prompt, jsonSchema = null, saveResponse = true, promptInstructions = null, cacheMessage = false, maxOutputChars = 0) {
|
|
200
215
|
return await this.aiService.textPrompt(this, prompt, jsonSchema, saveResponse, promptInstructions, this.aiService.getCacheConfig(this, cacheMessage), maxOutputChars);
|
|
201
216
|
}
|
|
202
|
-
async generateImage(prompt
|
|
203
|
-
return await this.aiService.generateImage(this, prompt,
|
|
217
|
+
async generateImage(prompt) {
|
|
218
|
+
return await this.aiService.generateImage(this, prompt, this.imageProperties);
|
|
219
|
+
}
|
|
220
|
+
async editImage(prompt, referenceImageArtifactIds) {
|
|
221
|
+
return await this.aiService.editImage(this, prompt, this.imageProperties, referenceImageArtifactIds);
|
|
204
222
|
}
|
|
205
223
|
}
|
|
206
224
|
exports.Agent = Agent;
|
|
@@ -39,6 +39,24 @@ exports.isKnownModel = isKnownModel;
|
|
|
39
39
|
const fs = __importStar(require("fs"));
|
|
40
40
|
const path = __importStar(require("path"));
|
|
41
41
|
let _modelPrices = null;
|
|
42
|
+
let _imageModels = null;
|
|
43
|
+
function getImageModels() {
|
|
44
|
+
if (_imageModels !== null)
|
|
45
|
+
return _imageModels;
|
|
46
|
+
const dataDir = process.env.BRIYAH_DATA_PATH || path.resolve(process.cwd(), 'briyah-data');
|
|
47
|
+
const imageModelsPath = path.join(dataDir, 'common', 'config', 'image_models.json');
|
|
48
|
+
if (!fs.existsSync(imageModelsPath)) {
|
|
49
|
+
_imageModels = [];
|
|
50
|
+
return _imageModels;
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
_imageModels = JSON.parse(fs.readFileSync(imageModelsPath, 'utf8'));
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
_imageModels = [];
|
|
57
|
+
}
|
|
58
|
+
return _imageModels;
|
|
59
|
+
}
|
|
42
60
|
function getModelPrices() {
|
|
43
61
|
if (_modelPrices !== null)
|
|
44
62
|
return _modelPrices;
|
|
@@ -69,5 +87,7 @@ function resolveModelInfo(modelName, prefix) {
|
|
|
69
87
|
return null;
|
|
70
88
|
}
|
|
71
89
|
function isKnownModel(modelName, prefix) {
|
|
72
|
-
|
|
90
|
+
if (resolveModelInfo(modelName, prefix) !== null)
|
|
91
|
+
return true;
|
|
92
|
+
return getImageModels().some((m) => m.model === modelName && m.centsPerImage != null);
|
|
73
93
|
}
|
|
@@ -129,6 +129,7 @@ export declare class AppController {
|
|
|
129
129
|
getPublishedRoomInstances(req: ExpressRequest, templateId: string): Promise<RoomInfo[]>;
|
|
130
130
|
resetPublishedRoomInstance(req: ExpressRequest, instanceId: string): Promise<void>;
|
|
131
131
|
resetStory(req: ExpressRequest, storyId: string): Promise<void>;
|
|
132
|
+
revertStoryChapter(req: ExpressRequest, storyId: string): Promise<void>;
|
|
132
133
|
getRoomArtifacts(req: ExpressRequest, roomId: string): Promise<{
|
|
133
134
|
artifacts: any[];
|
|
134
135
|
}>;
|
|
@@ -150,9 +151,11 @@ export declare class AppController {
|
|
|
150
151
|
idea: string;
|
|
151
152
|
userCharacterDesc: string;
|
|
152
153
|
otherCharactersDesc: string;
|
|
154
|
+
illustrateStory: boolean;
|
|
153
155
|
storyModel?: string;
|
|
154
156
|
isImport?: boolean;
|
|
155
157
|
imageModelName?: string;
|
|
158
|
+
imageEditModelName?: string;
|
|
156
159
|
}): Promise<StoryInfo>;
|
|
157
160
|
importStoryZip(req: ExpressRequest, file: Express.Multer.File): Promise<StoryInfo>;
|
|
158
161
|
deleteStory(req: ExpressRequest, storyId: string): Promise<void>;
|
|
@@ -164,6 +167,7 @@ export declare class AppController {
|
|
|
164
167
|
respondToStory(req: ExpressRequest, storyId: string, body: {
|
|
165
168
|
content: string;
|
|
166
169
|
}): Promise<void>;
|
|
170
|
+
interruptStory(req: ExpressRequest, storyId: string): Promise<void>;
|
|
167
171
|
introduceCharacter(req: ExpressRequest, storyId: string, body: {
|
|
168
172
|
name: string;
|
|
169
173
|
description?: string;
|
|
@@ -132,6 +132,7 @@ let AppController = class AppController {
|
|
|
132
132
|
return {
|
|
133
133
|
selectedStoryModel: process.env.DEFAULT_STORY_MODEL,
|
|
134
134
|
selectedImageModel: process.env.DEFAULT_IMAGE_MODEL,
|
|
135
|
+
selectedImageEditModel: process.env.DEFAULT_IMAGE_EDIT_MODEL,
|
|
135
136
|
enforceDefaultModels: process.env.ENFORCE_DEFAULT_MODELS === 'true',
|
|
136
137
|
};
|
|
137
138
|
}
|
|
@@ -1040,6 +1041,25 @@ let AppController = class AppController {
|
|
|
1040
1041
|
throw new common_1.HttpException('Failed to reset story', common_1.HttpStatus.INTERNAL_SERVER_ERROR);
|
|
1041
1042
|
}
|
|
1042
1043
|
}
|
|
1044
|
+
async revertStoryChapter(req, storyId) {
|
|
1045
|
+
if (!storyId) {
|
|
1046
|
+
throw new common_1.BadRequestException('Story ID is required');
|
|
1047
|
+
}
|
|
1048
|
+
try {
|
|
1049
|
+
const appService = this.getAppService(req);
|
|
1050
|
+
await appService.revertStoryChapter(storyId);
|
|
1051
|
+
}
|
|
1052
|
+
catch (error) {
|
|
1053
|
+
logger_1.logger.error(`[${req.user?.sub}] Error reverting chapter for story ${storyId}:`, error);
|
|
1054
|
+
if (error instanceof errors_1.NotFoundError) {
|
|
1055
|
+
throw new common_1.NotFoundException(error.message);
|
|
1056
|
+
}
|
|
1057
|
+
if (error instanceof errors_1.OperationFailedError) {
|
|
1058
|
+
throw new common_1.HttpException(error.message, common_1.HttpStatus.INTERNAL_SERVER_ERROR);
|
|
1059
|
+
}
|
|
1060
|
+
throw new common_1.HttpException('Failed to revert chapter', common_1.HttpStatus.INTERNAL_SERVER_ERROR);
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1043
1063
|
async getRoomArtifacts(req, roomId) {
|
|
1044
1064
|
try {
|
|
1045
1065
|
const appService = this.getAppService(req, undefined, roomId);
|
|
@@ -1134,7 +1154,7 @@ let AppController = class AppController {
|
|
|
1134
1154
|
}
|
|
1135
1155
|
try {
|
|
1136
1156
|
const appService = this.getAppService(req);
|
|
1137
|
-
return appService.createStory(body.name, body.idea, body.userCharacterDesc, body.otherCharactersDesc, body.storyModel, body.isImport, body.imageModelName);
|
|
1157
|
+
return appService.createStory(body.name, body.idea, body.userCharacterDesc, body.otherCharactersDesc, body.illustrateStory ?? true, body.storyModel, body.isImport, body.imageModelName, body.imageEditModelName);
|
|
1138
1158
|
}
|
|
1139
1159
|
catch (error) {
|
|
1140
1160
|
logger_1.logger.error(`[${req.user?.sub}] Error creating story ${body.name}:`, error);
|
|
@@ -1255,6 +1275,19 @@ let AppController = class AppController {
|
|
|
1255
1275
|
throw new common_1.HttpException(error.message || 'Failed to respond to story', common_1.HttpStatus.INTERNAL_SERVER_ERROR);
|
|
1256
1276
|
}
|
|
1257
1277
|
}
|
|
1278
|
+
async interruptStory(req, storyId) {
|
|
1279
|
+
try {
|
|
1280
|
+
const appService = this.getAppService(req);
|
|
1281
|
+
await appService.interruptStory(storyId);
|
|
1282
|
+
}
|
|
1283
|
+
catch (error) {
|
|
1284
|
+
logger_1.logger.error(`[${req.user?.sub}] Error interrupting story ${storyId}:`, error);
|
|
1285
|
+
if (error instanceof common_1.HttpException) {
|
|
1286
|
+
throw error;
|
|
1287
|
+
}
|
|
1288
|
+
throw new common_1.HttpException(error.message || 'Failed to interrupt story', common_1.HttpStatus.INTERNAL_SERVER_ERROR);
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1258
1291
|
async introduceCharacter(req, storyId, body) {
|
|
1259
1292
|
if (!body.name) {
|
|
1260
1293
|
throw new common_1.BadRequestException('Name is a required field');
|
|
@@ -2325,6 +2358,15 @@ __decorate([
|
|
|
2325
2358
|
__metadata("design:paramtypes", [Object, String]),
|
|
2326
2359
|
__metadata("design:returntype", Promise)
|
|
2327
2360
|
], AppController.prototype, "resetStory", null);
|
|
2361
|
+
__decorate([
|
|
2362
|
+
(0, common_1.Post)('stories/:storyId/revert'),
|
|
2363
|
+
(0, common_1.HttpCode)(common_1.HttpStatus.NO_CONTENT),
|
|
2364
|
+
__param(0, (0, common_1.Request)()),
|
|
2365
|
+
__param(1, (0, common_1.Param)('storyId')),
|
|
2366
|
+
__metadata("design:type", Function),
|
|
2367
|
+
__metadata("design:paramtypes", [Object, String]),
|
|
2368
|
+
__metadata("design:returntype", Promise)
|
|
2369
|
+
], AppController.prototype, "revertStoryChapter", null);
|
|
2328
2370
|
__decorate([
|
|
2329
2371
|
(0, room_access_decorator_1.RoomReadAccess)(),
|
|
2330
2372
|
(0, common_1.Get)('rooms/:roomId/artifacts'),
|
|
@@ -2448,6 +2490,14 @@ __decorate([
|
|
|
2448
2490
|
__metadata("design:paramtypes", [Object, String, Object]),
|
|
2449
2491
|
__metadata("design:returntype", Promise)
|
|
2450
2492
|
], AppController.prototype, "respondToStory", null);
|
|
2493
|
+
__decorate([
|
|
2494
|
+
(0, common_1.Post)('stories/:storyId/interrupt'),
|
|
2495
|
+
__param(0, (0, common_1.Request)()),
|
|
2496
|
+
__param(1, (0, common_1.Param)('storyId')),
|
|
2497
|
+
__metadata("design:type", Function),
|
|
2498
|
+
__metadata("design:paramtypes", [Object, String]),
|
|
2499
|
+
__metadata("design:returntype", Promise)
|
|
2500
|
+
], AppController.prototype, "interruptStory", null);
|
|
2451
2501
|
__decorate([
|
|
2452
2502
|
(0, common_1.Post)('stories/:storyId/characters'),
|
|
2453
2503
|
(0, common_1.HttpCode)(common_1.HttpStatus.CREATED),
|
|
@@ -115,7 +115,8 @@ export declare class AppService {
|
|
|
115
115
|
compactAgentConversation(agentId: string): Promise<void>;
|
|
116
116
|
resetRoom(roomId: string): Promise<void>;
|
|
117
117
|
resetStory(storyId: string): Promise<void>;
|
|
118
|
-
|
|
118
|
+
revertStoryChapter(storyId: string): Promise<void>;
|
|
119
|
+
createStory(name: string, idea: string, userCharacterDesc: string, otherCharactersDesc: string, illustrateStory: boolean, storyModel?: string, isImport?: boolean, imageModelName?: string, imageEditModelName?: string): Promise<StoryInfo>;
|
|
119
120
|
importStoryFromZip(zipBuffer: Buffer): Promise<StoryInfo>;
|
|
120
121
|
getStoryProgressEmitter(storyId: string): EventEmitter<any>;
|
|
121
122
|
getStoryMessageEmitter(storyId: string): EventEmitter<any>;
|
|
@@ -140,6 +141,7 @@ export declare class AppService {
|
|
|
140
141
|
getStoryState(storyId: string): Promise<StoryState>;
|
|
141
142
|
getStoryInfo(storyId: string): Promise<StoryInfo | undefined>;
|
|
142
143
|
respondToStory(storyId: string, content: string): Promise<void>;
|
|
144
|
+
interruptStory(storyId: string): Promise<void>;
|
|
143
145
|
introduceCharacterToStory(storyId: string, name: string, description: string, storyModel?: string, fromNarratorSuggestion?: boolean): Promise<void>;
|
|
144
146
|
declineCharacter(storyId: string, characterName: string): Promise<void>;
|
|
145
147
|
deleteCharacterFromStory(storyId: string, characterName: string): Promise<void>;
|
|
@@ -694,8 +694,7 @@ class AppService {
|
|
|
694
694
|
const allFiles = fs.readdirSync(targetDir);
|
|
695
695
|
const promptFiles = allFiles.filter((file) => file.endsWith('.prompt') || file.endsWith('.json'));
|
|
696
696
|
promptFiles.forEach((file) => {
|
|
697
|
-
|
|
698
|
-
fileMap.set(baseName, scope);
|
|
697
|
+
fileMap.set(file, scope);
|
|
699
698
|
});
|
|
700
699
|
};
|
|
701
700
|
scanDirectory(this.configService.getCommonPromptsDir(), 'common');
|
|
@@ -749,17 +748,20 @@ class AppService {
|
|
|
749
748
|
fs.writeFileSync(filePath, content);
|
|
750
749
|
}
|
|
751
750
|
deletePromptFile(folderName, fileName) {
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
751
|
+
const baseDir = this.configService.getUserPromptsDir();
|
|
752
|
+
const targetDir = folderName === 'shared' ? baseDir : path.join(baseDir, folderName);
|
|
753
|
+
const hasExtension = fileName.endsWith('.prompt') || fileName.endsWith('.json');
|
|
754
|
+
if (hasExtension) {
|
|
755
|
+
const filePath = path.join(targetDir, fileName);
|
|
756
|
+
if (fs.existsSync(filePath))
|
|
757
|
+
fs.unlinkSync(filePath);
|
|
759
758
|
}
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
759
|
+
else {
|
|
760
|
+
for (const ext of ['.prompt', '.json']) {
|
|
761
|
+
const filePath = path.join(targetDir, fileName + ext);
|
|
762
|
+
if (fs.existsSync(filePath))
|
|
763
|
+
fs.unlinkSync(filePath);
|
|
764
|
+
}
|
|
763
765
|
}
|
|
764
766
|
}
|
|
765
767
|
async getRoomArtifacts(roomId) {
|
|
@@ -967,8 +969,11 @@ class AppService {
|
|
|
967
969
|
logger_1.logger.warn(`Story "${storyName}" reset with warnings:`, warnings);
|
|
968
970
|
}
|
|
969
971
|
}
|
|
970
|
-
async
|
|
971
|
-
return this.storyService.
|
|
972
|
+
async revertStoryChapter(storyId) {
|
|
973
|
+
return this.storyService.revertStoryChapter(storyId);
|
|
974
|
+
}
|
|
975
|
+
async createStory(name, idea, userCharacterDesc, otherCharactersDesc, illustrateStory, storyModel, isImport, imageModelName, imageEditModelName) {
|
|
976
|
+
return this.storyService.createStory(name, idea, userCharacterDesc, otherCharactersDesc, illustrateStory, storyModel, isImport, imageModelName, imageEditModelName);
|
|
972
977
|
}
|
|
973
978
|
async importStoryFromZip(zipBuffer) {
|
|
974
979
|
return this.storyService.importStoryFromZip(zipBuffer);
|
|
@@ -1102,6 +1107,9 @@ class AppService {
|
|
|
1102
1107
|
async respondToStory(storyId, content) {
|
|
1103
1108
|
return this.storyService.respondToStory(storyId, content);
|
|
1104
1109
|
}
|
|
1110
|
+
async interruptStory(storyId) {
|
|
1111
|
+
return this.storyService.interruptStory(storyId);
|
|
1112
|
+
}
|
|
1105
1113
|
async introduceCharacterToStory(storyId, name, description, storyModel, fromNarratorSuggestion) {
|
|
1106
1114
|
await this.storyService.introduceCharacter(storyId, name, description, storyModel, fromNarratorSuggestion);
|
|
1107
1115
|
}
|
|
@@ -7,6 +7,7 @@ export declare class RoomMessage implements Message {
|
|
|
7
7
|
timestamp: Date;
|
|
8
8
|
name?: string;
|
|
9
9
|
situation?: string;
|
|
10
|
+
updatePortrait?: string[];
|
|
10
11
|
index?: number;
|
|
11
12
|
constructor(sender: string, action: MessageAction, content: string, targets?: string[], name?: string, situation?: string);
|
|
12
13
|
getSender(): string;
|
|
@@ -34,5 +34,6 @@ export declare class RoomStoreService {
|
|
|
34
34
|
saveArtifactFile(roomId: string, storageDir: string, artifact: Artifact): void;
|
|
35
35
|
deleteArtifactFile(roomId: string, storageDir: string, artifactName: string): boolean;
|
|
36
36
|
deleteAllArtifactFiles(roomId: string, storageDir: string): void;
|
|
37
|
+
loadArtifactFiles(roomId: string, storageDir: string): Artifact[];
|
|
37
38
|
private deleteRoomFile;
|
|
38
39
|
}
|
|
@@ -318,6 +318,9 @@ let RoomStoreService = class RoomStoreService {
|
|
|
318
318
|
deleteAllArtifactFiles(roomId, storageDir) {
|
|
319
319
|
this.artifactStoreService.deleteAllArtifacts(roomId, storageDir);
|
|
320
320
|
}
|
|
321
|
+
loadArtifactFiles(roomId, storageDir) {
|
|
322
|
+
return this.artifactStoreService.loadArtifacts(roomId, storageDir);
|
|
323
|
+
}
|
|
321
324
|
deleteRoomFile(roomId, storageDir, deleteAgents = false, room) {
|
|
322
325
|
try {
|
|
323
326
|
if (deleteAgents && room) {
|
|
@@ -23,6 +23,7 @@ export declare class Room {
|
|
|
23
23
|
private onError?;
|
|
24
24
|
private currentSituation;
|
|
25
25
|
private onSituationUpdate?;
|
|
26
|
+
private onModeratorResponseCallback?;
|
|
26
27
|
private templateRoomId;
|
|
27
28
|
private storageDir;
|
|
28
29
|
private roomStoreService;
|
|
@@ -93,6 +94,7 @@ export declare class Room {
|
|
|
93
94
|
getSituation(): string;
|
|
94
95
|
setSituation(situation: string): void;
|
|
95
96
|
setOnSituationUpdate(callback: (situation: string) => void): void;
|
|
97
|
+
setOnModeratorResponse(callback: (message: RoomMessage) => void): void;
|
|
96
98
|
private handleSituationUpdate;
|
|
97
99
|
handlePublishMessages(messages: RoomMessage[]): void;
|
|
98
100
|
handleExecuteMessages(messages: RoomMessage[]): void;
|
|
@@ -102,6 +104,7 @@ export declare class Room {
|
|
|
102
104
|
isProcessingInProgress(): boolean;
|
|
103
105
|
pause(): void;
|
|
104
106
|
resume(): void;
|
|
107
|
+
interrupt(): void;
|
|
105
108
|
checkAgentNicknameMatch(existingNickname: string, targetNickname: string): boolean;
|
|
106
109
|
private handleModeratorResponse;
|
|
107
110
|
private processPendingMessages;
|
|
@@ -29,6 +29,7 @@ class Room {
|
|
|
29
29
|
onError;
|
|
30
30
|
currentSituation = '';
|
|
31
31
|
onSituationUpdate;
|
|
32
|
+
onModeratorResponseCallback;
|
|
32
33
|
templateRoomId;
|
|
33
34
|
storageDir;
|
|
34
35
|
roomStoreService;
|
|
@@ -242,7 +243,11 @@ class Room {
|
|
|
242
243
|
return new message_1.RoomMessage(agent.agentNickname, app_types_1.MessageAction.MODERATE, content, [], null, situation);
|
|
243
244
|
}
|
|
244
245
|
situation = response.situation || undefined;
|
|
245
|
-
|
|
246
|
+
const msg = new message_1.RoomMessage(agent.agentNickname, normalizedAction, response.content, targets, response.name, situation);
|
|
247
|
+
if (Array.isArray(response.update_portrait) && response.update_portrait.length > 0) {
|
|
248
|
+
msg.updatePortrait = response.update_portrait;
|
|
249
|
+
}
|
|
250
|
+
return msg;
|
|
246
251
|
}
|
|
247
252
|
static coerceMessageAction(raw) {
|
|
248
253
|
if (typeof raw !== 'string')
|
|
@@ -484,6 +489,9 @@ Recent Message: ${message.getContent()}
|
|
|
484
489
|
setOnSituationUpdate(callback) {
|
|
485
490
|
this.onSituationUpdate = callback;
|
|
486
491
|
}
|
|
492
|
+
setOnModeratorResponse(callback) {
|
|
493
|
+
this.onModeratorResponseCallback = callback;
|
|
494
|
+
}
|
|
487
495
|
handleSituationUpdate(situation) {
|
|
488
496
|
logger_1.logger.log(`Situation updated: ${situation}`);
|
|
489
497
|
this.currentSituation = situation;
|
|
@@ -610,6 +618,10 @@ Recent Message: ${message.getContent()}
|
|
|
610
618
|
this.processPendingMessages();
|
|
611
619
|
}
|
|
612
620
|
}
|
|
621
|
+
interrupt() {
|
|
622
|
+
this.pendingMessages = [];
|
|
623
|
+
this.pause();
|
|
624
|
+
}
|
|
613
625
|
checkAgentNicknameMatch(existingNickname, targetNickname) {
|
|
614
626
|
if (existingNickname.toLowerCase() === targetNickname.toLowerCase())
|
|
615
627
|
return true;
|
|
@@ -625,6 +637,9 @@ Recent Message: ${message.getContent()}
|
|
|
625
637
|
const targets = moderatorMessage.targets || [];
|
|
626
638
|
if (!targets.includes(roomLeaderName))
|
|
627
639
|
targets.push(roomLeaderName);
|
|
640
|
+
if (this.onModeratorResponseCallback) {
|
|
641
|
+
this.onModeratorResponseCallback(moderatorMessage);
|
|
642
|
+
}
|
|
628
643
|
let content = moderatorMessage.content;
|
|
629
644
|
if (content && content.startsWith('relay'))
|
|
630
645
|
content = originalMessage.getContent();
|
|
@@ -659,13 +674,8 @@ Recent Message: ${message.getContent()}
|
|
|
659
674
|
let roomLeaderAgent = this.agents.find((a) => a.agentNickname === this.getRoomLeader());
|
|
660
675
|
if (!roomLeaderAgent)
|
|
661
676
|
throw new Error(`Room leader agent not found`);
|
|
662
|
-
logger_1.logger.warn(`Responder agent not found: ${
|
|
677
|
+
logger_1.logger.warn(`Responder agent "${responderNickname}" not found; falling back to room leader: ${roomLeaderAgent.agentNickname}`);
|
|
663
678
|
responderAgent = roomLeaderAgent;
|
|
664
|
-
if (responderNickname) {
|
|
665
|
-
if (this.onSituationUpdate && responderNickname.length > 0) {
|
|
666
|
-
this.onSituationUpdate(`INTRODUCE: ${responderNickname}`);
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
679
|
}
|
|
670
680
|
if (responderAgent.isControlledByHuman) {
|
|
671
681
|
logger_1.logger.log(`Waiting for human agent ${responderNickname} to respond`);
|
|
@@ -678,6 +688,11 @@ Recent Message: ${message.getContent()}
|
|
|
678
688
|
}
|
|
679
689
|
this.setCurrentSpeaker(responderNickname);
|
|
680
690
|
this.perceive(responderAgent, originalMessage, (response) => {
|
|
691
|
+
if (this.isPaused) {
|
|
692
|
+
this.processingInProgress = false;
|
|
693
|
+
this.notifyStateChange();
|
|
694
|
+
return;
|
|
695
|
+
}
|
|
681
696
|
if (response !== null) {
|
|
682
697
|
this.pendingMessages = [response, ...this.pendingMessages];
|
|
683
698
|
}
|
|
@@ -738,6 +753,11 @@ Recent Message: ${message.getContent()}
|
|
|
738
753
|
this.pendingMessages = [...moderateMessages.slice(1), ...this.pendingMessages];
|
|
739
754
|
}
|
|
740
755
|
this.moderate(moderator, originalMessage, (response) => {
|
|
756
|
+
if (this.isPaused) {
|
|
757
|
+
this.processingInProgress = false;
|
|
758
|
+
this.notifyStateChange();
|
|
759
|
+
return;
|
|
760
|
+
}
|
|
741
761
|
if (response !== null) {
|
|
742
762
|
this.handleModeratorResponse(response, originalMessage);
|
|
743
763
|
}
|