@multiplayer-app/ai-agent-node 0.1.0-beta.5 → 0.1.0-beta.50
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 +2 -2
- package/dist/cjs/config.cjs +88 -37
- 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 +127 -65
- package/dist/cjs/helpers/AIHelper.cjs.map +1 -1
- package/dist/cjs/helpers/AIHelper.d.ts +22 -16
- 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 +15 -6
- package/dist/cjs/helpers/ConfigHelper.cjs.map +1 -1
- package/dist/cjs/helpers/ConfigHelper.d.ts.map +1 -1
- package/dist/cjs/helpers/FileHelper.cjs +131 -151
- 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 +0 -1
- package/dist/cjs/helpers/index.cjs.map +1 -1
- package/dist/cjs/helpers/index.d.ts +0 -1
- package/dist/cjs/helpers/index.d.ts.map +1 -1
- package/dist/cjs/index.cjs +120 -28
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.ts +43 -11
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/libs/index.cjs +0 -1
- package/dist/cjs/libs/index.cjs.map +1 -1
- package/dist/cjs/libs/index.d.ts +0 -1
- package/dist/cjs/libs/index.d.ts.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 +173 -186
- 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 +39 -0
- package/dist/cjs/processors/ActivityProcessor.cjs.map +1 -0
- package/dist/cjs/processors/ActivityProcessor.d.ts +32 -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/AgentProcessor.cjs +46 -0
- package/dist/cjs/processors/AgentProcessor.cjs.map +1 -0
- package/dist/cjs/processors/AgentProcessor.d.ts +25 -0
- package/dist/cjs/processors/AgentProcessor.d.ts.map +1 -0
- package/dist/cjs/processors/AgentProcessor.test.cjs +103 -0
- package/dist/cjs/processors/AgentProcessor.test.cjs.map +1 -0
- package/dist/cjs/processors/AgentProcessor.test.d.ts +2 -0
- package/dist/cjs/processors/AgentProcessor.test.d.ts.map +1 -0
- package/dist/cjs/processors/ChatProcessor.cjs +355 -122
- package/dist/cjs/processors/ChatProcessor.cjs.map +1 -1
- package/dist/cjs/processors/ChatProcessor.d.ts +71 -11
- package/dist/cjs/processors/ChatProcessor.d.ts.map +1 -1
- package/dist/cjs/processors/ChatProcessor.test.cjs +762 -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/index.cjs +2 -0
- package/dist/cjs/processors/index.cjs.map +1 -1
- package/dist/cjs/processors/index.d.ts +2 -0
- package/dist/cjs/processors/index.d.ts.map +1 -1
- package/dist/cjs/services/AIService.cjs +87 -21
- package/dist/cjs/services/AIService.cjs.map +1 -1
- package/dist/cjs/services/AIService.d.ts +19 -7
- package/dist/cjs/services/AIService.d.ts.map +1 -1
- package/dist/cjs/services/InternalEventsHandler.cjs +3 -3
- 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 +2 -8
- 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 +20 -16
- 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 +8 -8
- 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 +0 -1
- package/dist/cjs/services/index.cjs.map +1 -1
- package/dist/cjs/services/index.d.ts +0 -1
- package/dist/cjs/services/index.d.ts.map +1 -1
- package/dist/cjs/store/AgentStore.cjs +3 -4
- 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/ConfigStore.cjs +7 -3
- package/dist/cjs/store/ConfigStore.cjs.map +1 -1
- package/dist/cjs/store/ConfigStore.d.ts +1 -0
- package/dist/cjs/store/ConfigStore.d.ts.map +1 -1
- package/dist/cjs/tools/generateChartTool.d.ts +2 -2
- package/dist/cjs/tools/proposeFormValuesTool.d.ts +2 -2
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/config.d.ts +57 -23
- package/dist/esm/config.d.ts.map +1 -1
- package/dist/esm/config.js +88 -35
- package/dist/esm/config.js.map +1 -1
- package/dist/esm/helpers/AIHelper.d.ts +22 -16
- package/dist/esm/helpers/AIHelper.d.ts.map +1 -1
- package/dist/esm/helpers/AIHelper.js +134 -70
- package/dist/esm/helpers/AIHelper.js.map +1 -1
- package/dist/esm/helpers/AIHelper.test.js +22 -15
- 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 +15 -6
- package/dist/esm/helpers/ConfigHelper.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 +131 -146
- package/dist/esm/helpers/FileHelper.js.map +1 -1
- package/dist/esm/helpers/index.d.ts +0 -1
- package/dist/esm/helpers/index.d.ts.map +1 -1
- package/dist/esm/helpers/index.js +0 -1
- package/dist/esm/helpers/index.js.map +1 -1
- package/dist/esm/index.d.ts +43 -11
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +92 -11
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/libs/index.d.ts +0 -1
- package/dist/esm/libs/index.d.ts.map +1 -1
- package/dist/esm/libs/index.js +0 -1
- package/dist/esm/libs/index.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 +177 -172
- package/dist/esm/libs/s3/s3.lib.js.map +1 -1
- package/dist/esm/processors/ActivityProcessor.d.ts +32 -0
- package/dist/esm/processors/ActivityProcessor.d.ts.map +1 -0
- package/dist/esm/processors/ActivityProcessor.js +36 -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/AgentProcessor.d.ts +25 -0
- package/dist/esm/processors/AgentProcessor.d.ts.map +1 -0
- package/dist/esm/processors/AgentProcessor.js +43 -0
- package/dist/esm/processors/AgentProcessor.js.map +1 -0
- package/dist/esm/processors/AgentProcessor.test.d.ts +2 -0
- package/dist/esm/processors/AgentProcessor.test.d.ts.map +1 -0
- package/dist/esm/processors/AgentProcessor.test.js +101 -0
- package/dist/esm/processors/AgentProcessor.test.js.map +1 -0
- package/dist/esm/processors/ChatProcessor.d.ts +71 -11
- package/dist/esm/processors/ChatProcessor.d.ts.map +1 -1
- package/dist/esm/processors/ChatProcessor.js +366 -126
- 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 +760 -0
- package/dist/esm/processors/ChatProcessor.test.js.map +1 -0
- package/dist/esm/processors/index.d.ts +2 -0
- package/dist/esm/processors/index.d.ts.map +1 -1
- package/dist/esm/processors/index.js +2 -0
- package/dist/esm/processors/index.js.map +1 -1
- package/dist/esm/services/AIService.d.ts +19 -7
- package/dist/esm/services/AIService.d.ts.map +1 -1
- package/dist/esm/services/AIService.js +91 -24
- 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 +4 -3
- 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 +2 -8
- 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 +21 -14
- 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 +10 -6
- package/dist/esm/services/SocketService.js.map +1 -1
- package/dist/esm/services/index.d.ts +0 -1
- package/dist/esm/services/index.d.ts.map +1 -1
- package/dist/esm/services/index.js +0 -1
- 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 +4 -2
- package/dist/esm/store/AgentStore.js.map +1 -1
- package/dist/esm/store/ConfigStore.d.ts +1 -0
- package/dist/esm/store/ConfigStore.d.ts.map +1 -1
- package/dist/esm/store/ConfigStore.js +7 -3
- package/dist/esm/store/ConfigStore.js.map +1 -1
- package/dist/esm/tools/generateChartTool.d.ts +2 -2
- package/dist/esm/tools/proposeFormValuesTool.d.ts +2 -2
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +12 -12
- 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 -131
- 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 -8
- 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 -122
- 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 -125
- 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 -45
- 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 -5
- 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 -123
- package/dist/esm/services/KafkaService.js.map +0 -1
|
@@ -2,25 +2,110 @@
|
|
|
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 services_2 = require("../services/index.cjs");
|
|
5
|
+
const zod_1 = require("zod");
|
|
7
6
|
const helpers_1 = require("../helpers/index.cjs");
|
|
8
7
|
const store_1 = require("../store/index.cjs");
|
|
9
8
|
const helpers_2 = require("../helpers/index.cjs");
|
|
10
|
-
const config_1 = require("../config.cjs");
|
|
11
9
|
const stream_1 = require("stream");
|
|
12
|
-
const util_1 = require("util");
|
|
13
10
|
const logger_1 = require("../libs/logger/index.cjs");
|
|
14
|
-
const
|
|
11
|
+
const store_2 = require("../store/index.cjs");
|
|
15
12
|
class ChatProcessor {
|
|
16
|
-
constructor(
|
|
17
|
-
this.chatRepository = chatRepository;
|
|
18
|
-
this.messageRepository = messageRepository;
|
|
19
|
-
this.artifactStore = artifactStore;
|
|
13
|
+
constructor(params) {
|
|
14
|
+
this.chatRepository = params.chatRepository;
|
|
15
|
+
this.messageRepository = params.messageRepository;
|
|
16
|
+
this.artifactStore = params.artifactStore;
|
|
17
|
+
this.config = params.config;
|
|
18
|
+
this.socketService = params.socketService;
|
|
19
|
+
this.agentStore = params.agentStore;
|
|
20
|
+
this.activityRepository = params.activityRepository;
|
|
21
|
+
this.agentConfigRepository = params.agentConfigRepository;
|
|
22
|
+
const fileHelper = new helpers_1.FileHelper(params.s3Lib, this.config);
|
|
23
|
+
this.aiHelper = new helpers_1.AIHelper(fileHelper, this.config);
|
|
24
|
+
this.debug = this.config.debug;
|
|
20
25
|
}
|
|
21
26
|
getTemporaryTitle(contextKey) {
|
|
22
27
|
return `${contextKey} session ${new Date().toISOString()}`;
|
|
23
28
|
}
|
|
29
|
+
isTemporaryTitle(title) {
|
|
30
|
+
// Matches pattern: "{contextKey} session {ISO_DATE_STRING}"
|
|
31
|
+
// Example: "default session 2026-01-23T10:30:45.123Z"
|
|
32
|
+
// toISOString() always includes milliseconds, so we require them
|
|
33
|
+
const pattern = /^.+ session \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/;
|
|
34
|
+
return pattern.test(title);
|
|
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
|
+
async validateToolCallInput(params) {
|
|
93
|
+
const agentOptions = await this.aiHelper.getAgentOptions({
|
|
94
|
+
agentName: params.agentName,
|
|
95
|
+
});
|
|
96
|
+
const tool = agentOptions.tools?.[params.toolName] ?? undefined;
|
|
97
|
+
const schema = tool?.inputSchema;
|
|
98
|
+
if (!schema) {
|
|
99
|
+
throw new Error(`Tool "${params.toolName}" schema not found`);
|
|
100
|
+
}
|
|
101
|
+
if (!(schema instanceof zod_1.z.ZodType)) {
|
|
102
|
+
throw new Error(`Tool "${params.toolName}" inputSchema must be a Zod schema`);
|
|
103
|
+
}
|
|
104
|
+
const result = schema.safeParse(params.input);
|
|
105
|
+
if (!result.success) {
|
|
106
|
+
throw new Error(`Invalid tool input for "${params.toolName}": ${result.error.message}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
24
109
|
async listChats(params) {
|
|
25
110
|
// Build filter object from params
|
|
26
111
|
const filter = {};
|
|
@@ -30,33 +115,56 @@ class ChatProcessor {
|
|
|
30
115
|
if (params?.contextKey) {
|
|
31
116
|
filter.contextKey = params.contextKey;
|
|
32
117
|
}
|
|
33
|
-
// Build query options for sort and limit with defaults
|
|
118
|
+
// Build query options for sort and limit with defaults.
|
|
34
119
|
const options = {
|
|
35
120
|
sort: {
|
|
36
121
|
field: params?.sortField ?? 'updatedAt',
|
|
37
122
|
order: params?.sortOrder ?? ai_agent_types_1.SortOrder.Desc
|
|
38
123
|
},
|
|
124
|
+
skip: params?.skip,
|
|
39
125
|
limit: params?.limit
|
|
40
126
|
};
|
|
41
|
-
|
|
42
|
-
|
|
127
|
+
const [total, data] = await Promise.all([
|
|
128
|
+
this.chatRepository.count(filter),
|
|
129
|
+
this.chatRepository.find(filter, options)
|
|
130
|
+
]);
|
|
131
|
+
return {
|
|
132
|
+
cursor: {
|
|
133
|
+
...(params?.skip != null ? { skip: params.skip } : {}),
|
|
134
|
+
...(params?.limit != null ? { limit: params.limit } : {}),
|
|
135
|
+
total
|
|
136
|
+
},
|
|
137
|
+
data
|
|
138
|
+
};
|
|
43
139
|
}
|
|
44
140
|
async getChat(chatId) {
|
|
45
141
|
const chat = await this.chatRepository.findById(chatId);
|
|
46
142
|
if (!chat) {
|
|
47
143
|
throw new Error('Chat not found');
|
|
48
144
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
145
|
+
return chat;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Get messages for a chat with optional cursor pagination.
|
|
149
|
+
* When limit is omitted, returns all messages (backward compatible).
|
|
150
|
+
* Messages are returned in chronological order (oldest → newest).
|
|
151
|
+
*/
|
|
152
|
+
async getMessages(chatId, options) {
|
|
153
|
+
const chat = await this.chatRepository.findById(chatId);
|
|
154
|
+
if (!chat) {
|
|
155
|
+
throw new Error('Chat not found');
|
|
156
|
+
}
|
|
157
|
+
return this.messageRepository.findByChatIdPaginated(chatId, options);
|
|
54
158
|
}
|
|
55
159
|
async deleteChat(chatId) {
|
|
56
160
|
const deleted = await this.chatRepository.delete(chatId);
|
|
57
161
|
if (!deleted) {
|
|
58
162
|
throw new Error('Chat not found');
|
|
59
163
|
}
|
|
164
|
+
await Promise.all([
|
|
165
|
+
this.messageRepository.deleteByChatId(chatId),
|
|
166
|
+
this.activityRepository.deleteByGroupId(chatId), // todo: discuss if this is needed
|
|
167
|
+
]);
|
|
60
168
|
this.artifactStore.deleteArtifacts(chatId);
|
|
61
169
|
}
|
|
62
170
|
async upsertAndGetChat(payload, excludeSocketId) {
|
|
@@ -92,7 +200,7 @@ class ChatProcessor {
|
|
|
92
200
|
if (!content) {
|
|
93
201
|
return this.getTemporaryTitle(payload.contextKey);
|
|
94
202
|
}
|
|
95
|
-
return
|
|
203
|
+
return this.aiHelper.generateTitleForMessage(payload.contextKey, [{
|
|
96
204
|
role: ai_agent_types_1.MessageRole.User,
|
|
97
205
|
content: content
|
|
98
206
|
}]);
|
|
@@ -108,7 +216,7 @@ class ChatProcessor {
|
|
|
108
216
|
toolCalls: []
|
|
109
217
|
});
|
|
110
218
|
if (chat.userId) {
|
|
111
|
-
|
|
219
|
+
this.socketService.emitMessageUpdate(chat.userId, message, excludeSocketId);
|
|
112
220
|
}
|
|
113
221
|
return message;
|
|
114
222
|
}
|
|
@@ -125,12 +233,7 @@ class ChatProcessor {
|
|
|
125
233
|
metadata,
|
|
126
234
|
...(payload.model ? { model: payload.model } : {})
|
|
127
235
|
});
|
|
128
|
-
|
|
129
|
-
const initialChatResponse = {
|
|
130
|
-
...chat,
|
|
131
|
-
messages: []
|
|
132
|
-
};
|
|
133
|
-
services_1.socketService.emitChatUpdate(targetUserId, initialChatResponse, excludeSocketId);
|
|
236
|
+
this.socketService.emitChatUpdate(targetUserId, chat, excludeSocketId);
|
|
134
237
|
return chat;
|
|
135
238
|
}
|
|
136
239
|
/**
|
|
@@ -185,33 +288,75 @@ class ChatProcessor {
|
|
|
185
288
|
await this.messageRepository.update(message.id, { toolCalls });
|
|
186
289
|
// Bump chat updatedAt so listChats ordering reflects the action.
|
|
187
290
|
await this.chatRepository.update(chat.id, { updatedAt: now });
|
|
188
|
-
|
|
291
|
+
this.socketService.emitMessageUpdate(chat.userId, updatedMessage, params.excludeSocketId);
|
|
189
292
|
if (params.systemMessage) {
|
|
190
293
|
//todo discuss support for system messages
|
|
191
294
|
//await this.createMessage(chat, MessageRole.System, params.systemMessage, undefined, params.excludeSocketId);
|
|
192
295
|
}
|
|
193
296
|
return { ok: true };
|
|
194
297
|
}
|
|
298
|
+
/**
|
|
299
|
+
* Update selected fields (input/output/status) on a specific tool call.
|
|
300
|
+
*/
|
|
301
|
+
async updateToolCall(params) {
|
|
302
|
+
if (params.input === undefined && params.output === undefined && params.status === undefined) {
|
|
303
|
+
throw new Error('At least one of input, output, or status must be provided');
|
|
304
|
+
}
|
|
305
|
+
const chat = await this.chatRepository.findById(params.chatId);
|
|
306
|
+
if (!chat) {
|
|
307
|
+
throw new Error('Chat not found');
|
|
308
|
+
}
|
|
309
|
+
if (params.userId && chat.userId !== params.userId) {
|
|
310
|
+
throw new Error('Chat does not belong to this user');
|
|
311
|
+
}
|
|
312
|
+
const message = await this.messageRepository.findById(params.messageId);
|
|
313
|
+
if (!message || message.chat !== params.chatId) {
|
|
314
|
+
throw new Error('Message not found or does not belong to this chat');
|
|
315
|
+
}
|
|
316
|
+
const targetToolCall = (message.toolCalls ?? []).find((tc) => tc.id === params.toolCallId);
|
|
317
|
+
if (!targetToolCall) {
|
|
318
|
+
throw new Error('Tool call not found in message');
|
|
319
|
+
}
|
|
320
|
+
if (params.input !== undefined) {
|
|
321
|
+
await this.validateToolCallInput({
|
|
322
|
+
agentName: message.agentName,
|
|
323
|
+
toolName: targetToolCall.name,
|
|
324
|
+
input: params.input,
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
const updatedMessage = await this.messageRepository.updateToolCall(params.messageId, params.toolCallId, {
|
|
328
|
+
...(params.input !== undefined ? { input: params.input } : {}),
|
|
329
|
+
...(params.output !== undefined ? { output: params.output } : {}),
|
|
330
|
+
...(params.status !== undefined ? { status: params.status } : {}),
|
|
331
|
+
});
|
|
332
|
+
if (!updatedMessage) {
|
|
333
|
+
throw new Error('Tool call not found in message');
|
|
334
|
+
}
|
|
335
|
+
const now = new Date().toISOString();
|
|
336
|
+
await this.chatRepository.update(chat.id, { updatedAt: now });
|
|
337
|
+
this.socketService.emitMessageUpdate(chat.userId, updatedMessage, params.excludeSocketId);
|
|
338
|
+
return updatedMessage;
|
|
339
|
+
}
|
|
195
340
|
async streamMessageStep(params) {
|
|
196
341
|
const { chat, assistantMessage, existingMessages, signal, excludeSocketId, agentOptions } = params;
|
|
197
342
|
if (signal.aborted) {
|
|
198
343
|
return;
|
|
199
344
|
}
|
|
200
|
-
const result = await
|
|
345
|
+
const result = await this.aiHelper.streamAssistantResponse(existingMessages, signal, agentOptions);
|
|
201
346
|
try {
|
|
202
347
|
for await (const chunk of result.fullStream) {
|
|
203
348
|
if (chunk.type === 'error') {
|
|
204
|
-
await
|
|
349
|
+
await this.agentStore.shareAgentProcessEvent(chat.id, { type: store_1.AgentProcessEventType.Error, data: chunk.error });
|
|
205
350
|
assistantMessage.content = chunk.error.message || 'Sorry, I cannot process you request due to the error';
|
|
206
351
|
await this.messageRepository.update(assistantMessage.id, assistantMessage);
|
|
207
352
|
await this.chatRepository.update(chat.id, { status: ai_agent_types_1.AgentStatus.Error });
|
|
208
353
|
continue;
|
|
209
354
|
}
|
|
210
355
|
if (chunk.type === 'abort') {
|
|
211
|
-
await
|
|
356
|
+
await this.agentStore.shareAgentProcessEvent(chat.id, { type: store_1.AgentProcessEventType.Aborted, data: undefined });
|
|
212
357
|
await this.chatRepository.update(chat.id, { status: ai_agent_types_1.AgentStatus.Aborted });
|
|
213
358
|
await this.messageRepository.update(assistantMessage.id, assistantMessage);
|
|
214
|
-
|
|
359
|
+
this.socketService.emitMessageUpdate(chat.userId, assistantMessage, excludeSocketId);
|
|
215
360
|
continue;
|
|
216
361
|
}
|
|
217
362
|
if (chunk.type === 'finish') {
|
|
@@ -229,37 +374,39 @@ class ChatProcessor {
|
|
|
229
374
|
}
|
|
230
375
|
await this.messageRepository.update(assistantMessage.id, { ...assistantMessage });
|
|
231
376
|
if (chunk.finishReason === 'stop') {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
377
|
+
await this.chatRepository.update(chat.id, { status: ai_agent_types_1.AgentStatus.Finished });
|
|
378
|
+
if (chat.title && this.isTemporaryTitle(chat.title)) {
|
|
379
|
+
const title = await this.aiHelper.generateTitleForMessage(chat.contextKey, existingMessages.filter(m => m.role === ai_agent_types_1.MessageRole.User), (stepResult) => {
|
|
380
|
+
return this.storeStepActivity({
|
|
381
|
+
chat,
|
|
382
|
+
stepResult,
|
|
383
|
+
name: ai_agent_types_1.ActivityOperationName.TITLE_GENERATION,
|
|
384
|
+
sourceId: chat.id,
|
|
385
|
+
sourceType: 'Chat',
|
|
386
|
+
tenants: params.tenants || {},
|
|
387
|
+
});
|
|
388
|
+
});
|
|
389
|
+
await this.chatRepository.update(chat.id, { title });
|
|
390
|
+
this.socketService.emitChatUpdate(chat.userId, { ...chat, title });
|
|
243
391
|
}
|
|
244
|
-
await store_1.agentStore.shareAgentProcessEvent(chat.id, { type: store_1.AgentProcessEventType.Finished, data: assistantMessage });
|
|
245
|
-
continue;
|
|
246
392
|
}
|
|
247
393
|
if (chunk.finishReason === 'tool-calls') {
|
|
248
394
|
if (assistantMessage.toolCalls?.some(toolCall => toolCall.requiresConfirmation && toolCall.approvalId && !toolCall.output)) {
|
|
249
395
|
await this.chatRepository.update(chat.id, { status: ai_agent_types_1.AgentStatus.WaitingForUserAction });
|
|
250
|
-
await
|
|
251
|
-
|
|
252
|
-
else {
|
|
253
|
-
await store_1.agentStore.shareAgentProcessEvent(chat.id, {
|
|
254
|
-
type: store_1.AgentProcessEventType.Update,
|
|
255
|
-
data: assistantMessage
|
|
256
|
-
});
|
|
257
|
-
await this.streamMessageStep(params);
|
|
396
|
+
await this.agentStore.shareAgentProcessEvent(chat.id, { type: store_1.AgentProcessEventType.Finished, data: assistantMessage });
|
|
397
|
+
continue;
|
|
258
398
|
}
|
|
259
|
-
continue;
|
|
260
399
|
}
|
|
261
400
|
//todo: Handle other finish reasons // length, content, error, other, undefined
|
|
262
|
-
await
|
|
401
|
+
await this.agentStore.shareAgentProcessEvent(chat.id, { type: store_1.AgentProcessEventType.Finished, data: assistantMessage });
|
|
402
|
+
if (assistantMessage.activity) {
|
|
403
|
+
const groupedMeta = await this.activityRepository.getGroupedMetadataByParentId(assistantMessage.activity);
|
|
404
|
+
await this.activityRepository.updateMetadata(assistantMessage.activity, {
|
|
405
|
+
usage: groupedMeta,
|
|
406
|
+
finishReason: chunk.finishReason,
|
|
407
|
+
responseTimestamp: new Date().toISOString(),
|
|
408
|
+
});
|
|
409
|
+
}
|
|
263
410
|
continue;
|
|
264
411
|
}
|
|
265
412
|
if (chunk.type === 'text-delta') {
|
|
@@ -268,8 +415,8 @@ class ChatProcessor {
|
|
|
268
415
|
...assistantMessage,
|
|
269
416
|
content: assistantMessage.content
|
|
270
417
|
};
|
|
271
|
-
|
|
272
|
-
await
|
|
418
|
+
this.socketService.emitMessageUpdate(chat.userId, updatedMessage, excludeSocketId);
|
|
419
|
+
await this.agentStore.shareAgentProcessEvent(chat.id, { type: store_1.AgentProcessEventType.Update, data: updatedMessage });
|
|
273
420
|
await this.messageRepository.update(assistantMessage.id, { content: assistantMessage.content });
|
|
274
421
|
continue;
|
|
275
422
|
}
|
|
@@ -284,7 +431,7 @@ class ChatProcessor {
|
|
|
284
431
|
});
|
|
285
432
|
continue;
|
|
286
433
|
}
|
|
287
|
-
if (chunk.type === 'tool-call') {
|
|
434
|
+
if (chunk.type === 'tool-call') {
|
|
288
435
|
const toolCall = assistantMessage.toolCalls?.find(toolCall => toolCall.id === chunk.toolCallId);
|
|
289
436
|
if (toolCall) {
|
|
290
437
|
toolCall.status = ai_agent_types_1.AgentToolCallStatus.Running;
|
|
@@ -296,7 +443,7 @@ class ChatProcessor {
|
|
|
296
443
|
const toolCall = assistantMessage.toolCalls?.find(toolCall => toolCall.id === chunk.toolCallId);
|
|
297
444
|
if (toolCall) {
|
|
298
445
|
toolCall.status = ai_agent_types_1.AgentToolCallStatus.Failed;
|
|
299
|
-
toolCall.error = JSON.stringify(chunk.error);
|
|
446
|
+
toolCall.error = chunk.error.message || JSON.stringify(chunk.error);
|
|
300
447
|
}
|
|
301
448
|
continue;
|
|
302
449
|
}
|
|
@@ -305,13 +452,16 @@ class ChatProcessor {
|
|
|
305
452
|
if (toolCall) {
|
|
306
453
|
toolCall.requiresConfirmation = true;
|
|
307
454
|
toolCall.approvalId = chunk.approvalId;
|
|
455
|
+
if (toolCall.name === ai_agent_types_1.AgentToolType.REQUEST_CLARIFICATION) {
|
|
456
|
+
toolCall.requiresUserAction = true;
|
|
457
|
+
}
|
|
308
458
|
}
|
|
309
459
|
continue;
|
|
310
460
|
}
|
|
311
461
|
if (chunk.type === 'tool-result') {
|
|
312
462
|
const toolCall = assistantMessage.toolCalls?.find(toolCall => toolCall.id === chunk.toolCallId);
|
|
313
463
|
if (toolCall) {
|
|
314
|
-
if (chunk.output
|
|
464
|
+
if (chunk.output?.requiresApproval) {
|
|
315
465
|
toolCall.requiresConfirmation = true;
|
|
316
466
|
continue;
|
|
317
467
|
}
|
|
@@ -324,9 +474,9 @@ class ChatProcessor {
|
|
|
324
474
|
if (!assistantMessage.reasoning)
|
|
325
475
|
assistantMessage.reasoning = '';
|
|
326
476
|
assistantMessage.reasoning += chunk.text;
|
|
327
|
-
|
|
477
|
+
this.socketService.emitMessageUpdate(chat.userId, assistantMessage, excludeSocketId);
|
|
328
478
|
await this.messageRepository.update(assistantMessage.id, { reasoning: assistantMessage.reasoning });
|
|
329
|
-
await
|
|
479
|
+
await this.agentStore.shareAgentProcessEvent(chat.id, { type: store_1.AgentProcessEventType.Update, data: assistantMessage });
|
|
330
480
|
continue;
|
|
331
481
|
}
|
|
332
482
|
}
|
|
@@ -335,7 +485,7 @@ class ChatProcessor {
|
|
|
335
485
|
if (streamError instanceof Error && streamError.name === 'AbortError') {
|
|
336
486
|
return;
|
|
337
487
|
}
|
|
338
|
-
await
|
|
488
|
+
await this.agentStore.shareAgentProcessEvent(chat.id, { type: store_1.AgentProcessEventType.Error, data: streamError });
|
|
339
489
|
throw streamError;
|
|
340
490
|
}
|
|
341
491
|
}
|
|
@@ -347,7 +497,7 @@ class ChatProcessor {
|
|
|
347
497
|
if (!assistantMessage || assistantMessage.chat !== chat.id) {
|
|
348
498
|
throw new Error(`Assistant message with id ${payload.messageId} not found`);
|
|
349
499
|
}
|
|
350
|
-
const agentOptions = await
|
|
500
|
+
const agentOptions = await this.aiHelper.getAgentOptions({
|
|
351
501
|
agentName: assistantMessage.agentName,
|
|
352
502
|
context: payload.context
|
|
353
503
|
});
|
|
@@ -360,14 +510,20 @@ class ChatProcessor {
|
|
|
360
510
|
};
|
|
361
511
|
}
|
|
362
512
|
toolCall.approved = payload.approved;
|
|
363
|
-
toolCall.
|
|
513
|
+
toolCall.userResponse = payload.userResponse;
|
|
364
514
|
if (!toolCall.approved) {
|
|
365
515
|
toolCall.output = {
|
|
366
516
|
type: 'execution-denied',
|
|
367
|
-
reason: toolCall.
|
|
517
|
+
reason: toolCall.userResponse
|
|
368
518
|
};
|
|
369
519
|
toolCall.status = ai_agent_types_1.AgentToolCallStatus.Failed;
|
|
370
520
|
}
|
|
521
|
+
else if (toolCall.requiresUserAction) {
|
|
522
|
+
toolCall.output = {
|
|
523
|
+
userResponse: toolCall.userResponse
|
|
524
|
+
};
|
|
525
|
+
toolCall.status = ai_agent_types_1.AgentToolCallStatus.Succeeded;
|
|
526
|
+
}
|
|
371
527
|
else {
|
|
372
528
|
const executeFunction = agentOptions.tools?.[toolCall.name]?.execute;
|
|
373
529
|
if (executeFunction) {
|
|
@@ -400,32 +556,105 @@ class ChatProcessor {
|
|
|
400
556
|
}
|
|
401
557
|
async processNewUserMessage(chat, payload, prevMessages, excludeSocketId) {
|
|
402
558
|
const userMessage = await this.createMessage(chat, ai_agent_types_1.MessageRole.User, { content: payload.content, agentName: undefined }, payload.attachments);
|
|
403
|
-
await
|
|
404
|
-
|
|
559
|
+
await this.agentStore.shareAgentProcessEvent(chat.id, { type: store_1.AgentProcessEventType.Update, data: userMessage });
|
|
560
|
+
let assistantMessage = await this.createMessage(chat, ai_agent_types_1.MessageRole.Assistant, { content: '', agentName: undefined }, undefined, excludeSocketId);
|
|
561
|
+
const parentActivity = await this.activityRepository.create({
|
|
562
|
+
ownerId: chat.userId,
|
|
563
|
+
groupId: chat.id,
|
|
564
|
+
name: ai_agent_types_1.ActivityOperationName.MESSAGE_PROCESSING,
|
|
565
|
+
tenants: payload.tenants ?? {},
|
|
566
|
+
sourceId: userMessage.id,
|
|
567
|
+
sourceType: 'AgentMessage',
|
|
568
|
+
metadata: {
|
|
569
|
+
contextKey: chat.contextKey,
|
|
570
|
+
modelId: this.aiHelper.getLanguageModelId(chat.model),
|
|
571
|
+
},
|
|
572
|
+
});
|
|
573
|
+
const agentOptions = await this.aiHelper.getAgentOptions({
|
|
405
574
|
contextKey: chat.contextKey,
|
|
406
|
-
messages:
|
|
575
|
+
messages: [...prevMessages, userMessage],
|
|
407
576
|
context: payload.context,
|
|
408
577
|
agentName: undefined,
|
|
409
578
|
modelId: chat.model,
|
|
579
|
+
}, {
|
|
580
|
+
onStepFinish: async (stepResult) => {
|
|
581
|
+
await this.storeStepActivity({
|
|
582
|
+
chat,
|
|
583
|
+
parentId: parentActivity.id,
|
|
584
|
+
stepResult,
|
|
585
|
+
name: ai_agent_types_1.ActivityOperationName.AGENT_SELECTION,
|
|
586
|
+
sourceId: userMessage.id,
|
|
587
|
+
sourceType: 'AgentMessage',
|
|
588
|
+
tenants: payload.tenants || {},
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
});
|
|
592
|
+
const updatedAssistantMessage = await this.messageRepository.update(assistantMessage.id, {
|
|
593
|
+
agentName: agentOptions.name,
|
|
594
|
+
activity: parentActivity.id
|
|
410
595
|
});
|
|
411
|
-
|
|
412
|
-
|
|
596
|
+
await this.activityRepository.update(parentActivity.id, {
|
|
597
|
+
metadata: {
|
|
598
|
+
...parentActivity.metadata,
|
|
599
|
+
agentOptions: {
|
|
600
|
+
name: agentOptions.name,
|
|
601
|
+
modelId: this.aiHelper.getLanguageModelId(agentOptions.model),
|
|
602
|
+
temperature: agentOptions.temperature,
|
|
603
|
+
maxOutputTokens: agentOptions.maxOutputTokens,
|
|
604
|
+
topP: agentOptions.topP,
|
|
605
|
+
topK: agentOptions.topK,
|
|
606
|
+
presencePenalty: agentOptions.presencePenalty,
|
|
607
|
+
frequencyPenalty: agentOptions.frequencyPenalty,
|
|
608
|
+
stopSequences: agentOptions.stopSequences,
|
|
609
|
+
seed: agentOptions.seed,
|
|
610
|
+
},
|
|
611
|
+
},
|
|
612
|
+
});
|
|
613
|
+
if (!updatedAssistantMessage) {
|
|
614
|
+
throw new Error(`Assistant message with id ${assistantMessage.id} not found after update`);
|
|
615
|
+
}
|
|
616
|
+
assistantMessage = updatedAssistantMessage;
|
|
413
617
|
return {
|
|
414
618
|
userMessage,
|
|
415
619
|
assistantMessage,
|
|
416
620
|
agentOptions,
|
|
417
621
|
};
|
|
418
622
|
}
|
|
623
|
+
async storeStepActivity(params) {
|
|
624
|
+
try {
|
|
625
|
+
const stepResult = params.stepResult;
|
|
626
|
+
const mergedUsage = this.mergeUsageWithProviderMetadata(stepResult.usage, stepResult.providerMetadata);
|
|
627
|
+
const activity = await this.activityRepository.create({
|
|
628
|
+
ownerId: params.chat.userId,
|
|
629
|
+
groupId: params.chat.id,
|
|
630
|
+
name: params.name,
|
|
631
|
+
tenants: params.tenants || {},
|
|
632
|
+
sourceId: params.sourceId,
|
|
633
|
+
sourceType: params.sourceType,
|
|
634
|
+
metadata: {
|
|
635
|
+
finishReason: stepResult.finishReason,
|
|
636
|
+
usage: mergedUsage,
|
|
637
|
+
responseTimestamp: stepResult.response.timestamp,
|
|
638
|
+
modelId: stepResult.response.modelId,
|
|
639
|
+
messages: this.debug ? stepResult.request?.body?.messages : undefined,
|
|
640
|
+
},
|
|
641
|
+
parentId: params.parentId,
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
catch (error) {
|
|
645
|
+
logger_1.logger.error({ error, chatId: params.chat.id, parentId: params.parentId }, 'Failed to store step activity');
|
|
646
|
+
}
|
|
647
|
+
}
|
|
419
648
|
async streamMessage(chat, payload, excludeSocketId, onAgentStart) {
|
|
420
649
|
try {
|
|
421
|
-
const abortController =
|
|
650
|
+
const abortController = this.agentStore.registerAgentProcess(chat.id);
|
|
422
651
|
onAgentStart?.();
|
|
423
652
|
let assistantMessage;
|
|
424
653
|
let agentOptions;
|
|
425
654
|
const existingMessages = await this.messageRepository.findByChatId(chat.id);
|
|
426
655
|
// Limit context to prevent exceeding token limits
|
|
427
656
|
const limitedMessages = helpers_2.ContextLimiter.limitContext(existingMessages, {
|
|
428
|
-
maxMessages:
|
|
657
|
+
maxMessages: this.config.ai.maxContextMessages,
|
|
429
658
|
keepFirstUserMessage: true,
|
|
430
659
|
keepSystemMessages: true,
|
|
431
660
|
});
|
|
@@ -447,6 +676,19 @@ class ChatProcessor {
|
|
|
447
676
|
agentOptions = result.agentOptions;
|
|
448
677
|
limitedMessages.push(result.userMessage);
|
|
449
678
|
}
|
|
679
|
+
agentOptions.onStepFinish = (stepResult) => {
|
|
680
|
+
return this.storeStepActivity({
|
|
681
|
+
chat,
|
|
682
|
+
parentId: assistantMessage.activity,
|
|
683
|
+
stepResult,
|
|
684
|
+
name: ai_agent_types_1.ActivityOperationName.STEP_FINISHED,
|
|
685
|
+
sourceId: assistantMessage.id,
|
|
686
|
+
sourceType: 'AgentMessage',
|
|
687
|
+
tenants: payload.tenants || {},
|
|
688
|
+
});
|
|
689
|
+
};
|
|
690
|
+
const userPreferences = await this.agentConfigRepository.findByUserIdAndAgentName(chat.userId, agentOptions.name);
|
|
691
|
+
agentOptions.activeTools = this.getAvailableTools(agentOptions, userPreferences);
|
|
450
692
|
await this.streamMessageStep({
|
|
451
693
|
chat,
|
|
452
694
|
existingMessages: limitedMessages,
|
|
@@ -454,12 +696,28 @@ class ChatProcessor {
|
|
|
454
696
|
agentOptions,
|
|
455
697
|
excludeSocketId: excludeSocketId,
|
|
456
698
|
signal: abortController.signal,
|
|
699
|
+
tenants: payload.tenants || {},
|
|
457
700
|
});
|
|
458
701
|
}
|
|
459
702
|
catch (error) {
|
|
460
703
|
throw error;
|
|
461
704
|
}
|
|
462
705
|
}
|
|
706
|
+
getAvailableTools(agentOptions, userPreferences) {
|
|
707
|
+
const toolNames = Object.keys(agentOptions.tools || {});
|
|
708
|
+
const availableToolsMap = Object.fromEntries(toolNames.map(key => [key, true]));
|
|
709
|
+
const agentsConfiguration = store_2.ConfigStore.getInstance().getAgentConfigByName(agentOptions.name);
|
|
710
|
+
agentsConfiguration.tools.forEach((tool) => {
|
|
711
|
+
const toolTitle = tool.data?.title || tool.type;
|
|
712
|
+
if (tool.disabledByDefault) {
|
|
713
|
+
availableToolsMap[toolTitle] = false;
|
|
714
|
+
}
|
|
715
|
+
if (tool.userConfigurable && userPreferences?.tools?.[toolTitle] !== undefined) {
|
|
716
|
+
availableToolsMap[toolTitle] = userPreferences.tools[toolTitle];
|
|
717
|
+
}
|
|
718
|
+
});
|
|
719
|
+
return Object.keys(availableToolsMap).filter(key => availableToolsMap[key]);
|
|
720
|
+
}
|
|
463
721
|
listArtifacts(chatId) {
|
|
464
722
|
return this.artifactStore.listArtifacts(chatId);
|
|
465
723
|
}
|
|
@@ -490,7 +748,7 @@ class ChatProcessor {
|
|
|
490
748
|
return null;
|
|
491
749
|
}
|
|
492
750
|
}
|
|
493
|
-
getMessageStream(chatId) {
|
|
751
|
+
getMessageStream(chatId, signal) {
|
|
494
752
|
const stream = new stream_1.PassThrough();
|
|
495
753
|
let ended = false;
|
|
496
754
|
const endStream = (error) => {
|
|
@@ -511,13 +769,15 @@ class ChatProcessor {
|
|
|
511
769
|
}
|
|
512
770
|
};
|
|
513
771
|
const pushChunk = (chunk) => {
|
|
514
|
-
if (ended || stream.destroyed || stream.writableEnded)
|
|
772
|
+
if (ended || stream.destroyed || stream.writableEnded || signal?.aborted)
|
|
515
773
|
return;
|
|
516
774
|
stream.write(`data: ${JSON.stringify(chunk)}\n\n`);
|
|
517
775
|
};
|
|
518
776
|
const listener = (event) => {
|
|
519
|
-
if (
|
|
777
|
+
if (signal?.aborted) {
|
|
778
|
+
endStream();
|
|
520
779
|
return;
|
|
780
|
+
}
|
|
521
781
|
try {
|
|
522
782
|
const chunk = this.eventToChunk(event);
|
|
523
783
|
if (chunk) {
|
|
@@ -527,7 +787,6 @@ class ChatProcessor {
|
|
|
527
787
|
event.type === store_1.AgentProcessEventType.Error ||
|
|
528
788
|
event.type === store_1.AgentProcessEventType.Aborted) {
|
|
529
789
|
endStream();
|
|
530
|
-
store_1.agentStore.removeListener(chatId, listener);
|
|
531
790
|
}
|
|
532
791
|
}
|
|
533
792
|
catch (err) {
|
|
@@ -536,21 +795,18 @@ class ChatProcessor {
|
|
|
536
795
|
error: err instanceof Error ? err.message : 'Unknown error occurred',
|
|
537
796
|
});
|
|
538
797
|
endStream(err);
|
|
539
|
-
store_1.agentStore.removeListener(chatId, listener);
|
|
540
798
|
}
|
|
541
799
|
};
|
|
542
|
-
// Cleanup on consumer side closing
|
|
543
800
|
const closeHandler = () => {
|
|
544
|
-
|
|
801
|
+
this.agentStore.removeListener(chatId, listener);
|
|
545
802
|
};
|
|
546
803
|
const errorHandler = (err) => {
|
|
547
|
-
|
|
548
|
-
store_1.agentStore.removeListener(chatId, listener);
|
|
804
|
+
signal?.removeEventListener('abort', endStream);
|
|
549
805
|
endStream(err);
|
|
550
806
|
};
|
|
551
807
|
stream.on('close', closeHandler);
|
|
552
808
|
stream.on('error', errorHandler);
|
|
553
|
-
const listenerAttached =
|
|
809
|
+
const listenerAttached = this.agentStore.addListener(chatId, listener);
|
|
554
810
|
if (!listenerAttached) {
|
|
555
811
|
// Remove stream listeners if listener attachment failed to prevent memory leak
|
|
556
812
|
stream.removeListener('close', closeHandler);
|
|
@@ -559,51 +815,28 @@ class ChatProcessor {
|
|
|
559
815
|
}
|
|
560
816
|
return stream;
|
|
561
817
|
}
|
|
562
|
-
async createMessageStream(payload, excludeSocketId) {
|
|
818
|
+
async createMessageStream(payload, excludeSocketId, signal) {
|
|
563
819
|
const stream = new stream_1.PassThrough();
|
|
564
|
-
(
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
// Send chat metadata first
|
|
568
|
-
if (!('chatId' in payload) && !('messageId' in payload) && chat) {
|
|
569
|
-
stream.write(`data: ${JSON.stringify({
|
|
570
|
-
type: ai_agent_types_1.StreamChunkType.Chat,
|
|
571
|
-
chatId: chat.id,
|
|
572
|
-
chat,
|
|
573
|
-
})}\n\n`);
|
|
574
|
-
}
|
|
575
|
-
await this.streamMessage(chat, payload, excludeSocketId, async () => {
|
|
576
|
-
if (stream.destroyed || stream.writableEnded) {
|
|
577
|
-
return;
|
|
578
|
-
}
|
|
579
|
-
const messageStream = this.getMessageStream(chat.id);
|
|
580
|
-
// If client disconnects, destroy inner stream
|
|
581
|
-
stream.on('close', () => {
|
|
582
|
-
if (!messageStream.destroyed) {
|
|
583
|
-
messageStream.destroy();
|
|
584
|
-
}
|
|
585
|
-
});
|
|
586
|
-
await pipelineAsync(messageStream, stream);
|
|
587
|
-
});
|
|
588
|
-
}
|
|
589
|
-
catch (error) {
|
|
590
|
-
logger_1.logger.error({ error }, 'createMessageStream failed');
|
|
591
|
-
if (!stream.destroyed && !stream.writableEnded) {
|
|
592
|
-
stream.write(`data: ${JSON.stringify({
|
|
593
|
-
type: ai_agent_types_1.StreamChunkType.Error,
|
|
594
|
-
error: error instanceof Error ? error.message : 'Unknown error occurred',
|
|
595
|
-
})}\n\n`);
|
|
596
|
-
stream.write('data: [DONE]\n\n');
|
|
597
|
-
stream.end();
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
})().catch((err) => {
|
|
601
|
-
logger_1.logger.error({ err }, 'Unhandled stream task error');
|
|
602
|
-
if (!stream.destroyed)
|
|
603
|
-
stream.destroy(err);
|
|
820
|
+
this.runMessageStream(stream, payload, excludeSocketId, signal)
|
|
821
|
+
.catch(err => {
|
|
822
|
+
logger_1.logger.error({ err }, 'Stream task failed');
|
|
604
823
|
});
|
|
605
824
|
return stream;
|
|
606
825
|
}
|
|
826
|
+
async runMessageStream(stream, payload, excludeSocketId, signal) {
|
|
827
|
+
const chat = await this.upsertAndGetChat(payload, excludeSocketId);
|
|
828
|
+
if (!('chatId' in payload) && !('messageId' in payload) && chat) {
|
|
829
|
+
stream.write(`data: ${JSON.stringify({
|
|
830
|
+
type: ai_agent_types_1.StreamChunkType.Chat,
|
|
831
|
+
chatId: chat.id,
|
|
832
|
+
chat,
|
|
833
|
+
})}\n\n`);
|
|
834
|
+
}
|
|
835
|
+
await this.streamMessage(chat, payload, excludeSocketId, () => {
|
|
836
|
+
const messageStream = this.getMessageStream(chat.id, signal);
|
|
837
|
+
messageStream.pipe(stream);
|
|
838
|
+
});
|
|
839
|
+
}
|
|
607
840
|
}
|
|
608
841
|
exports.ChatProcessor = ChatProcessor;
|
|
609
842
|
//# sourceMappingURL=ChatProcessor.js.map
|