@multiplayer-app/ai-agent-node 0.1.0-beta.4 → 0.1.0-beta.41
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/cjs/config.cjs +88 -38
- package/dist/cjs/config.cjs.map +1 -1
- package/dist/cjs/config.d.ts +57 -23
- package/dist/cjs/config.d.ts.map +1 -1
- package/dist/cjs/helpers/AIHelper.cjs +160 -101
- package/dist/cjs/helpers/AIHelper.cjs.map +1 -1
- package/dist/cjs/helpers/AIHelper.d.ts +21 -13
- package/dist/cjs/helpers/AIHelper.d.ts.map +1 -1
- package/dist/cjs/helpers/AIHelper.test.cjs +22 -15
- package/dist/cjs/helpers/AIHelper.test.cjs.map +1 -1
- package/dist/cjs/helpers/ConfigHelper.cjs +19 -11
- package/dist/cjs/helpers/ConfigHelper.cjs.map +1 -1
- package/dist/cjs/helpers/ConfigHelper.d.ts.map +1 -1
- package/dist/cjs/helpers/ContextLimiter.cjs +2 -3
- package/dist/cjs/helpers/ContextLimiter.cjs.map +1 -1
- package/dist/cjs/helpers/FileHelper.cjs +132 -154
- package/dist/cjs/helpers/FileHelper.cjs.map +1 -1
- package/dist/cjs/helpers/FileHelper.d.ts +19 -25
- package/dist/cjs/helpers/FileHelper.d.ts.map +1 -1
- package/dist/cjs/helpers/index.cjs +4 -5
- package/dist/cjs/helpers/index.cjs.map +1 -1
- package/dist/cjs/helpers/index.d.ts +4 -5
- package/dist/cjs/helpers/index.d.ts.map +1 -1
- package/dist/cjs/index.cjs +118 -31
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.ts +42 -13
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/libs/index.cjs +2 -3
- package/dist/cjs/libs/index.cjs.map +1 -1
- package/dist/cjs/libs/index.d.ts +2 -3
- package/dist/cjs/libs/index.d.ts.map +1 -1
- package/dist/cjs/libs/logger/index.cjs +5 -5
- package/dist/cjs/libs/logger/index.cjs.map +1 -1
- package/dist/cjs/libs/logger/index.d.ts +2 -2
- package/dist/cjs/libs/logger/index.d.ts.map +1 -1
- package/dist/cjs/libs/logger/kafkajs-logger-creator.cjs +2 -2
- package/dist/cjs/libs/logger/kafkajs-logger-creator.cjs.map +1 -1
- package/dist/cjs/libs/s3/index.cjs +3 -39
- package/dist/cjs/libs/s3/index.cjs.map +1 -1
- package/dist/cjs/libs/s3/index.d.ts +1 -2
- package/dist/cjs/libs/s3/index.d.ts.map +1 -1
- package/dist/cjs/libs/s3/s3.lib.cjs +174 -191
- package/dist/cjs/libs/s3/s3.lib.cjs.map +1 -1
- package/dist/cjs/libs/s3/s3.lib.d.ts +29 -22
- package/dist/cjs/libs/s3/s3.lib.d.ts.map +1 -1
- package/dist/cjs/processors/ActivityProcessor.cjs +36 -0
- package/dist/cjs/processors/ActivityProcessor.cjs.map +1 -0
- package/dist/cjs/processors/ActivityProcessor.d.ts +27 -0
- package/dist/cjs/processors/ActivityProcessor.d.ts.map +1 -0
- package/dist/cjs/processors/ActivityProcessor.test.cjs +84 -0
- package/dist/cjs/processors/ActivityProcessor.test.cjs.map +1 -0
- package/dist/cjs/processors/ActivityProcessor.test.d.ts +2 -0
- package/dist/cjs/processors/ActivityProcessor.test.d.ts.map +1 -0
- package/dist/cjs/processors/ChatProcessor.cjs +335 -163
- package/dist/cjs/processors/ChatProcessor.cjs.map +1 -1
- package/dist/cjs/processors/ChatProcessor.d.ts +56 -9
- package/dist/cjs/processors/ChatProcessor.d.ts.map +1 -1
- package/dist/cjs/processors/ChatProcessor.test.cjs +450 -0
- package/dist/cjs/processors/ChatProcessor.test.cjs.map +1 -0
- package/dist/cjs/processors/ChatProcessor.test.d.ts +2 -0
- package/dist/cjs/processors/ChatProcessor.test.d.ts.map +1 -0
- package/dist/cjs/processors/ModelsProcessor.cjs +2 -2
- package/dist/cjs/processors/ModelsProcessor.cjs.map +1 -1
- package/dist/cjs/processors/index.cjs +3 -2
- package/dist/cjs/processors/index.cjs.map +1 -1
- package/dist/cjs/processors/index.d.ts +3 -2
- package/dist/cjs/processors/index.d.ts.map +1 -1
- package/dist/cjs/services/AIService.cjs +50 -31
- package/dist/cjs/services/AIService.cjs.map +1 -1
- package/dist/cjs/services/AIService.d.ts +16 -5
- package/dist/cjs/services/AIService.d.ts.map +1 -1
- package/dist/cjs/services/InternalEventsHandler.cjs +5 -5
- package/dist/cjs/services/InternalEventsHandler.cjs.map +1 -1
- package/dist/cjs/services/InternalEventsHandler.d.ts +3 -1
- package/dist/cjs/services/InternalEventsHandler.d.ts.map +1 -1
- package/dist/cjs/services/ModelFetcher.cjs +9 -15
- package/dist/cjs/services/ModelFetcher.cjs.map +1 -1
- package/dist/cjs/services/ModelFetcher.d.ts +2 -7
- package/dist/cjs/services/ModelFetcher.d.ts.map +1 -1
- package/dist/cjs/services/RedisService.cjs +35 -32
- package/dist/cjs/services/RedisService.cjs.map +1 -1
- package/dist/cjs/services/RedisService.d.ts +5 -2
- package/dist/cjs/services/RedisService.d.ts.map +1 -1
- package/dist/cjs/services/SocketService.cjs +19 -20
- package/dist/cjs/services/SocketService.cjs.map +1 -1
- package/dist/cjs/services/SocketService.d.ts +9 -6
- package/dist/cjs/services/SocketService.d.ts.map +1 -1
- package/dist/cjs/services/index.cjs +5 -6
- package/dist/cjs/services/index.cjs.map +1 -1
- package/dist/cjs/services/index.d.ts +5 -6
- package/dist/cjs/services/index.d.ts.map +1 -1
- package/dist/cjs/store/AgentStore.cjs +4 -5
- package/dist/cjs/store/AgentStore.cjs.map +1 -1
- package/dist/cjs/store/AgentStore.d.ts +2 -1
- package/dist/cjs/store/AgentStore.d.ts.map +1 -1
- package/dist/cjs/store/ArtifactStore.cjs +2 -4
- package/dist/cjs/store/ArtifactStore.cjs.map +1 -1
- package/dist/cjs/store/ConfigStore.cjs +8 -11
- package/dist/cjs/store/ConfigStore.cjs.map +1 -1
- package/dist/cjs/store/ConfigStore.d.ts.map +1 -1
- package/dist/cjs/store/ConfigStore.test.cjs +2 -2
- package/dist/cjs/store/ConfigStore.test.cjs.map +1 -1
- package/dist/cjs/store/ModelStore.cjs +4 -4
- package/dist/cjs/store/ModelStore.cjs.map +1 -1
- package/dist/cjs/store/ModelStore.test.cjs +17 -17
- package/dist/cjs/store/ModelStore.test.cjs.map +1 -1
- package/dist/cjs/store/index.cjs +4 -4
- package/dist/cjs/store/index.cjs.map +1 -1
- package/dist/cjs/store/index.d.ts +4 -4
- package/dist/cjs/store/index.d.ts.map +1 -1
- package/dist/cjs/tools/proposeFormValuesTool.d.ts +2 -2
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -0
- package/dist/esm/config.d.ts +57 -23
- package/dist/esm/config.d.ts.map +1 -1
- package/dist/esm/config.js +88 -36
- package/dist/esm/config.js.map +1 -1
- package/dist/esm/helpers/AIHelper.d.ts +21 -13
- package/dist/esm/helpers/AIHelper.d.ts.map +1 -1
- package/dist/esm/helpers/AIHelper.js +159 -98
- package/dist/esm/helpers/AIHelper.js.map +1 -1
- package/dist/esm/helpers/AIHelper.test.js +21 -14
- package/dist/esm/helpers/AIHelper.test.js.map +1 -1
- package/dist/esm/helpers/ConfigHelper.d.ts.map +1 -1
- package/dist/esm/helpers/ConfigHelper.js +17 -9
- package/dist/esm/helpers/ConfigHelper.js.map +1 -1
- package/dist/esm/helpers/ContextLimiter.js +2 -3
- package/dist/esm/helpers/ContextLimiter.js.map +1 -1
- package/dist/esm/helpers/FileHelper.d.ts +19 -25
- package/dist/esm/helpers/FileHelper.d.ts.map +1 -1
- package/dist/esm/helpers/FileHelper.js +132 -149
- package/dist/esm/helpers/FileHelper.js.map +1 -1
- package/dist/esm/helpers/index.d.ts +4 -5
- package/dist/esm/helpers/index.d.ts.map +1 -1
- package/dist/esm/helpers/index.js +4 -5
- package/dist/esm/helpers/index.js.map +1 -1
- package/dist/esm/index.d.ts +42 -13
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +87 -12
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/libs/index.d.ts +2 -3
- package/dist/esm/libs/index.d.ts.map +1 -1
- package/dist/esm/libs/index.js +2 -3
- package/dist/esm/libs/index.js.map +1 -1
- package/dist/esm/libs/logger/index.d.ts +2 -2
- package/dist/esm/libs/logger/index.d.ts.map +1 -1
- package/dist/esm/libs/logger/index.js +2 -2
- package/dist/esm/libs/logger/index.js.map +1 -1
- package/dist/esm/libs/logger/kafkajs-logger-creator.js +1 -1
- package/dist/esm/libs/logger/kafkajs-logger-creator.js.map +1 -1
- package/dist/esm/libs/s3/index.d.ts +1 -2
- package/dist/esm/libs/s3/index.d.ts.map +1 -1
- package/dist/esm/libs/s3/index.js +1 -2
- package/dist/esm/libs/s3/index.js.map +1 -1
- package/dist/esm/libs/s3/s3.lib.d.ts +29 -22
- package/dist/esm/libs/s3/s3.lib.d.ts.map +1 -1
- package/dist/esm/libs/s3/s3.lib.js +178 -177
- package/dist/esm/libs/s3/s3.lib.js.map +1 -1
- package/dist/esm/processors/ActivityProcessor.d.ts +27 -0
- package/dist/esm/processors/ActivityProcessor.d.ts.map +1 -0
- package/dist/esm/processors/ActivityProcessor.js +33 -0
- package/dist/esm/processors/ActivityProcessor.js.map +1 -0
- package/dist/esm/processors/ActivityProcessor.test.d.ts +2 -0
- package/dist/esm/processors/ActivityProcessor.test.d.ts.map +1 -0
- package/dist/esm/processors/ActivityProcessor.test.js +82 -0
- package/dist/esm/processors/ActivityProcessor.test.js.map +1 -0
- package/dist/esm/processors/ChatProcessor.d.ts +56 -9
- package/dist/esm/processors/ChatProcessor.d.ts.map +1 -1
- package/dist/esm/processors/ChatProcessor.js +334 -153
- package/dist/esm/processors/ChatProcessor.js.map +1 -1
- package/dist/esm/processors/ChatProcessor.test.d.ts +2 -0
- package/dist/esm/processors/ChatProcessor.test.d.ts.map +1 -0
- package/dist/esm/processors/ChatProcessor.test.js +448 -0
- package/dist/esm/processors/ChatProcessor.test.js.map +1 -0
- package/dist/esm/processors/ModelsProcessor.js +1 -1
- package/dist/esm/processors/ModelsProcessor.js.map +1 -1
- package/dist/esm/processors/index.d.ts +3 -2
- package/dist/esm/processors/index.d.ts.map +1 -1
- package/dist/esm/processors/index.js +3 -2
- package/dist/esm/processors/index.js.map +1 -1
- package/dist/esm/services/AIService.d.ts +16 -5
- package/dist/esm/services/AIService.d.ts.map +1 -1
- package/dist/esm/services/AIService.js +53 -32
- package/dist/esm/services/AIService.js.map +1 -1
- package/dist/esm/services/InternalEventsHandler.d.ts +3 -1
- package/dist/esm/services/InternalEventsHandler.d.ts.map +1 -1
- package/dist/esm/services/InternalEventsHandler.js +10 -8
- package/dist/esm/services/InternalEventsHandler.js.map +1 -1
- package/dist/esm/services/ModelFetcher.d.ts +2 -7
- package/dist/esm/services/ModelFetcher.d.ts.map +1 -1
- package/dist/esm/services/ModelFetcher.js +4 -9
- package/dist/esm/services/ModelFetcher.js.map +1 -1
- package/dist/esm/services/RedisService.d.ts +5 -2
- package/dist/esm/services/RedisService.d.ts.map +1 -1
- package/dist/esm/services/RedisService.js +25 -21
- package/dist/esm/services/RedisService.js.map +1 -1
- package/dist/esm/services/SocketService.d.ts +9 -6
- package/dist/esm/services/SocketService.d.ts.map +1 -1
- package/dist/esm/services/SocketService.js +15 -13
- package/dist/esm/services/SocketService.js.map +1 -1
- package/dist/esm/services/index.d.ts +5 -6
- package/dist/esm/services/index.d.ts.map +1 -1
- package/dist/esm/services/index.js +5 -6
- package/dist/esm/services/index.js.map +1 -1
- package/dist/esm/store/AgentStore.d.ts +2 -1
- package/dist/esm/store/AgentStore.d.ts.map +1 -1
- package/dist/esm/store/AgentStore.js +5 -5
- package/dist/esm/store/AgentStore.js.map +1 -1
- package/dist/esm/store/ArtifactStore.js +3 -7
- package/dist/esm/store/ArtifactStore.js.map +1 -1
- package/dist/esm/store/ConfigStore.d.ts.map +1 -1
- package/dist/esm/store/ConfigStore.js +16 -19
- package/dist/esm/store/ConfigStore.js.map +1 -1
- package/dist/esm/store/ConfigStore.test.js +1 -1
- package/dist/esm/store/ConfigStore.test.js.map +1 -1
- package/dist/esm/store/ModelStore.js +6 -6
- package/dist/esm/store/ModelStore.js.map +1 -1
- package/dist/esm/store/ModelStore.test.js +12 -12
- package/dist/esm/store/ModelStore.test.js.map +1 -1
- package/dist/esm/store/index.d.ts +4 -4
- package/dist/esm/store/index.d.ts.map +1 -1
- package/dist/esm/store/index.js +4 -4
- package/dist/esm/store/index.js.map +1 -1
- package/dist/esm/tools/proposeFormValuesTool.d.ts +2 -2
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -0
- package/package.json +15 -15
- package/dist/cjs/helpers/SetupHelper.cjs +0 -37
- package/dist/cjs/helpers/SetupHelper.cjs.map +0 -1
- package/dist/cjs/helpers/SetupHelper.d.ts +0 -5
- package/dist/cjs/helpers/SetupHelper.d.ts.map +0 -1
- package/dist/cjs/libs/kafka/config.cjs +0 -8
- package/dist/cjs/libs/kafka/config.cjs.map +0 -1
- package/dist/cjs/libs/kafka/config.d.ts +0 -5
- package/dist/cjs/libs/kafka/config.d.ts.map +0 -1
- package/dist/cjs/libs/kafka/consumer.cjs +0 -133
- package/dist/cjs/libs/kafka/consumer.cjs.map +0 -1
- package/dist/cjs/libs/kafka/consumer.d.ts +0 -16
- package/dist/cjs/libs/kafka/consumer.d.ts.map +0 -1
- package/dist/cjs/libs/kafka/index.cjs +0 -19
- package/dist/cjs/libs/kafka/index.cjs.map +0 -1
- package/dist/cjs/libs/kafka/index.d.ts +0 -3
- package/dist/cjs/libs/kafka/index.d.ts.map +0 -1
- package/dist/cjs/libs/kafka/kafka.cjs +0 -27
- package/dist/cjs/libs/kafka/kafka.cjs.map +0 -1
- package/dist/cjs/libs/kafka/kafka.d.ts +0 -3
- package/dist/cjs/libs/kafka/kafka.d.ts.map +0 -1
- package/dist/cjs/libs/kafka/producer.cjs +0 -48
- package/dist/cjs/libs/kafka/producer.cjs.map +0 -1
- package/dist/cjs/libs/kafka/producer.d.ts +0 -11
- package/dist/cjs/libs/kafka/producer.d.ts.map +0 -1
- package/dist/cjs/libs/logger/config.cjs +0 -9
- package/dist/cjs/libs/logger/config.cjs.map +0 -1
- package/dist/cjs/libs/logger/config.d.ts +0 -5
- package/dist/cjs/libs/logger/config.d.ts.map +0 -1
- package/dist/cjs/libs/s3/config.cjs +0 -10
- package/dist/cjs/libs/s3/config.cjs.map +0 -1
- package/dist/cjs/libs/s3/config.d.ts +0 -7
- package/dist/cjs/libs/s3/config.d.ts.map +0 -1
- package/dist/cjs/services/KafkaService.cjs +0 -123
- package/dist/cjs/services/KafkaService.cjs.map +0 -1
- package/dist/cjs/services/KafkaService.d.ts +0 -35
- package/dist/cjs/services/KafkaService.d.ts.map +0 -1
- package/dist/esm/helpers/SetupHelper.d.ts +0 -5
- package/dist/esm/helpers/SetupHelper.d.ts.map +0 -1
- package/dist/esm/helpers/SetupHelper.js +0 -32
- package/dist/esm/helpers/SetupHelper.js.map +0 -1
- package/dist/esm/libs/kafka/config.d.ts +0 -5
- package/dist/esm/libs/kafka/config.d.ts.map +0 -1
- package/dist/esm/libs/kafka/config.js +0 -5
- package/dist/esm/libs/kafka/config.js.map +0 -1
- package/dist/esm/libs/kafka/consumer.d.ts +0 -16
- package/dist/esm/libs/kafka/consumer.d.ts.map +0 -1
- package/dist/esm/libs/kafka/consumer.js +0 -126
- package/dist/esm/libs/kafka/consumer.js.map +0 -1
- package/dist/esm/libs/kafka/index.d.ts +0 -3
- package/dist/esm/libs/kafka/index.d.ts.map +0 -1
- package/dist/esm/libs/kafka/index.js +0 -3
- package/dist/esm/libs/kafka/index.js.map +0 -1
- package/dist/esm/libs/kafka/kafka.d.ts +0 -3
- package/dist/esm/libs/kafka/kafka.d.ts.map +0 -1
- package/dist/esm/libs/kafka/kafka.js +0 -24
- package/dist/esm/libs/kafka/kafka.js.map +0 -1
- package/dist/esm/libs/kafka/producer.d.ts +0 -11
- package/dist/esm/libs/kafka/producer.d.ts.map +0 -1
- package/dist/esm/libs/kafka/producer.js +0 -44
- package/dist/esm/libs/kafka/producer.js.map +0 -1
- package/dist/esm/libs/logger/config.d.ts +0 -5
- package/dist/esm/libs/logger/config.d.ts.map +0 -1
- package/dist/esm/libs/logger/config.js +0 -6
- package/dist/esm/libs/logger/config.js.map +0 -1
- package/dist/esm/libs/s3/config.d.ts +0 -7
- package/dist/esm/libs/s3/config.d.ts.map +0 -1
- package/dist/esm/libs/s3/config.js +0 -7
- package/dist/esm/libs/s3/config.js.map +0 -1
- package/dist/esm/services/KafkaService.d.ts +0 -35
- package/dist/esm/services/KafkaService.d.ts.map +0 -1
- package/dist/esm/services/KafkaService.js +0 -120
- package/dist/esm/services/KafkaService.js.map +0 -1
- package/dist/tsconfig.cjs.tsbuildinfo +0 -1
- package/dist/tsconfig.esm.tsbuildinfo +0 -1
|
@@ -2,67 +2,185 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ChatProcessor = void 0;
|
|
4
4
|
const ai_agent_types_1 = require("@multiplayer-app/ai-agent-types");
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const index_js_4 = require("../store/index.js");
|
|
9
|
-
const index_js_5 = require("../helpers/index.js");
|
|
10
|
-
const config_js_1 = require("../config.js");
|
|
5
|
+
const helpers_1 = require("../helpers/index.cjs");
|
|
6
|
+
const store_1 = require("../store/index.cjs");
|
|
7
|
+
const helpers_2 = require("../helpers/index.cjs");
|
|
11
8
|
const stream_1 = require("stream");
|
|
12
|
-
const
|
|
13
|
-
const index_js_6 = require("../libs/logger/index.js");
|
|
14
|
-
const pipelineAsync = (0, util_1.promisify)(stream_1.pipeline);
|
|
9
|
+
const logger_1 = require("../libs/logger/index.cjs");
|
|
15
10
|
class ChatProcessor {
|
|
16
|
-
constructor(
|
|
17
|
-
this.chatRepository = chatRepository;
|
|
18
|
-
this.messageRepository = messageRepository;
|
|
19
|
-
this.artifactStore = artifactStore;
|
|
11
|
+
constructor(params) {
|
|
12
|
+
this.chatRepository = params.chatRepository;
|
|
13
|
+
this.messageRepository = params.messageRepository;
|
|
14
|
+
this.artifactStore = params.artifactStore;
|
|
15
|
+
this.config = params.config;
|
|
16
|
+
this.socketService = params.socketService;
|
|
17
|
+
this.agentStore = params.agentStore;
|
|
18
|
+
this.activityRepository = params.activityRepository;
|
|
19
|
+
const fileHelper = new helpers_1.FileHelper(params.s3Lib, this.config);
|
|
20
|
+
this.aiHelper = new helpers_1.AIHelper(fileHelper, this.config);
|
|
21
|
+
this.debug = this.config.debug;
|
|
20
22
|
}
|
|
21
23
|
getTemporaryTitle(contextKey) {
|
|
22
24
|
return `${contextKey} session ${new Date().toISOString()}`;
|
|
23
25
|
}
|
|
26
|
+
isTemporaryTitle(title) {
|
|
27
|
+
// Matches pattern: "{contextKey} session {ISO_DATE_STRING}"
|
|
28
|
+
// Example: "default session 2026-01-23T10:30:45.123Z"
|
|
29
|
+
// toISOString() always includes milliseconds, so we require them
|
|
30
|
+
const pattern = /^.+ session \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/;
|
|
31
|
+
return pattern.test(title);
|
|
32
|
+
}
|
|
33
|
+
sanitizeProviderMetadata(providerMetadata) {
|
|
34
|
+
return this.stripReasoningMetadata(providerMetadata);
|
|
35
|
+
}
|
|
36
|
+
isPlainObject(value) {
|
|
37
|
+
return !!value && typeof value === 'object' && !Array.isArray(value);
|
|
38
|
+
}
|
|
39
|
+
mergeMissingUsageFields(target, source) {
|
|
40
|
+
for (const [key, sourceValue] of Object.entries(source)) {
|
|
41
|
+
const targetValue = target[key];
|
|
42
|
+
if (targetValue === undefined) {
|
|
43
|
+
target[key] = sourceValue;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (this.isPlainObject(targetValue) && this.isPlainObject(sourceValue)) {
|
|
47
|
+
this.mergeMissingUsageFields(targetValue, sourceValue);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
extractCostUsageFields(source) {
|
|
52
|
+
const extracted = {};
|
|
53
|
+
for (const [key, value] of Object.entries(source)) {
|
|
54
|
+
const normalizedKey = key.toLowerCase();
|
|
55
|
+
if (normalizedKey.includes('cost')) {
|
|
56
|
+
extracted[key] = value;
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
if (this.isPlainObject(value)) {
|
|
60
|
+
const nestedCostFields = this.extractCostUsageFields(value);
|
|
61
|
+
if (Object.keys(nestedCostFields).length > 0) {
|
|
62
|
+
extracted[key] = nestedCostFields;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return extracted;
|
|
67
|
+
}
|
|
68
|
+
mergeUsageWithProviderMetadata(stepUsage, providerMetadata) {
|
|
69
|
+
const mergedUsage = this.isPlainObject(stepUsage) ? { ...stepUsage } : {};
|
|
70
|
+
let hasProviderUsage = false;
|
|
71
|
+
if (this.isPlainObject(providerMetadata)) {
|
|
72
|
+
for (const providerEntry of Object.values(providerMetadata)) {
|
|
73
|
+
if (!this.isPlainObject(providerEntry) || !this.isPlainObject(providerEntry.usage)) {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
const providerCostUsage = this.extractCostUsageFields(providerEntry.usage);
|
|
77
|
+
if (Object.keys(providerCostUsage).length === 0) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
hasProviderUsage = true;
|
|
81
|
+
this.mergeMissingUsageFields(mergedUsage, providerCostUsage);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (this.isPlainObject(stepUsage)) {
|
|
85
|
+
return mergedUsage;
|
|
86
|
+
}
|
|
87
|
+
if (hasProviderUsage) {
|
|
88
|
+
return mergedUsage;
|
|
89
|
+
}
|
|
90
|
+
return stepUsage;
|
|
91
|
+
}
|
|
92
|
+
stripReasoningMetadata(value) {
|
|
93
|
+
if (Array.isArray(value)) {
|
|
94
|
+
return value
|
|
95
|
+
.map((entry) => this.stripReasoningMetadata(entry))
|
|
96
|
+
.filter((entry) => entry !== undefined);
|
|
97
|
+
}
|
|
98
|
+
if (!value || typeof value !== 'object') {
|
|
99
|
+
return value;
|
|
100
|
+
}
|
|
101
|
+
const record = value;
|
|
102
|
+
const entryType = record.type;
|
|
103
|
+
if (typeof entryType === 'string' && entryType.startsWith('reasoning.')) {
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
const sanitized = {};
|
|
107
|
+
for (const [key, entryValue] of Object.entries(record)) {
|
|
108
|
+
const normalizedKey = key.toLowerCase();
|
|
109
|
+
if (normalizedKey === 'reasoning_details' ||
|
|
110
|
+
normalizedKey === 'reasoningdetails' ||
|
|
111
|
+
normalizedKey === 'reasoning') {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
const sanitizedValue = this.stripReasoningMetadata(entryValue);
|
|
115
|
+
if (sanitizedValue !== undefined) {
|
|
116
|
+
sanitized[key] = sanitizedValue;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return sanitized;
|
|
120
|
+
}
|
|
24
121
|
async listChats(params) {
|
|
25
|
-
var _a, _b;
|
|
26
122
|
// Build filter object from params
|
|
27
123
|
const filter = {};
|
|
28
|
-
if (params
|
|
124
|
+
if (params?.userId) {
|
|
29
125
|
filter.userId = params.userId;
|
|
30
126
|
}
|
|
31
|
-
if (params
|
|
127
|
+
if (params?.contextKey) {
|
|
32
128
|
filter.contextKey = params.contextKey;
|
|
33
129
|
}
|
|
34
|
-
// Build query options for sort and limit with defaults
|
|
130
|
+
// Build query options for sort and limit with defaults.
|
|
35
131
|
const options = {
|
|
36
132
|
sort: {
|
|
37
|
-
field:
|
|
38
|
-
order:
|
|
133
|
+
field: params?.sortField ?? 'updatedAt',
|
|
134
|
+
order: params?.sortOrder ?? ai_agent_types_1.SortOrder.Desc
|
|
39
135
|
},
|
|
40
|
-
|
|
136
|
+
skip: params?.skip,
|
|
137
|
+
limit: params?.limit
|
|
138
|
+
};
|
|
139
|
+
const [total, data] = await Promise.all([
|
|
140
|
+
this.chatRepository.count(filter),
|
|
141
|
+
this.chatRepository.find(filter, options)
|
|
142
|
+
]);
|
|
143
|
+
return {
|
|
144
|
+
cursor: {
|
|
145
|
+
...(params?.skip != null ? { skip: params.skip } : {}),
|
|
146
|
+
...(params?.limit != null ? { limit: params.limit } : {}),
|
|
147
|
+
total
|
|
148
|
+
},
|
|
149
|
+
data
|
|
41
150
|
};
|
|
42
|
-
// Use aggregation to fetch chats with related messages
|
|
43
|
-
return this.chatRepository.findWithMessages(filter, options);
|
|
44
151
|
}
|
|
45
152
|
async getChat(chatId) {
|
|
46
153
|
const chat = await this.chatRepository.findById(chatId);
|
|
47
154
|
if (!chat) {
|
|
48
155
|
throw new Error('Chat not found');
|
|
49
156
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
157
|
+
return chat;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Get messages for a chat with optional cursor pagination.
|
|
161
|
+
* When limit is omitted, returns all messages (backward compatible).
|
|
162
|
+
* Messages are returned in chronological order (oldest → newest).
|
|
163
|
+
*/
|
|
164
|
+
async getMessages(chatId, options) {
|
|
165
|
+
const chat = await this.chatRepository.findById(chatId);
|
|
166
|
+
if (!chat) {
|
|
167
|
+
throw new Error('Chat not found');
|
|
168
|
+
}
|
|
169
|
+
return this.messageRepository.findByChatIdPaginated(chatId, options);
|
|
55
170
|
}
|
|
56
171
|
async deleteChat(chatId) {
|
|
57
172
|
const deleted = await this.chatRepository.delete(chatId);
|
|
58
173
|
if (!deleted) {
|
|
59
174
|
throw new Error('Chat not found');
|
|
60
175
|
}
|
|
176
|
+
await Promise.all([
|
|
177
|
+
this.messageRepository.deleteByChatId(chatId),
|
|
178
|
+
this.activityRepository.deleteByGroupId(chatId), // todo: discuss if this is needed
|
|
179
|
+
]);
|
|
61
180
|
this.artifactStore.deleteArtifacts(chatId);
|
|
62
181
|
}
|
|
63
182
|
async upsertAndGetChat(payload, excludeSocketId) {
|
|
64
|
-
|
|
65
|
-
const targetUserId = (_a = payload.userId) !== null && _a !== void 0 ? _a : 'guest';
|
|
183
|
+
const targetUserId = payload.userId ?? 'guest';
|
|
66
184
|
let chat = null;
|
|
67
185
|
if (payload.chatId) {
|
|
68
186
|
chat = await this.chatRepository.findById(payload.chatId);
|
|
@@ -94,7 +212,7 @@ class ChatProcessor {
|
|
|
94
212
|
if (!content) {
|
|
95
213
|
return this.getTemporaryTitle(payload.contextKey);
|
|
96
214
|
}
|
|
97
|
-
return
|
|
215
|
+
return this.aiHelper.generateTitleForMessage(payload.contextKey, [{
|
|
98
216
|
role: ai_agent_types_1.MessageRole.User,
|
|
99
217
|
content: content
|
|
100
218
|
}]);
|
|
@@ -105,18 +223,17 @@ class ChatProcessor {
|
|
|
105
223
|
role,
|
|
106
224
|
content: messageData.content,
|
|
107
225
|
agentName: messageData.agentName,
|
|
108
|
-
attachments: attachments
|
|
226
|
+
attachments: attachments ?? [],
|
|
109
227
|
reasoning: "",
|
|
110
228
|
toolCalls: []
|
|
111
229
|
});
|
|
112
230
|
if (chat.userId) {
|
|
113
|
-
|
|
231
|
+
this.socketService.emitMessageUpdate(chat.userId, message, excludeSocketId);
|
|
114
232
|
}
|
|
115
233
|
return message;
|
|
116
234
|
}
|
|
117
235
|
async createChat(payload, excludeSocketId) {
|
|
118
|
-
|
|
119
|
-
const targetUserId = (_a = payload.userId) !== null && _a !== void 0 ? _a : 'guest';
|
|
236
|
+
const targetUserId = payload.userId ?? 'guest';
|
|
120
237
|
const contextKey = 'contextKey' in payload ? payload.contextKey : 'default';
|
|
121
238
|
const metadata = 'metadata' in payload ? payload.metadata : {};
|
|
122
239
|
const chat = await this.chatRepository.create({
|
|
@@ -128,12 +245,7 @@ class ChatProcessor {
|
|
|
128
245
|
metadata,
|
|
129
246
|
...(payload.model ? { model: payload.model } : {})
|
|
130
247
|
});
|
|
131
|
-
|
|
132
|
-
const initialChatResponse = {
|
|
133
|
-
...chat,
|
|
134
|
-
messages: []
|
|
135
|
-
};
|
|
136
|
-
index_js_1.socketService.emitChatUpdate(targetUserId, initialChatResponse, excludeSocketId);
|
|
248
|
+
this.socketService.emitChatUpdate(targetUserId, chat, excludeSocketId);
|
|
137
249
|
return chat;
|
|
138
250
|
}
|
|
139
251
|
/**
|
|
@@ -141,23 +253,22 @@ class ChatProcessor {
|
|
|
141
253
|
* This updates the message containing the tool call and optionally appends a System message.
|
|
142
254
|
*/
|
|
143
255
|
async recordToolCallAction(params) {
|
|
144
|
-
var _a, _b, _c, _d;
|
|
145
256
|
const chat = await this.chatRepository.findById(params.chatId);
|
|
146
257
|
if (!chat) {
|
|
147
258
|
throw new Error('Chat not found');
|
|
148
259
|
}
|
|
149
260
|
const messages = await this.messageRepository.findByChatId(params.chatId);
|
|
150
|
-
const message = messages.find((m) =>
|
|
261
|
+
const message = messages.find((m) => (m.toolCalls ?? []).some((c) => c.id === params.toolCallId));
|
|
151
262
|
if (!message) {
|
|
152
263
|
throw new Error('Tool call not found');
|
|
153
264
|
}
|
|
154
|
-
const toolCalls =
|
|
265
|
+
const toolCalls = message.toolCalls ?? [];
|
|
155
266
|
const target = toolCalls.find((c) => c.id === params.toolCallId);
|
|
156
267
|
if (!target) {
|
|
157
268
|
throw new Error('Tool call not found');
|
|
158
269
|
}
|
|
159
270
|
const now = new Date().toISOString();
|
|
160
|
-
const output = (
|
|
271
|
+
const output = (target.output ?? {});
|
|
161
272
|
const mp = (output['_mp'] && typeof output['_mp'] === 'object' && !Array.isArray(output['_mp']))
|
|
162
273
|
? output['_mp']
|
|
163
274
|
: {};
|
|
@@ -167,14 +278,14 @@ class ChatProcessor {
|
|
|
167
278
|
lastAction: {
|
|
168
279
|
action: params.action,
|
|
169
280
|
at: now,
|
|
170
|
-
data:
|
|
281
|
+
data: params.data ?? {},
|
|
171
282
|
},
|
|
172
283
|
actions: [
|
|
173
284
|
...actions,
|
|
174
285
|
{
|
|
175
286
|
action: params.action,
|
|
176
287
|
at: now,
|
|
177
|
-
data:
|
|
288
|
+
data: params.data ?? {},
|
|
178
289
|
}
|
|
179
290
|
]
|
|
180
291
|
};
|
|
@@ -189,7 +300,7 @@ class ChatProcessor {
|
|
|
189
300
|
await this.messageRepository.update(message.id, { toolCalls });
|
|
190
301
|
// Bump chat updatedAt so listChats ordering reflects the action.
|
|
191
302
|
await this.chatRepository.update(chat.id, { updatedAt: now });
|
|
192
|
-
|
|
303
|
+
this.socketService.emitMessageUpdate(chat.userId, updatedMessage, params.excludeSocketId);
|
|
193
304
|
if (params.systemMessage) {
|
|
194
305
|
//todo discuss support for system messages
|
|
195
306
|
//await this.createMessage(chat, MessageRole.System, params.systemMessage, undefined, params.excludeSocketId);
|
|
@@ -197,26 +308,25 @@ class ChatProcessor {
|
|
|
197
308
|
return { ok: true };
|
|
198
309
|
}
|
|
199
310
|
async streamMessageStep(params) {
|
|
200
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
201
311
|
const { chat, assistantMessage, existingMessages, signal, excludeSocketId, agentOptions } = params;
|
|
202
312
|
if (signal.aborted) {
|
|
203
313
|
return;
|
|
204
314
|
}
|
|
205
|
-
const result = await
|
|
315
|
+
const result = await this.aiHelper.streamAssistantResponse(existingMessages, signal, agentOptions);
|
|
206
316
|
try {
|
|
207
317
|
for await (const chunk of result.fullStream) {
|
|
208
318
|
if (chunk.type === 'error') {
|
|
209
|
-
await
|
|
319
|
+
await this.agentStore.shareAgentProcessEvent(chat.id, { type: store_1.AgentProcessEventType.Error, data: chunk.error });
|
|
210
320
|
assistantMessage.content = chunk.error.message || 'Sorry, I cannot process you request due to the error';
|
|
211
321
|
await this.messageRepository.update(assistantMessage.id, assistantMessage);
|
|
212
322
|
await this.chatRepository.update(chat.id, { status: ai_agent_types_1.AgentStatus.Error });
|
|
213
323
|
continue;
|
|
214
324
|
}
|
|
215
325
|
if (chunk.type === 'abort') {
|
|
216
|
-
await
|
|
326
|
+
await this.agentStore.shareAgentProcessEvent(chat.id, { type: store_1.AgentProcessEventType.Aborted, data: undefined });
|
|
217
327
|
await this.chatRepository.update(chat.id, { status: ai_agent_types_1.AgentStatus.Aborted });
|
|
218
328
|
await this.messageRepository.update(assistantMessage.id, assistantMessage);
|
|
219
|
-
|
|
329
|
+
this.socketService.emitMessageUpdate(chat.userId, assistantMessage, excludeSocketId);
|
|
220
330
|
continue;
|
|
221
331
|
}
|
|
222
332
|
if (chunk.type === 'finish') {
|
|
@@ -229,41 +339,44 @@ class ChatProcessor {
|
|
|
229
339
|
}
|
|
230
340
|
if (chunk.totalUsage && typeof chunk.totalUsage === 'object') {
|
|
231
341
|
const totalUsage = chunk.totalUsage;
|
|
232
|
-
assistantMessage.tokens =
|
|
342
|
+
assistantMessage.tokens = totalUsage.totalTokens ??
|
|
343
|
+
((totalUsage.promptTokens ?? 0) + (totalUsage.completionTokens ?? 0));
|
|
233
344
|
}
|
|
234
345
|
await this.messageRepository.update(assistantMessage.id, { ...assistantMessage });
|
|
235
346
|
if (chunk.finishReason === 'stop') {
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
347
|
+
await this.chatRepository.update(chat.id, { status: ai_agent_types_1.AgentStatus.Finished });
|
|
348
|
+
if (chat.title && this.isTemporaryTitle(chat.title)) {
|
|
349
|
+
const title = await this.aiHelper.generateTitleForMessage(chat.contextKey, existingMessages.filter(m => m.role === ai_agent_types_1.MessageRole.User), (stepResult) => {
|
|
350
|
+
return this.storeStepActivity({
|
|
351
|
+
chat,
|
|
352
|
+
stepResult,
|
|
353
|
+
name: ai_agent_types_1.ActivityOperationName.TITLE_GENERATION,
|
|
354
|
+
sourceId: chat.id,
|
|
355
|
+
sourceType: 'Chat',
|
|
356
|
+
tenants: params.tenants || {},
|
|
357
|
+
});
|
|
358
|
+
});
|
|
359
|
+
await this.chatRepository.update(chat.id, { title });
|
|
360
|
+
this.socketService.emitChatUpdate(chat.userId, { ...chat, title });
|
|
247
361
|
}
|
|
248
|
-
await index_js_4.agentStore.shareAgentProcessEvent(chat.id, { type: index_js_4.AgentProcessEventType.Finished, data: assistantMessage });
|
|
249
|
-
continue;
|
|
250
362
|
}
|
|
251
363
|
if (chunk.finishReason === 'tool-calls') {
|
|
252
|
-
if (
|
|
364
|
+
if (assistantMessage.toolCalls?.some(toolCall => toolCall.requiresConfirmation && toolCall.approvalId && !toolCall.output)) {
|
|
253
365
|
await this.chatRepository.update(chat.id, { status: ai_agent_types_1.AgentStatus.WaitingForUserAction });
|
|
254
|
-
await
|
|
255
|
-
|
|
256
|
-
else {
|
|
257
|
-
await index_js_4.agentStore.shareAgentProcessEvent(chat.id, {
|
|
258
|
-
type: index_js_4.AgentProcessEventType.Update,
|
|
259
|
-
data: assistantMessage
|
|
260
|
-
});
|
|
261
|
-
await this.streamMessageStep(params);
|
|
366
|
+
await this.agentStore.shareAgentProcessEvent(chat.id, { type: store_1.AgentProcessEventType.Finished, data: assistantMessage });
|
|
367
|
+
continue;
|
|
262
368
|
}
|
|
263
|
-
continue;
|
|
264
369
|
}
|
|
265
370
|
//todo: Handle other finish reasons // length, content, error, other, undefined
|
|
266
|
-
await
|
|
371
|
+
await this.agentStore.shareAgentProcessEvent(chat.id, { type: store_1.AgentProcessEventType.Finished, data: assistantMessage });
|
|
372
|
+
if (assistantMessage.activity) {
|
|
373
|
+
const groupedMeta = await this.activityRepository.getGroupedMetadataByParentId(assistantMessage.activity);
|
|
374
|
+
await this.activityRepository.updateMetadata(assistantMessage.activity, {
|
|
375
|
+
usage: groupedMeta,
|
|
376
|
+
finishReason: chunk.finishReason,
|
|
377
|
+
responseTimestamp: new Date().toISOString(),
|
|
378
|
+
});
|
|
379
|
+
}
|
|
267
380
|
continue;
|
|
268
381
|
}
|
|
269
382
|
if (chunk.type === 'text-delta') {
|
|
@@ -272,8 +385,8 @@ class ChatProcessor {
|
|
|
272
385
|
...assistantMessage,
|
|
273
386
|
content: assistantMessage.content
|
|
274
387
|
};
|
|
275
|
-
|
|
276
|
-
await
|
|
388
|
+
this.socketService.emitMessageUpdate(chat.userId, updatedMessage, excludeSocketId);
|
|
389
|
+
await this.agentStore.shareAgentProcessEvent(chat.id, { type: store_1.AgentProcessEventType.Update, data: updatedMessage });
|
|
277
390
|
await this.messageRepository.update(assistantMessage.id, { content: assistantMessage.content });
|
|
278
391
|
continue;
|
|
279
392
|
}
|
|
@@ -288,8 +401,8 @@ class ChatProcessor {
|
|
|
288
401
|
});
|
|
289
402
|
continue;
|
|
290
403
|
}
|
|
291
|
-
if (chunk.type === 'tool-call') {
|
|
292
|
-
const toolCall =
|
|
404
|
+
if (chunk.type === 'tool-call') {
|
|
405
|
+
const toolCall = assistantMessage.toolCalls?.find(toolCall => toolCall.id === chunk.toolCallId);
|
|
293
406
|
if (toolCall) {
|
|
294
407
|
toolCall.status = ai_agent_types_1.AgentToolCallStatus.Running;
|
|
295
408
|
toolCall.input = chunk.input;
|
|
@@ -297,15 +410,15 @@ class ChatProcessor {
|
|
|
297
410
|
continue;
|
|
298
411
|
}
|
|
299
412
|
if (chunk.type === 'tool-error') {
|
|
300
|
-
const toolCall =
|
|
413
|
+
const toolCall = assistantMessage.toolCalls?.find(toolCall => toolCall.id === chunk.toolCallId);
|
|
301
414
|
if (toolCall) {
|
|
302
415
|
toolCall.status = ai_agent_types_1.AgentToolCallStatus.Failed;
|
|
303
|
-
toolCall.error = JSON.stringify(chunk.error);
|
|
416
|
+
toolCall.error = chunk.error.message || JSON.stringify(chunk.error);
|
|
304
417
|
}
|
|
305
418
|
continue;
|
|
306
419
|
}
|
|
307
420
|
if (chunk.type === 'tool-approval-request') {
|
|
308
|
-
const toolCall =
|
|
421
|
+
const toolCall = assistantMessage.toolCalls?.find(toolCall => toolCall.id === chunk.toolCall.toolCallId);
|
|
309
422
|
if (toolCall) {
|
|
310
423
|
toolCall.requiresConfirmation = true;
|
|
311
424
|
toolCall.approvalId = chunk.approvalId;
|
|
@@ -313,7 +426,7 @@ class ChatProcessor {
|
|
|
313
426
|
continue;
|
|
314
427
|
}
|
|
315
428
|
if (chunk.type === 'tool-result') {
|
|
316
|
-
const toolCall =
|
|
429
|
+
const toolCall = assistantMessage.toolCalls?.find(toolCall => toolCall.id === chunk.toolCallId);
|
|
317
430
|
if (toolCall) {
|
|
318
431
|
if (chunk.output.requiresApproval) {
|
|
319
432
|
toolCall.requiresConfirmation = true;
|
|
@@ -328,9 +441,9 @@ class ChatProcessor {
|
|
|
328
441
|
if (!assistantMessage.reasoning)
|
|
329
442
|
assistantMessage.reasoning = '';
|
|
330
443
|
assistantMessage.reasoning += chunk.text;
|
|
331
|
-
|
|
444
|
+
this.socketService.emitMessageUpdate(chat.userId, assistantMessage, excludeSocketId);
|
|
332
445
|
await this.messageRepository.update(assistantMessage.id, { reasoning: assistantMessage.reasoning });
|
|
333
|
-
await
|
|
446
|
+
await this.agentStore.shareAgentProcessEvent(chat.id, { type: store_1.AgentProcessEventType.Update, data: assistantMessage });
|
|
334
447
|
continue;
|
|
335
448
|
}
|
|
336
449
|
}
|
|
@@ -339,7 +452,7 @@ class ChatProcessor {
|
|
|
339
452
|
if (streamError instanceof Error && streamError.name === 'AbortError') {
|
|
340
453
|
return;
|
|
341
454
|
}
|
|
342
|
-
await
|
|
455
|
+
await this.agentStore.shareAgentProcessEvent(chat.id, { type: store_1.AgentProcessEventType.Error, data: streamError });
|
|
343
456
|
throw streamError;
|
|
344
457
|
}
|
|
345
458
|
}
|
|
@@ -347,16 +460,15 @@ class ChatProcessor {
|
|
|
347
460
|
return 'approvalId' in payload;
|
|
348
461
|
}
|
|
349
462
|
async processApprovalPayload(chat, payload) {
|
|
350
|
-
var _a, _b, _c;
|
|
351
463
|
const assistantMessage = await this.messageRepository.findById(payload.messageId);
|
|
352
464
|
if (!assistantMessage || assistantMessage.chat !== chat.id) {
|
|
353
465
|
throw new Error(`Assistant message with id ${payload.messageId} not found`);
|
|
354
466
|
}
|
|
355
|
-
const agentOptions = await
|
|
467
|
+
const agentOptions = await this.aiHelper.getAgentOptions({
|
|
356
468
|
agentName: assistantMessage.agentName,
|
|
357
469
|
context: payload.context
|
|
358
470
|
});
|
|
359
|
-
const toolCall =
|
|
471
|
+
const toolCall = assistantMessage.toolCalls?.find(tc => tc.approvalId === payload.approvalId);
|
|
360
472
|
if (!toolCall) {
|
|
361
473
|
// continue, tool is not found
|
|
362
474
|
return {
|
|
@@ -374,14 +486,14 @@ class ChatProcessor {
|
|
|
374
486
|
toolCall.status = ai_agent_types_1.AgentToolCallStatus.Failed;
|
|
375
487
|
}
|
|
376
488
|
else {
|
|
377
|
-
const executeFunction =
|
|
489
|
+
const executeFunction = agentOptions.tools?.[toolCall.name]?.execute;
|
|
378
490
|
if (executeFunction) {
|
|
379
491
|
try {
|
|
380
492
|
toolCall.output = await executeFunction(toolCall.input, { toolCallId: toolCall.id, messages: [] });
|
|
381
493
|
toolCall.status = ai_agent_types_1.AgentToolCallStatus.Succeeded;
|
|
382
494
|
}
|
|
383
495
|
catch (error) {
|
|
384
|
-
|
|
496
|
+
logger_1.logger.error(error);
|
|
385
497
|
toolCall.status = ai_agent_types_1.AgentToolCallStatus.Failed;
|
|
386
498
|
toolCall.output = {
|
|
387
499
|
type: 'execution-denied',
|
|
@@ -405,32 +517,105 @@ class ChatProcessor {
|
|
|
405
517
|
}
|
|
406
518
|
async processNewUserMessage(chat, payload, prevMessages, excludeSocketId) {
|
|
407
519
|
const userMessage = await this.createMessage(chat, ai_agent_types_1.MessageRole.User, { content: payload.content, agentName: undefined }, payload.attachments);
|
|
408
|
-
await
|
|
409
|
-
|
|
520
|
+
await this.agentStore.shareAgentProcessEvent(chat.id, { type: store_1.AgentProcessEventType.Update, data: userMessage });
|
|
521
|
+
let assistantMessage = await this.createMessage(chat, ai_agent_types_1.MessageRole.Assistant, { content: '', agentName: undefined }, undefined, excludeSocketId);
|
|
522
|
+
const parentActivity = await this.activityRepository.create({
|
|
523
|
+
ownerId: chat.userId,
|
|
524
|
+
groupId: chat.id,
|
|
525
|
+
name: ai_agent_types_1.ActivityOperationName.MESSAGE_PROCESSING,
|
|
526
|
+
tenants: {}, //todo
|
|
527
|
+
sourceId: userMessage.id,
|
|
528
|
+
sourceType: 'AgentMessage',
|
|
529
|
+
metadata: {
|
|
530
|
+
contextKey: chat.contextKey,
|
|
531
|
+
modelId: this.aiHelper.getLanguageModelId(chat.model),
|
|
532
|
+
},
|
|
533
|
+
});
|
|
534
|
+
const agentOptions = await this.aiHelper.getAgentOptions({
|
|
410
535
|
contextKey: chat.contextKey,
|
|
411
|
-
messages:
|
|
536
|
+
messages: [...prevMessages, userMessage],
|
|
412
537
|
context: payload.context,
|
|
413
538
|
agentName: undefined,
|
|
414
539
|
modelId: chat.model,
|
|
540
|
+
}, {
|
|
541
|
+
onStepFinish: async (stepResult) => {
|
|
542
|
+
await this.storeStepActivity({
|
|
543
|
+
chat,
|
|
544
|
+
parentId: parentActivity.id,
|
|
545
|
+
stepResult,
|
|
546
|
+
name: ai_agent_types_1.ActivityOperationName.AGENT_SELECTION,
|
|
547
|
+
sourceId: userMessage.id,
|
|
548
|
+
sourceType: 'AgentMessage',
|
|
549
|
+
tenants: payload.tenants || {},
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
});
|
|
553
|
+
const updatedAssistantMessage = await this.messageRepository.update(assistantMessage.id, {
|
|
554
|
+
agentName: agentOptions.name,
|
|
555
|
+
activity: parentActivity.id
|
|
556
|
+
});
|
|
557
|
+
await this.activityRepository.update(parentActivity.id, {
|
|
558
|
+
metadata: {
|
|
559
|
+
...parentActivity.metadata,
|
|
560
|
+
agentOptions: {
|
|
561
|
+
name: agentOptions.name,
|
|
562
|
+
modelId: this.aiHelper.getLanguageModelId(agentOptions.model),
|
|
563
|
+
temperature: agentOptions.temperature,
|
|
564
|
+
maxOutputTokens: agentOptions.maxOutputTokens,
|
|
565
|
+
topP: agentOptions.topP,
|
|
566
|
+
topK: agentOptions.topK,
|
|
567
|
+
presencePenalty: agentOptions.presencePenalty,
|
|
568
|
+
frequencyPenalty: agentOptions.frequencyPenalty,
|
|
569
|
+
stopSequences: agentOptions.stopSequences,
|
|
570
|
+
seed: agentOptions.seed,
|
|
571
|
+
},
|
|
572
|
+
},
|
|
415
573
|
});
|
|
416
|
-
|
|
417
|
-
|
|
574
|
+
if (!updatedAssistantMessage) {
|
|
575
|
+
throw new Error(`Assistant message with id ${assistantMessage.id} not found after update`);
|
|
576
|
+
}
|
|
577
|
+
assistantMessage = updatedAssistantMessage;
|
|
418
578
|
return {
|
|
419
579
|
userMessage,
|
|
420
580
|
assistantMessage,
|
|
421
581
|
agentOptions,
|
|
422
582
|
};
|
|
423
583
|
}
|
|
584
|
+
async storeStepActivity(params) {
|
|
585
|
+
try {
|
|
586
|
+
const stepResult = params.stepResult;
|
|
587
|
+
const mergedUsage = this.mergeUsageWithProviderMetadata(stepResult.usage, stepResult.providerMetadata);
|
|
588
|
+
const activity = await this.activityRepository.create({
|
|
589
|
+
ownerId: params.chat.userId,
|
|
590
|
+
groupId: params.chat.id,
|
|
591
|
+
name: params.name,
|
|
592
|
+
tenants: params.tenants || {},
|
|
593
|
+
sourceId: params.sourceId,
|
|
594
|
+
sourceType: params.sourceType,
|
|
595
|
+
metadata: {
|
|
596
|
+
finishReason: stepResult.finishReason,
|
|
597
|
+
usage: mergedUsage,
|
|
598
|
+
responseTimestamp: stepResult.response.timestamp,
|
|
599
|
+
modelId: stepResult.response.modelId,
|
|
600
|
+
messages: this.debug ? stepResult.request?.body?.messages : undefined,
|
|
601
|
+
},
|
|
602
|
+
parentId: params.parentId,
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
catch (error) {
|
|
606
|
+
logger_1.logger.error({ error, chatId: params.chat.id, parentId: params.parentId }, 'Failed to store step activity');
|
|
607
|
+
}
|
|
608
|
+
}
|
|
424
609
|
async streamMessage(chat, payload, excludeSocketId, onAgentStart) {
|
|
425
610
|
try {
|
|
426
|
-
const abortController =
|
|
427
|
-
onAgentStart
|
|
611
|
+
const abortController = this.agentStore.registerAgentProcess(chat.id);
|
|
612
|
+
onAgentStart?.();
|
|
428
613
|
let assistantMessage;
|
|
429
614
|
let agentOptions;
|
|
430
615
|
const existingMessages = await this.messageRepository.findByChatId(chat.id);
|
|
431
616
|
// Limit context to prevent exceeding token limits
|
|
432
|
-
const limitedMessages =
|
|
433
|
-
maxMessages:
|
|
617
|
+
const limitedMessages = helpers_2.ContextLimiter.limitContext(existingMessages, {
|
|
618
|
+
maxMessages: this.config.ai.maxContextMessages,
|
|
434
619
|
keepFirstUserMessage: true,
|
|
435
620
|
keepSystemMessages: true,
|
|
436
621
|
});
|
|
@@ -452,6 +637,17 @@ class ChatProcessor {
|
|
|
452
637
|
agentOptions = result.agentOptions;
|
|
453
638
|
limitedMessages.push(result.userMessage);
|
|
454
639
|
}
|
|
640
|
+
agentOptions.onStepFinish = (stepResult) => {
|
|
641
|
+
return this.storeStepActivity({
|
|
642
|
+
chat,
|
|
643
|
+
parentId: assistantMessage.activity,
|
|
644
|
+
stepResult,
|
|
645
|
+
name: ai_agent_types_1.ActivityOperationName.STEP_FINISHED,
|
|
646
|
+
sourceId: assistantMessage.id,
|
|
647
|
+
sourceType: 'AgentMessage',
|
|
648
|
+
tenants: payload.tenants || {},
|
|
649
|
+
});
|
|
650
|
+
};
|
|
455
651
|
await this.streamMessageStep({
|
|
456
652
|
chat,
|
|
457
653
|
existingMessages: limitedMessages,
|
|
@@ -459,6 +655,7 @@ class ChatProcessor {
|
|
|
459
655
|
agentOptions,
|
|
460
656
|
excludeSocketId: excludeSocketId,
|
|
461
657
|
signal: abortController.signal,
|
|
658
|
+
tenants: payload.tenants || {},
|
|
462
659
|
});
|
|
463
660
|
}
|
|
464
661
|
catch (error) {
|
|
@@ -470,32 +667,32 @@ class ChatProcessor {
|
|
|
470
667
|
}
|
|
471
668
|
eventToChunk(event) {
|
|
472
669
|
switch (event.type) {
|
|
473
|
-
case
|
|
670
|
+
case store_1.AgentProcessEventType.Update:
|
|
474
671
|
return {
|
|
475
672
|
type: ai_agent_types_1.StreamChunkType.Message,
|
|
476
673
|
message: event.data
|
|
477
674
|
};
|
|
478
|
-
case
|
|
675
|
+
case store_1.AgentProcessEventType.Error:
|
|
479
676
|
return {
|
|
480
677
|
type: ai_agent_types_1.StreamChunkType.Error,
|
|
481
678
|
error: event.data.message || 'Unknown error occurred'
|
|
482
679
|
};
|
|
483
|
-
case
|
|
680
|
+
case store_1.AgentProcessEventType.Finished:
|
|
484
681
|
return {
|
|
485
682
|
type: ai_agent_types_1.StreamChunkType.Message,
|
|
486
683
|
message: event.data
|
|
487
684
|
};
|
|
488
|
-
case
|
|
685
|
+
case store_1.AgentProcessEventType.Aborted:
|
|
489
686
|
// Aborted events don't produce chunks, they just signal stream end
|
|
490
687
|
return null;
|
|
491
|
-
case
|
|
688
|
+
case store_1.AgentProcessEventType.Stop:
|
|
492
689
|
// Stop events don't produce chunks
|
|
493
690
|
return null;
|
|
494
691
|
default:
|
|
495
692
|
return null;
|
|
496
693
|
}
|
|
497
694
|
}
|
|
498
|
-
getMessageStream(chatId) {
|
|
695
|
+
getMessageStream(chatId, signal) {
|
|
499
696
|
const stream = new stream_1.PassThrough();
|
|
500
697
|
let ended = false;
|
|
501
698
|
const endStream = (error) => {
|
|
@@ -503,7 +700,7 @@ class ChatProcessor {
|
|
|
503
700
|
return;
|
|
504
701
|
ended = true;
|
|
505
702
|
if (error) {
|
|
506
|
-
|
|
703
|
+
logger_1.logger.error({ error }, 'Message stream error');
|
|
507
704
|
}
|
|
508
705
|
if (!stream.destroyed && !stream.writableEnded) {
|
|
509
706
|
try {
|
|
@@ -511,28 +708,29 @@ class ChatProcessor {
|
|
|
511
708
|
stream.end();
|
|
512
709
|
}
|
|
513
710
|
catch (e) {
|
|
514
|
-
|
|
711
|
+
logger_1.logger.error({ e }, 'Failed to end SSE stream');
|
|
515
712
|
}
|
|
516
713
|
}
|
|
517
714
|
};
|
|
518
715
|
const pushChunk = (chunk) => {
|
|
519
|
-
if (ended || stream.destroyed || stream.writableEnded)
|
|
716
|
+
if (ended || stream.destroyed || stream.writableEnded || signal?.aborted)
|
|
520
717
|
return;
|
|
521
718
|
stream.write(`data: ${JSON.stringify(chunk)}\n\n`);
|
|
522
719
|
};
|
|
523
720
|
const listener = (event) => {
|
|
524
|
-
if (
|
|
721
|
+
if (signal?.aborted) {
|
|
722
|
+
endStream();
|
|
525
723
|
return;
|
|
724
|
+
}
|
|
526
725
|
try {
|
|
527
726
|
const chunk = this.eventToChunk(event);
|
|
528
727
|
if (chunk) {
|
|
529
728
|
pushChunk(chunk);
|
|
530
729
|
}
|
|
531
|
-
if (event.type ===
|
|
532
|
-
event.type ===
|
|
533
|
-
event.type ===
|
|
730
|
+
if (event.type === store_1.AgentProcessEventType.Finished ||
|
|
731
|
+
event.type === store_1.AgentProcessEventType.Error ||
|
|
732
|
+
event.type === store_1.AgentProcessEventType.Aborted) {
|
|
534
733
|
endStream();
|
|
535
|
-
index_js_4.agentStore.removeListener(chatId, listener);
|
|
536
734
|
}
|
|
537
735
|
}
|
|
538
736
|
catch (err) {
|
|
@@ -541,21 +739,18 @@ class ChatProcessor {
|
|
|
541
739
|
error: err instanceof Error ? err.message : 'Unknown error occurred',
|
|
542
740
|
});
|
|
543
741
|
endStream(err);
|
|
544
|
-
index_js_4.agentStore.removeListener(chatId, listener);
|
|
545
742
|
}
|
|
546
743
|
};
|
|
547
|
-
// Cleanup on consumer side closing
|
|
548
744
|
const closeHandler = () => {
|
|
549
|
-
|
|
745
|
+
this.agentStore.removeListener(chatId, listener);
|
|
550
746
|
};
|
|
551
747
|
const errorHandler = (err) => {
|
|
552
|
-
|
|
553
|
-
index_js_4.agentStore.removeListener(chatId, listener);
|
|
748
|
+
signal?.removeEventListener('abort', endStream);
|
|
554
749
|
endStream(err);
|
|
555
750
|
};
|
|
556
751
|
stream.on('close', closeHandler);
|
|
557
752
|
stream.on('error', errorHandler);
|
|
558
|
-
const listenerAttached =
|
|
753
|
+
const listenerAttached = this.agentStore.addListener(chatId, listener);
|
|
559
754
|
if (!listenerAttached) {
|
|
560
755
|
// Remove stream listeners if listener attachment failed to prevent memory leak
|
|
561
756
|
stream.removeListener('close', closeHandler);
|
|
@@ -564,51 +759,28 @@ class ChatProcessor {
|
|
|
564
759
|
}
|
|
565
760
|
return stream;
|
|
566
761
|
}
|
|
567
|
-
async createMessageStream(payload, excludeSocketId) {
|
|
762
|
+
async createMessageStream(payload, excludeSocketId, signal) {
|
|
568
763
|
const stream = new stream_1.PassThrough();
|
|
569
|
-
(
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
// Send chat metadata first
|
|
573
|
-
if (!('chatId' in payload) && !('messageId' in payload) && chat) {
|
|
574
|
-
stream.write(`data: ${JSON.stringify({
|
|
575
|
-
type: ai_agent_types_1.StreamChunkType.Chat,
|
|
576
|
-
chatId: chat.id,
|
|
577
|
-
chat,
|
|
578
|
-
})}\n\n`);
|
|
579
|
-
}
|
|
580
|
-
await this.streamMessage(chat, payload, excludeSocketId, async () => {
|
|
581
|
-
if (stream.destroyed || stream.writableEnded) {
|
|
582
|
-
return;
|
|
583
|
-
}
|
|
584
|
-
const messageStream = this.getMessageStream(chat.id);
|
|
585
|
-
// If client disconnects, destroy inner stream
|
|
586
|
-
stream.on('close', () => {
|
|
587
|
-
if (!messageStream.destroyed) {
|
|
588
|
-
messageStream.destroy();
|
|
589
|
-
}
|
|
590
|
-
});
|
|
591
|
-
await pipelineAsync(messageStream, stream);
|
|
592
|
-
});
|
|
593
|
-
}
|
|
594
|
-
catch (error) {
|
|
595
|
-
index_js_6.logger.error({ error }, 'createMessageStream failed');
|
|
596
|
-
if (!stream.destroyed && !stream.writableEnded) {
|
|
597
|
-
stream.write(`data: ${JSON.stringify({
|
|
598
|
-
type: ai_agent_types_1.StreamChunkType.Error,
|
|
599
|
-
error: error instanceof Error ? error.message : 'Unknown error occurred',
|
|
600
|
-
})}\n\n`);
|
|
601
|
-
stream.write('data: [DONE]\n\n');
|
|
602
|
-
stream.end();
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
})().catch((err) => {
|
|
606
|
-
index_js_6.logger.error({ err }, 'Unhandled stream task error');
|
|
607
|
-
if (!stream.destroyed)
|
|
608
|
-
stream.destroy(err);
|
|
764
|
+
this.runMessageStream(stream, payload, excludeSocketId, signal)
|
|
765
|
+
.catch(err => {
|
|
766
|
+
logger_1.logger.error({ err }, 'Stream task failed');
|
|
609
767
|
});
|
|
610
768
|
return stream;
|
|
611
769
|
}
|
|
770
|
+
async runMessageStream(stream, payload, excludeSocketId, signal) {
|
|
771
|
+
const chat = await this.upsertAndGetChat(payload, excludeSocketId);
|
|
772
|
+
if (!('chatId' in payload) && !('messageId' in payload) && chat) {
|
|
773
|
+
stream.write(`data: ${JSON.stringify({
|
|
774
|
+
type: ai_agent_types_1.StreamChunkType.Chat,
|
|
775
|
+
chatId: chat.id,
|
|
776
|
+
chat,
|
|
777
|
+
})}\n\n`);
|
|
778
|
+
}
|
|
779
|
+
await this.streamMessage(chat, payload, excludeSocketId, () => {
|
|
780
|
+
const messageStream = this.getMessageStream(chat.id, signal);
|
|
781
|
+
messageStream.pipe(stream);
|
|
782
|
+
});
|
|
783
|
+
}
|
|
612
784
|
}
|
|
613
785
|
exports.ChatProcessor = ChatProcessor;
|
|
614
786
|
//# sourceMappingURL=ChatProcessor.js.map
|