briyah 1.0.7 → 1.0.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/README.md +31 -21
- package/dist/server/src/ai/LLM/anthropic.service.js +16 -8
- package/dist/server/src/ai/LLM/base-ai.service.js +5 -4
- package/dist/server/src/ai/LLM/deepseek.service.js +8 -6
- package/dist/server/src/ai/LLM/fal.service.js +15 -14
- package/dist/server/src/ai/LLM/googleai.service.js +10 -8
- package/dist/server/src/ai/LLM/grok.service.js +9 -7
- package/dist/server/src/ai/LLM/mock.service.js +7 -6
- package/dist/server/src/ai/LLM/openai.service.js +15 -13
- package/dist/server/src/ai/LLM/together.service.js +10 -8
- package/dist/server/src/ai/LLM/vertexai.service.js +10 -9
- package/dist/server/src/ai/agent-store.service.js +12 -11
- package/dist/server/src/ai/artifact.service.js +7 -6
- package/dist/server/src/ai/attached-file.service.js +8 -7
- package/dist/server/src/ai/published-agents.service.js +5 -4
- package/dist/server/src/app/balance.service.js +7 -6
- package/dist/server/src/app/stripe.controller.js +12 -11
- package/dist/server/src/app/stripe.service.js +20 -19
- package/dist/server/src/app/transaction.service.js +6 -5
- package/dist/server/src/app/user-service-manager.js +6 -5
- package/dist/server/src/app.controller.js +95 -94
- package/dist/server/src/app.service.js +31 -30
- package/dist/server/src/auth/auth.controller.js +21 -20
- package/dist/server/src/auth/jwt-auth.guard.js +4 -3
- package/dist/server/src/auth/rate-limit.service.d.ts +0 -1
- package/dist/server/src/auth/rate-limit.service.js +6 -7
- package/dist/server/src/auth/twilio.service.js +4 -3
- package/dist/server/src/auth/users.service.js +5 -4
- package/dist/server/src/common/logger.d.ts +21 -0
- package/dist/server/src/common/logger.js +83 -0
- package/dist/server/src/room/artifact-store.service.d.ts +0 -1
- package/dist/server/src/room/artifact-store.service.js +16 -17
- package/dist/server/src/room/published-rooms.service.js +3 -2
- package/dist/server/src/room/room-store.service.js +17 -16
- package/dist/server/src/room/room.js +14 -13
- package/dist/server/src/sdk/briyah-config.d.ts +7 -0
- package/dist/server/src/sdk/briyah-config.js +1 -0
- package/dist/server/src/sdk/briyah.js +13 -4
- package/dist/server/src/sdk/index.d.ts +4 -1
- package/dist/server/src/sdk/index.js +3 -1
- package/dist/server/src/story/story-progress.service.js +2 -1
- package/dist/server/src/story/story-store.service.js +28 -27
- package/dist/server/src/story/story.service.js +114 -113
- package/dist/shared/types/app.types.d.ts +1 -2
- package/docs/.nojekyll +1 -0
- package/docs/assets/hierarchy.js +1 -0
- package/docs/assets/highlight.css +106 -0
- package/docs/assets/icons.js +18 -0
- package/docs/assets/icons.svg +1 -0
- package/docs/assets/main.js +60 -0
- package/docs/assets/navigation.js +1 -0
- package/docs/assets/search.js +1 -0
- package/docs/assets/style.css +1633 -0
- package/docs/classes/Agent.html +87 -0
- package/docs/classes/Briyah.html +64 -0
- package/docs/classes/BriyahConfigService.html +12 -0
- package/docs/classes/Room.html +119 -0
- package/docs/classes/RoomMessage.html +41 -0
- package/docs/enums/MessageAction.html +13 -0
- package/docs/hierarchy.html +1 -0
- package/docs/index.html +136 -0
- package/docs/interfaces/AgentInfo.html +17 -0
- package/docs/interfaces/AgentMessagesResponse.html +5 -0
- package/docs/interfaces/AppService.html +741 -0
- package/docs/interfaces/Artifact.html +6 -0
- package/docs/interfaces/ArtifactMetadata.html +8 -0
- package/docs/interfaces/AttachDocumentResponse.html +3 -0
- package/docs/interfaces/BriyahConfigOptions.html +16 -0
- package/docs/interfaces/ChapterInfo.html +3 -0
- package/docs/interfaces/Character.html +7 -0
- package/docs/interfaces/CreateAgentResponse.html +2 -0
- package/docs/interfaces/CreateRoomResponse.html +3 -0
- package/docs/interfaces/CreateStoryResponse.html +2 -0
- package/docs/interfaces/FileList.html +2 -0
- package/docs/interfaces/LoggingOptions.html +9 -0
- package/docs/interfaces/Message.html +6 -0
- package/docs/interfaces/ModelInfo.html +5 -0
- package/docs/interfaces/PreparedPromptResponse.html +3 -0
- package/docs/interfaces/ProcessTextResponse.html +7 -0
- package/docs/interfaces/PromptFile.html +3 -0
- package/docs/interfaces/PromptFileContent.html +3 -0
- package/docs/interfaces/PromptFilesResponse.html +2 -0
- package/docs/interfaces/PromptFolder.html +3 -0
- package/docs/interfaces/PromptFoldersResponse.html +2 -0
- package/docs/interfaces/RoomDetails.html +9 -0
- package/docs/interfaces/RoomInfo.html +5 -0
- package/docs/interfaces/RoomMessagesResponse.html +3 -0
- package/docs/interfaces/StoryIdea.html +5 -0
- package/docs/interfaces/StoryInfo.html +21 -0
- package/docs/interfaces/StoryMessageUpdate.html +6 -0
- package/docs/interfaces/StoryState.html +15 -0
- package/docs/interfaces/StorySuggestion.html +9 -0
- package/docs/modules.html +1 -0
- package/docs/types/PromptScope.html +1 -0
- package/package.json +6 -3
- package/data/common/config/story_ideas.txt +0 -6
package/README.md
CHANGED
|
@@ -34,10 +34,10 @@ const appService = briyah.getAppService('user-123');
|
|
|
34
34
|
// Call agent.save() when you want to persist it to disk.
|
|
35
35
|
const agent = appService.createAgent(
|
|
36
36
|
'Anthropic',
|
|
37
|
-
'Assistant',
|
|
38
|
-
'
|
|
37
|
+
'AI Assistant',
|
|
38
|
+
'James',
|
|
39
39
|
'A helpful AI assistant',
|
|
40
|
-
'claude-
|
|
40
|
+
'claude-haiku-4-5'
|
|
41
41
|
);
|
|
42
42
|
|
|
43
43
|
if (!agent.id) throw new Error('Agent creation failed');
|
|
@@ -84,11 +84,6 @@ interface BriyahConfigOptions {
|
|
|
84
84
|
|
|
85
85
|
### Environment Variables
|
|
86
86
|
|
|
87
|
-
Briyah requires certain environment variables to be set:
|
|
88
|
-
|
|
89
|
-
**Required:**
|
|
90
|
-
- `STARTING_BALANCE` - Starting balance for new users (e.g., "10.00")
|
|
91
|
-
|
|
92
87
|
**LLM Provider API Keys** (at least one required):
|
|
93
88
|
- `ANTHROPIC_API_KEY` - For Claude models
|
|
94
89
|
- `OPENAI_API_KEY` - For GPT models
|
|
@@ -98,9 +93,32 @@ Briyah requires certain environment variables to be set:
|
|
|
98
93
|
- `TOGETHER_API_KEY` - For Together AI models
|
|
99
94
|
|
|
100
95
|
**Optional:**
|
|
96
|
+
- `STARTING_BALANCE` - Starting balance for new users (e.g., "10.00")
|
|
101
97
|
- `SERVER_DATA_PATH` - Global default data path (overridden by constructor `dataPath`)
|
|
102
98
|
- `USER_SERVICE_CACHE_TIMEOUT_MINUTES` - Cache timeout (overridden by constructor option)
|
|
103
99
|
|
|
100
|
+
### Logging
|
|
101
|
+
|
|
102
|
+
Briyah writes logs to `{dataPath}/logs/briyah.log` by default. Configure or disable via the `logging` option:
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
const briyah = new Briyah({
|
|
106
|
+
dataPath: './my-data',
|
|
107
|
+
logging: {
|
|
108
|
+
enabled: true, // default
|
|
109
|
+
logFile: './my-data/logs/app.log', // default: {dataPath}/logs/briyah.log
|
|
110
|
+
console: false, // set true to also log to stdout/stderr
|
|
111
|
+
level: 'warn', // 'debug' | 'log' | 'warn' | 'error' — default: 'log'
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// Log to console only (no file):
|
|
116
|
+
const briyah = new Briyah({ logging: { console: true, logFile: null } });
|
|
117
|
+
|
|
118
|
+
// Disable logging entirely:
|
|
119
|
+
const briyah = new Briyah({ logging: { enabled: false } });
|
|
120
|
+
```
|
|
121
|
+
|
|
104
122
|
## API Reference
|
|
105
123
|
|
|
106
124
|
### Briyah Class
|
|
@@ -282,10 +300,10 @@ const appService = briyah.getAppService('user-123');
|
|
|
282
300
|
// Create an agent
|
|
283
301
|
const agent = appService.createAgent(
|
|
284
302
|
'Anthropic', // provider
|
|
285
|
-
'Assistant',
|
|
286
|
-
'
|
|
287
|
-
'
|
|
288
|
-
'claude-
|
|
303
|
+
'AI Assistant', // name
|
|
304
|
+
'James', // nickname
|
|
305
|
+
'A helpful AI assistant', // description
|
|
306
|
+
'claude-haiku-4-5' // model
|
|
289
307
|
);
|
|
290
308
|
|
|
291
309
|
if (!agent.id) throw new Error('Agent creation failed');
|
|
@@ -309,7 +327,7 @@ const appService = briyah.getAppService('user-123');
|
|
|
309
327
|
|
|
310
328
|
// Create agents
|
|
311
329
|
const analyst = appService.createAgent('OpenAI', 'Analyst', 'Analyst', 'Data analyst', 'gpt-4');
|
|
312
|
-
const writer = appService.createAgent('Anthropic', 'Writer', 'Writer', 'Content writer', 'claude-
|
|
330
|
+
const writer = appService.createAgent('Anthropic', 'Writer', 'Writer', 'Content writer', 'claude-haiku-4-5');
|
|
313
331
|
|
|
314
332
|
if (!analyst.id || !writer.id) throw new Error('Agent creation failed');
|
|
315
333
|
|
|
@@ -375,10 +393,6 @@ const user2Service = briyah2.getAppService('user-123');
|
|
|
375
393
|
|
|
376
394
|
**Note:** Singleton services (LLM providers, message emitters) are shared across all Briyah instances within the same process. This is safe because they are stateless or keyed by ID.
|
|
377
395
|
|
|
378
|
-
## Backward Compatibility
|
|
379
|
-
|
|
380
|
-
The Briyah SDK is fully backward compatible with the existing NestJS application. The NestJS app continues to work without any changes, while new applications can use the SDK for simplified integration.
|
|
381
|
-
|
|
382
396
|
## Troubleshooting
|
|
383
397
|
|
|
384
398
|
### "Must call init() before getAppService()"
|
|
@@ -396,7 +410,3 @@ Set the `STARTING_BALANCE` environment variable or pass `startingBalance` in the
|
|
|
396
410
|
### Cache not working as expected
|
|
397
411
|
|
|
398
412
|
Check the cache statistics with `getCacheStats()` and adjust `userServiceCacheTimeoutMinutes` in the constructor options.
|
|
399
|
-
|
|
400
|
-
## Support
|
|
401
|
-
|
|
402
|
-
For issues or questions, please refer to the main Briyah documentation or create an issue in the repository.
|
|
@@ -15,6 +15,7 @@ const sdk_1 = require("@anthropic-ai/sdk");
|
|
|
15
15
|
const base_ai_service_1 = require("./base-ai.service");
|
|
16
16
|
const model_prices_1 = require("../model_prices");
|
|
17
17
|
const errors_1 = require("../../common/errors");
|
|
18
|
+
const logger_1 = require("../../common/logger");
|
|
18
19
|
let AnthropicAiService = class AnthropicAiService extends base_ai_service_1.BaseAiService {
|
|
19
20
|
anthropic;
|
|
20
21
|
constructor() {
|
|
@@ -30,9 +31,10 @@ let AnthropicAiService = class AnthropicAiService extends base_ai_service_1.Base
|
|
|
30
31
|
timeout: 1200000,
|
|
31
32
|
maxRetries: 3,
|
|
32
33
|
});
|
|
34
|
+
logger_1.logger.debug('Anthropic service initialized successfully');
|
|
33
35
|
}
|
|
34
36
|
catch (error) {
|
|
35
|
-
|
|
37
|
+
logger_1.logger.error('Error initializing Anthropic service:', error);
|
|
36
38
|
this._isAvailable = false;
|
|
37
39
|
}
|
|
38
40
|
}
|
|
@@ -70,7 +72,7 @@ let AnthropicAiService = class AnthropicAiService extends base_ai_service_1.Base
|
|
|
70
72
|
}));
|
|
71
73
|
}
|
|
72
74
|
catch (error) {
|
|
73
|
-
|
|
75
|
+
logger_1.logger.error('Error fetching Anthropic models:', error);
|
|
74
76
|
}
|
|
75
77
|
}
|
|
76
78
|
addToConversationHistory(agent, message, fromSelf = false) {
|
|
@@ -241,8 +243,8 @@ let AnthropicAiService = class AnthropicAiService extends base_ai_service_1.Base
|
|
|
241
243
|
}
|
|
242
244
|
catch (parseError) {
|
|
243
245
|
lastError = parseError;
|
|
244
|
-
|
|
245
|
-
|
|
246
|
+
logger_1.logger.warn(`JSON parse attempt ${attempt}/${maxRetries} failed:`, parseError);
|
|
247
|
+
logger_1.logger.warn('Raw response:', responseText);
|
|
246
248
|
if (attempt < maxRetries) {
|
|
247
249
|
const retryMessage = `Your previous response was not valid JSON. Please respond with ONLY valid JSON that can be parsed. No explanatory text, no markdown, no formatting - just pure JSON that conforms to the schema. Here was the parsing error: ${parseError.message}`;
|
|
248
250
|
messages.push({
|
|
@@ -279,7 +281,13 @@ let AnthropicAiService = class AnthropicAiService extends base_ai_service_1.Base
|
|
|
279
281
|
}
|
|
280
282
|
catch (apiError) {
|
|
281
283
|
lastError = apiError;
|
|
282
|
-
|
|
284
|
+
if (apiError.status === 404) {
|
|
285
|
+
const innerError = apiError.error?.error;
|
|
286
|
+
const errorType = innerError?.type ?? 'not_found_error';
|
|
287
|
+
const errorMessage = innerError?.message ?? apiError.message;
|
|
288
|
+
throw new Error(`${errorType}: ${errorMessage}`);
|
|
289
|
+
}
|
|
290
|
+
logger_1.logger.error(`API call attempt ${attempt}/${maxRetries} failed:`, apiError);
|
|
283
291
|
if (attempt < maxRetries) {
|
|
284
292
|
await new Promise((resolve) => setTimeout(resolve, 1000 * attempt));
|
|
285
293
|
}
|
|
@@ -290,7 +298,7 @@ let AnthropicAiService = class AnthropicAiService extends base_ai_service_1.Base
|
|
|
290
298
|
computeMessageCost(agent, usage) {
|
|
291
299
|
const modelInfo = (0, model_prices_1.getModelPrices)()[agent.modelName];
|
|
292
300
|
if (!modelInfo) {
|
|
293
|
-
|
|
301
|
+
logger_1.logger.error(`No price info found for model ${agent.modelName}`);
|
|
294
302
|
return 0;
|
|
295
303
|
}
|
|
296
304
|
const cacheCreationTokens = usage.cache_creation_input_tokens || 0;
|
|
@@ -309,12 +317,12 @@ let AnthropicAiService = class AnthropicAiService extends base_ai_service_1.Base
|
|
|
309
317
|
agent.totalOutputTokens += outputTokens;
|
|
310
318
|
agent.totalCost += cost;
|
|
311
319
|
agent.totalMarkup += markup;
|
|
312
|
-
|
|
320
|
+
logger_1.logger.log(`Cost for ${agent.agentName} message: ${cost.toFixed(4)}, markup: ${markup.toFixed(4)}`);
|
|
313
321
|
if (agent.balanceService && cost > 0) {
|
|
314
322
|
agent.balanceService.decrementBalance(cost, markup);
|
|
315
323
|
}
|
|
316
324
|
if (cacheCreationTokens > 0 || cacheReadTokens > 0) {
|
|
317
|
-
|
|
325
|
+
logger_1.logger.log(`Cache metrics for ${agent.agentName}: creation=${cacheCreationTokens}, read=${cacheReadTokens}, standard=${standardInputTokens}`);
|
|
318
326
|
}
|
|
319
327
|
}
|
|
320
328
|
};
|
|
@@ -50,6 +50,7 @@ const fs_1 = require("fs");
|
|
|
50
50
|
const fs = __importStar(require("fs"));
|
|
51
51
|
const handlebars_1 = require("handlebars");
|
|
52
52
|
const errors_1 = require("../../common/errors");
|
|
53
|
+
const logger_1 = require("../../common/logger");
|
|
53
54
|
let BaseAiService = class BaseAiService {
|
|
54
55
|
modelsCache = null;
|
|
55
56
|
_isAvailable = true;
|
|
@@ -112,7 +113,7 @@ let BaseAiService = class BaseAiService {
|
|
|
112
113
|
return JSON.parse(jsonSchemaString);
|
|
113
114
|
}
|
|
114
115
|
catch (error) {
|
|
115
|
-
|
|
116
|
+
logger_1.logger.error(`Error parsing JSON schema from ${jsonSchemaFile}:`, error);
|
|
116
117
|
return null;
|
|
117
118
|
}
|
|
118
119
|
}
|
|
@@ -129,7 +130,7 @@ let BaseAiService = class BaseAiService {
|
|
|
129
130
|
return models;
|
|
130
131
|
}
|
|
131
132
|
catch (error) {
|
|
132
|
-
|
|
133
|
+
logger_1.logger.error(`Error fetching models for ${this.getServiceName()}:`, error);
|
|
133
134
|
throw error;
|
|
134
135
|
}
|
|
135
136
|
}
|
|
@@ -154,7 +155,7 @@ let BaseAiService = class BaseAiService {
|
|
|
154
155
|
systemInstructionPrompt = (0, fs_1.readFileSync)(systemInstructionFile).toString('utf8');
|
|
155
156
|
}
|
|
156
157
|
catch (error) {
|
|
157
|
-
|
|
158
|
+
logger_1.logger.error(`Error reading system instruction from ${systemInstructionFile}:`, error);
|
|
158
159
|
systemInstructionPrompt = null;
|
|
159
160
|
}
|
|
160
161
|
}
|
|
@@ -261,7 +262,7 @@ let BaseAiService = class BaseAiService {
|
|
|
261
262
|
return `Document attached: ${fileName}`;
|
|
262
263
|
}
|
|
263
264
|
catch (error) {
|
|
264
|
-
|
|
265
|
+
logger_1.logger.error(`Error attaching document in ${this.getServiceName()} service:`, error);
|
|
265
266
|
throw new Error(`Error attaching document: ${error.message}`);
|
|
266
267
|
}
|
|
267
268
|
}
|
|
@@ -17,6 +17,7 @@ const base_ai_service_1 = require("./base-ai.service");
|
|
|
17
17
|
const zod_1 = require("zod");
|
|
18
18
|
const model_prices_1 = require("../model_prices");
|
|
19
19
|
const errors_1 = require("../../common/errors");
|
|
20
|
+
const logger_1 = require("../../common/logger");
|
|
20
21
|
let DeepSeekAiService = class DeepSeekAiService extends base_ai_service_1.BaseAiService {
|
|
21
22
|
deepseekClient;
|
|
22
23
|
constructor() {
|
|
@@ -30,9 +31,10 @@ let DeepSeekAiService = class DeepSeekAiService extends base_ai_service_1.BaseAi
|
|
|
30
31
|
this.deepseekClient = (0, deepseek_1.createDeepSeek)({
|
|
31
32
|
apiKey: apiKey,
|
|
32
33
|
});
|
|
34
|
+
logger_1.logger.debug('DeepSeek service initialized successfully');
|
|
33
35
|
}
|
|
34
36
|
catch (error) {
|
|
35
|
-
|
|
37
|
+
logger_1.logger.error('Error initializing DeepSeek service:', error);
|
|
36
38
|
this._isAvailable = false;
|
|
37
39
|
}
|
|
38
40
|
}
|
|
@@ -66,7 +68,7 @@ let DeepSeekAiService = class DeepSeekAiService extends base_ai_service_1.BaseAi
|
|
|
66
68
|
});
|
|
67
69
|
}
|
|
68
70
|
catch (error) {
|
|
69
|
-
|
|
71
|
+
logger_1.logger.error('Error fetching DeepSeek models from API:', error);
|
|
70
72
|
throw error;
|
|
71
73
|
}
|
|
72
74
|
}
|
|
@@ -226,7 +228,7 @@ let DeepSeekAiService = class DeepSeekAiService extends base_ai_service_1.BaseAi
|
|
|
226
228
|
}
|
|
227
229
|
}
|
|
228
230
|
catch (error) {
|
|
229
|
-
|
|
231
|
+
logger_1.logger.error('Error generating response from DeepSeek:', error);
|
|
230
232
|
throw error;
|
|
231
233
|
}
|
|
232
234
|
}
|
|
@@ -246,7 +248,7 @@ let DeepSeekAiService = class DeepSeekAiService extends base_ai_service_1.BaseAi
|
|
|
246
248
|
modelInfo = (0, model_prices_1.getModelPrices)()[`deepseek/${agent.modelName}`];
|
|
247
249
|
}
|
|
248
250
|
if (!modelInfo) {
|
|
249
|
-
|
|
251
|
+
logger_1.logger.error(`No price info found for model ${agent.modelName} or deepseek/${agent.modelName}`);
|
|
250
252
|
return;
|
|
251
253
|
}
|
|
252
254
|
const uncachedCost = uncachedInputTokens * modelInfo.input_cost_per_token;
|
|
@@ -259,9 +261,9 @@ let DeepSeekAiService = class DeepSeekAiService extends base_ai_service_1.BaseAi
|
|
|
259
261
|
agent.totalOutputTokens += outputTokens;
|
|
260
262
|
agent.totalCost += cost;
|
|
261
263
|
agent.totalMarkup += markup;
|
|
262
|
-
|
|
264
|
+
logger_1.logger.log(`Cost for ${agent.agentName} message: ${cost} (markup: ${markup.toFixed(4)})`);
|
|
263
265
|
if (cachedTokens > 0) {
|
|
264
|
-
|
|
266
|
+
logger_1.logger.log(`Cache metrics for ${agent.agentName}: cached=${cachedTokens}, uncached=${uncachedInputTokens}`);
|
|
265
267
|
}
|
|
266
268
|
if (agent.balanceService && cost > 0) {
|
|
267
269
|
agent.balanceService.decrementBalance(cost, markup);
|
|
@@ -15,6 +15,7 @@ const client_1 = require("@fal-ai/client");
|
|
|
15
15
|
const base_ai_service_1 = require("./base-ai.service");
|
|
16
16
|
const model_prices_1 = require("../model_prices");
|
|
17
17
|
const errors_1 = require("../../common/errors");
|
|
18
|
+
const logger_1 = require("../../common/logger");
|
|
18
19
|
let FalAiService = class FalAiService extends base_ai_service_1.BaseAiService {
|
|
19
20
|
constructor() {
|
|
20
21
|
super();
|
|
@@ -25,10 +26,10 @@ let FalAiService = class FalAiService extends base_ai_service_1.BaseAiService {
|
|
|
25
26
|
return;
|
|
26
27
|
}
|
|
27
28
|
client_1.fal.config({ credentials: apiKey });
|
|
28
|
-
|
|
29
|
+
logger_1.logger.debug('FalAI service initialized successfully');
|
|
29
30
|
}
|
|
30
31
|
catch (error) {
|
|
31
|
-
|
|
32
|
+
logger_1.logger.error('Error initializing Fal AI service:', error);
|
|
32
33
|
this._isAvailable = false;
|
|
33
34
|
}
|
|
34
35
|
}
|
|
@@ -50,7 +51,7 @@ let FalAiService = class FalAiService extends base_ai_service_1.BaseAiService {
|
|
|
50
51
|
},
|
|
51
52
|
});
|
|
52
53
|
if (!response.ok) {
|
|
53
|
-
|
|
54
|
+
logger_1.logger.error(`Fal API error: ${response.status} ${response.statusText}`);
|
|
54
55
|
return [];
|
|
55
56
|
}
|
|
56
57
|
const data = await response.json();
|
|
@@ -65,11 +66,11 @@ let FalAiService = class FalAiService extends base_ai_service_1.BaseAiService {
|
|
|
65
66
|
});
|
|
66
67
|
}
|
|
67
68
|
}
|
|
68
|
-
|
|
69
|
+
logger_1.logger.log(`Fetched ${models.length} active models from Fal AI`);
|
|
69
70
|
return models;
|
|
70
71
|
}
|
|
71
72
|
catch (error) {
|
|
72
|
-
|
|
73
|
+
logger_1.logger.error('Error fetching Fal AI models:', error);
|
|
73
74
|
return [];
|
|
74
75
|
}
|
|
75
76
|
}
|
|
@@ -159,7 +160,7 @@ let FalAiService = class FalAiService extends base_ai_service_1.BaseAiService {
|
|
|
159
160
|
this.computeMessageCost(agent, usage, estimatedInputTokens, estimatedOutputTokens);
|
|
160
161
|
}
|
|
161
162
|
catch (error) {
|
|
162
|
-
|
|
163
|
+
logger_1.logger.error('Error calling Fal AI:', error);
|
|
163
164
|
if (error.message?.includes('authentication') ||
|
|
164
165
|
error.message?.includes('unauthorized')) {
|
|
165
166
|
throw new Error('Fal AI authentication failed. Check FAL_API_KEY.');
|
|
@@ -178,8 +179,8 @@ let FalAiService = class FalAiService extends base_ai_service_1.BaseAiService {
|
|
|
178
179
|
return JSON.parse(responseText);
|
|
179
180
|
}
|
|
180
181
|
catch (parseError) {
|
|
181
|
-
|
|
182
|
-
|
|
182
|
+
logger_1.logger.error('Failed to parse JSON response:', parseError);
|
|
183
|
+
logger_1.logger.error('Response text:', responseText);
|
|
183
184
|
throw new Error('Failed to parse JSON response from Fal AI');
|
|
184
185
|
}
|
|
185
186
|
}
|
|
@@ -193,7 +194,7 @@ let FalAiService = class FalAiService extends base_ai_service_1.BaseAiService {
|
|
|
193
194
|
modelInfo = (0, model_prices_1.getModelPrices)()[`fal_ai/${agent.modelName}`];
|
|
194
195
|
}
|
|
195
196
|
if (!modelInfo) {
|
|
196
|
-
|
|
197
|
+
logger_1.logger.warn(`No price info found for model ${agent.modelName}. Skipping cost tracking.`);
|
|
197
198
|
return;
|
|
198
199
|
}
|
|
199
200
|
const inputCost = inputTokens * (modelInfo.input_cost_per_token || 0);
|
|
@@ -205,10 +206,10 @@ let FalAiService = class FalAiService extends base_ai_service_1.BaseAiService {
|
|
|
205
206
|
agent.totalCost += cost;
|
|
206
207
|
agent.totalMarkup += markup;
|
|
207
208
|
if (!usage?.prompt_tokens) {
|
|
208
|
-
|
|
209
|
+
logger_1.logger.log(`Cost for ${agent.agentName} message (estimated): ${cost.toFixed(4)} (markup: ${markup.toFixed(4)})`);
|
|
209
210
|
}
|
|
210
211
|
else {
|
|
211
|
-
|
|
212
|
+
logger_1.logger.log(`Cost for ${agent.agentName} message: ${cost.toFixed(4)} (markup: ${markup.toFixed(4)})`);
|
|
212
213
|
}
|
|
213
214
|
if (agent.balanceService && cost > 0) {
|
|
214
215
|
agent.balanceService.decrementBalance(cost, markup);
|
|
@@ -220,14 +221,14 @@ let FalAiService = class FalAiService extends base_ai_service_1.BaseAiService {
|
|
|
220
221
|
modelInfo = (0, model_prices_1.getModelPrices)()[`fal_ai/${agent.modelName}`];
|
|
221
222
|
}
|
|
222
223
|
if (!modelInfo || !modelInfo.output_cost_per_image) {
|
|
223
|
-
|
|
224
|
+
logger_1.logger.warn(`No image price info found for ${agent.modelName}. Skipping cost tracking.`);
|
|
224
225
|
return;
|
|
225
226
|
}
|
|
226
227
|
const cost = modelInfo.output_cost_per_image;
|
|
227
228
|
const markup = 0;
|
|
228
229
|
agent.totalCost += cost;
|
|
229
230
|
agent.totalMarkup += markup;
|
|
230
|
-
|
|
231
|
+
logger_1.logger.log(`Cost for image generation: ${cost.toFixed(4)} (markup: ${markup.toFixed(4)})`);
|
|
231
232
|
if (agent.balanceService && cost > 0) {
|
|
232
233
|
agent.balanceService.decrementBalance(cost, markup);
|
|
233
234
|
}
|
|
@@ -297,7 +298,7 @@ let FalAiService = class FalAiService extends base_ai_service_1.BaseAiService {
|
|
|
297
298
|
return { artifactId };
|
|
298
299
|
}
|
|
299
300
|
catch (error) {
|
|
300
|
-
|
|
301
|
+
logger_1.logger.error('Error generating image with Fal AI:', error.message || error);
|
|
301
302
|
return { error };
|
|
302
303
|
}
|
|
303
304
|
}
|
|
@@ -15,6 +15,7 @@ const genai_1 = require("@google/genai");
|
|
|
15
15
|
const base_ai_service_1 = require("./base-ai.service");
|
|
16
16
|
const model_prices_1 = require("../model_prices");
|
|
17
17
|
const errors_1 = require("../../common/errors");
|
|
18
|
+
const logger_1 = require("../../common/logger");
|
|
18
19
|
let GoogleAiService = class GoogleAiService extends base_ai_service_1.BaseAiService {
|
|
19
20
|
googleAI = null;
|
|
20
21
|
constructor() {
|
|
@@ -26,9 +27,10 @@ let GoogleAiService = class GoogleAiService extends base_ai_service_1.BaseAiServ
|
|
|
26
27
|
return;
|
|
27
28
|
}
|
|
28
29
|
this.googleAI = new genai_1.GoogleGenAI({ apiKey });
|
|
30
|
+
logger_1.logger.debug('Google AI service initialized successfully');
|
|
29
31
|
}
|
|
30
32
|
catch (error) {
|
|
31
|
-
|
|
33
|
+
logger_1.logger.error('Error initializing Google AI service:', error);
|
|
32
34
|
this._isAvailable = false;
|
|
33
35
|
}
|
|
34
36
|
}
|
|
@@ -55,7 +57,7 @@ let GoogleAiService = class GoogleAiService extends base_ai_service_1.BaseAiServ
|
|
|
55
57
|
});
|
|
56
58
|
}
|
|
57
59
|
catch (error) {
|
|
58
|
-
|
|
60
|
+
logger_1.logger.warn('Could not fetch models from Google AI API, using fallback list:', error.message);
|
|
59
61
|
}
|
|
60
62
|
}
|
|
61
63
|
addToConversationHistory(agent, message, fromSelf = false) {
|
|
@@ -139,7 +141,7 @@ let GoogleAiService = class GoogleAiService extends base_ai_service_1.BaseAiServ
|
|
|
139
141
|
}
|
|
140
142
|
}
|
|
141
143
|
catch (error) {
|
|
142
|
-
|
|
144
|
+
logger_1.logger.error('Error calling Google AI:', error);
|
|
143
145
|
throw error;
|
|
144
146
|
}
|
|
145
147
|
if (saveResponse) {
|
|
@@ -201,7 +203,7 @@ let GoogleAiService = class GoogleAiService extends base_ai_service_1.BaseAiServ
|
|
|
201
203
|
return { artifactId };
|
|
202
204
|
}
|
|
203
205
|
catch (error) {
|
|
204
|
-
|
|
206
|
+
logger_1.logger.error('Error generating image with Google AI:', error);
|
|
205
207
|
return { error };
|
|
206
208
|
}
|
|
207
209
|
}
|
|
@@ -210,7 +212,7 @@ let GoogleAiService = class GoogleAiService extends base_ai_service_1.BaseAiServ
|
|
|
210
212
|
const outputTokens = usage.candidatesTokenCount || 0;
|
|
211
213
|
const modelInfo = (0, model_prices_1.getModelPrices)()[agent.modelName];
|
|
212
214
|
if (!modelInfo) {
|
|
213
|
-
|
|
215
|
+
logger_1.logger.error(`No price info found for model ${agent.modelName}`);
|
|
214
216
|
return;
|
|
215
217
|
}
|
|
216
218
|
const inputCost = inputTokens * modelInfo.input_cost_per_token;
|
|
@@ -221,7 +223,7 @@ let GoogleAiService = class GoogleAiService extends base_ai_service_1.BaseAiServ
|
|
|
221
223
|
agent.totalOutputTokens += outputTokens;
|
|
222
224
|
agent.totalCost += cost;
|
|
223
225
|
agent.totalMarkup += markup;
|
|
224
|
-
|
|
226
|
+
logger_1.logger.log(`Cost for ${agent.agentName} message: ${cost} (markup: ${markup.toFixed(4)})`);
|
|
225
227
|
if (agent.balanceService && cost > 0) {
|
|
226
228
|
agent.balanceService.decrementBalance(cost, markup);
|
|
227
229
|
}
|
|
@@ -229,7 +231,7 @@ let GoogleAiService = class GoogleAiService extends base_ai_service_1.BaseAiServ
|
|
|
229
231
|
computeImageCost(agent, modelName) {
|
|
230
232
|
const modelInfo = (0, model_prices_1.getModelPrices)()[modelName];
|
|
231
233
|
if (!modelInfo || !modelInfo.output_cost_per_image) {
|
|
232
|
-
|
|
234
|
+
logger_1.logger.error(`No image price info found for model ${modelName}`);
|
|
233
235
|
return;
|
|
234
236
|
}
|
|
235
237
|
const outputCost = modelInfo.output_cost_per_image;
|
|
@@ -237,7 +239,7 @@ let GoogleAiService = class GoogleAiService extends base_ai_service_1.BaseAiServ
|
|
|
237
239
|
const cost = outputCost + markup;
|
|
238
240
|
agent.totalCost += cost;
|
|
239
241
|
agent.totalMarkup += markup;
|
|
240
|
-
|
|
242
|
+
logger_1.logger.log(`Cost for image generation: ${cost} (markup: ${markup.toFixed(4)})`);
|
|
241
243
|
if (agent.balanceService && cost > 0) {
|
|
242
244
|
agent.balanceService.decrementBalance(cost, markup);
|
|
243
245
|
}
|
|
@@ -16,6 +16,7 @@ const openai_2 = require("openai");
|
|
|
16
16
|
const base_ai_service_1 = require("./base-ai.service");
|
|
17
17
|
const model_prices_1 = require("../model_prices");
|
|
18
18
|
const errors_1 = require("../../common/errors");
|
|
19
|
+
const logger_1 = require("../../common/logger");
|
|
19
20
|
let GrokAiService = class GrokAiService extends base_ai_service_1.BaseAiService {
|
|
20
21
|
openai;
|
|
21
22
|
constructor() {
|
|
@@ -33,9 +34,10 @@ let GrokAiService = class GrokAiService extends base_ai_service_1.BaseAiService
|
|
|
33
34
|
maxRetries: 3,
|
|
34
35
|
};
|
|
35
36
|
this.openai = new openai_1.OpenAI(options);
|
|
37
|
+
logger_1.logger.debug('Grok service initialized successfully');
|
|
36
38
|
}
|
|
37
39
|
catch (error) {
|
|
38
|
-
|
|
40
|
+
logger_1.logger.error('Error initializing Grok service:', error);
|
|
39
41
|
this._isAvailable = false;
|
|
40
42
|
}
|
|
41
43
|
}
|
|
@@ -92,10 +94,10 @@ let GrokAiService = class GrokAiService extends base_ai_service_1.BaseAiService
|
|
|
92
94
|
metadata.serviceMetadata?.resourceId) {
|
|
93
95
|
try {
|
|
94
96
|
await this.openai.files.delete(metadata.serviceMetadata.resourceId);
|
|
95
|
-
|
|
97
|
+
logger_1.logger.log(`Deleted Grok file ${metadata.serviceMetadata.resourceId} for agent ${agent.id}`);
|
|
96
98
|
}
|
|
97
99
|
catch (error) {
|
|
98
|
-
|
|
100
|
+
logger_1.logger.error(`Error deleting Grok file ${metadata.serviceMetadata.resourceId}:`, error);
|
|
99
101
|
}
|
|
100
102
|
}
|
|
101
103
|
}
|
|
@@ -194,7 +196,7 @@ let GrokAiService = class GrokAiService extends base_ai_service_1.BaseAiService
|
|
|
194
196
|
}
|
|
195
197
|
}
|
|
196
198
|
catch (error) {
|
|
197
|
-
|
|
199
|
+
logger_1.logger.error(error);
|
|
198
200
|
throw error;
|
|
199
201
|
}
|
|
200
202
|
if (saveResponse) {
|
|
@@ -230,7 +232,7 @@ let GrokAiService = class GrokAiService extends base_ai_service_1.BaseAiService
|
|
|
230
232
|
modelInfo = (0, model_prices_1.getModelPrices)()[`xai/${agent.modelName}`];
|
|
231
233
|
}
|
|
232
234
|
if (!modelInfo) {
|
|
233
|
-
|
|
235
|
+
logger_1.logger.error(`No price info found for model ${agent.modelName} or xai/${agent.modelName}`);
|
|
234
236
|
return;
|
|
235
237
|
}
|
|
236
238
|
const uncachedCost = uncachedPromptTokens * modelInfo.input_cost_per_token;
|
|
@@ -243,9 +245,9 @@ let GrokAiService = class GrokAiService extends base_ai_service_1.BaseAiService
|
|
|
243
245
|
agent.totalOutputTokens += completionTokens;
|
|
244
246
|
agent.totalCost += cost;
|
|
245
247
|
agent.totalMarkup += markup;
|
|
246
|
-
|
|
248
|
+
logger_1.logger.log(`Cost for ${agent.agentName} message: ${cost} (markup: ${markup.toFixed(4)})`);
|
|
247
249
|
if (cachedTokens > 0) {
|
|
248
|
-
|
|
250
|
+
logger_1.logger.log(`Cache metrics for ${agent.agentName}: cached=${cachedTokens}, uncached=${uncachedPromptTokens}`);
|
|
249
251
|
}
|
|
250
252
|
if (agent.balanceService && cost > 0) {
|
|
251
253
|
agent.balanceService.decrementBalance(cost, markup);
|
|
@@ -47,6 +47,7 @@ const common_1 = require("@nestjs/common");
|
|
|
47
47
|
const base_ai_service_1 = require("./base-ai.service");
|
|
48
48
|
const fs = __importStar(require("fs"));
|
|
49
49
|
const model_prices_1 = require("../model_prices");
|
|
50
|
+
const logger_1 = require("../../common/logger");
|
|
50
51
|
let MockAiService = class MockAiService extends base_ai_service_1.BaseAiService {
|
|
51
52
|
constructor() {
|
|
52
53
|
super();
|
|
@@ -69,7 +70,7 @@ let MockAiService = class MockAiService extends base_ai_service_1.BaseAiService
|
|
|
69
70
|
async preparedPrompt(agent, promptFileName, variables, saveResponse = true, _cacheConfig = null) {
|
|
70
71
|
const mockFile = this.findPromptFile(agent, promptFileName, '.mock');
|
|
71
72
|
if (!mockFile) {
|
|
72
|
-
|
|
73
|
+
logger_1.logger.warn(`Mock file '${promptFileName}.mock' not found for agent '${agent.agentName}'. Using generic response.`);
|
|
73
74
|
const preparedPrompt = this.getPreparedPrompt(agent, promptFileName, variables);
|
|
74
75
|
const jsonSchema = this.getPreparedSchema(agent, promptFileName);
|
|
75
76
|
return this.textPrompt(agent, preparedPrompt, jsonSchema, saveResponse);
|
|
@@ -88,7 +89,7 @@ let MockAiService = class MockAiService extends base_ai_service_1.BaseAiService
|
|
|
88
89
|
return parsedResponse;
|
|
89
90
|
}
|
|
90
91
|
catch (error) {
|
|
91
|
-
|
|
92
|
+
logger_1.logger.error(`Error parsing mock JSON response from ${mockFile}:`, error);
|
|
92
93
|
throw new Error(`Invalid JSON in mock file: ${mockFile}`);
|
|
93
94
|
}
|
|
94
95
|
}
|
|
@@ -122,7 +123,7 @@ let MockAiService = class MockAiService extends base_ai_service_1.BaseAiService
|
|
|
122
123
|
const mockFileBaseName = this.getMockFile(promptFileName, prompt, variables);
|
|
123
124
|
const mockFile = this.findPromptFile(agent, mockFileBaseName, '.mock');
|
|
124
125
|
if (!mockFile) {
|
|
125
|
-
|
|
126
|
+
logger_1.logger.warn(`Mock file '${mockFile}' not found for agent '${agent.agentName}'. Using generic response.`);
|
|
126
127
|
return this.textPrompt(agent, prompt || 'Mock prompt', null, saveResponse, cacheConfig);
|
|
127
128
|
}
|
|
128
129
|
const mockResponse = fs.readFileSync(mockFile).toString('utf8');
|
|
@@ -138,7 +139,7 @@ let MockAiService = class MockAiService extends base_ai_service_1.BaseAiService
|
|
|
138
139
|
return parsedResponse;
|
|
139
140
|
}
|
|
140
141
|
catch (error) {
|
|
141
|
-
|
|
142
|
+
logger_1.logger.error(`Error parsing mock JSON response from ${mockFile}:`, error);
|
|
142
143
|
throw new Error(`Invalid JSON in mock file: ${mockFile}`);
|
|
143
144
|
}
|
|
144
145
|
}
|
|
@@ -167,7 +168,7 @@ let MockAiService = class MockAiService extends base_ai_service_1.BaseAiService
|
|
|
167
168
|
const outputTokens = Math.max(50, Math.floor(response.length / 4));
|
|
168
169
|
const modelInfo = (0, model_prices_1.getModelPrices)()['mock-fast-v1'];
|
|
169
170
|
if (!modelInfo) {
|
|
170
|
-
|
|
171
|
+
logger_1.logger.warn('Mock model pricing not found in model_prices.ts');
|
|
171
172
|
return;
|
|
172
173
|
}
|
|
173
174
|
const inputCost = inputTokens * modelInfo.input_cost_per_token;
|
|
@@ -178,7 +179,7 @@ let MockAiService = class MockAiService extends base_ai_service_1.BaseAiService
|
|
|
178
179
|
agent.totalInputTokens += inputTokens;
|
|
179
180
|
agent.totalOutputTokens += outputTokens;
|
|
180
181
|
agent.totalMarkup += markup;
|
|
181
|
-
|
|
182
|
+
logger_1.logger.log(`Cost for ${agent.agentName} message: ${totalCost} (markup: ${markup.toFixed(4)})`);
|
|
182
183
|
if (agent.balanceService) {
|
|
183
184
|
await agent.balanceService.decrementBalance(totalCost, markup);
|
|
184
185
|
}
|