@multiplayer-app/ai-agent-node 0.1.0-beta.4 → 0.1.0-beta.40
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 +56 -23
- package/dist/cjs/config.d.ts.map +1 -1
- package/dist/cjs/helpers/AIHelper.cjs +154 -98
- package/dist/cjs/helpers/AIHelper.cjs.map +1 -1
- package/dist/cjs/helpers/AIHelper.d.ts +20 -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 +15 -7
- 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 +111 -31
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.ts +39 -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/ChatProcessor.cjs +138 -162
- package/dist/cjs/processors/ChatProcessor.cjs.map +1 -1
- package/dist/cjs/processors/ChatProcessor.d.ts +36 -10
- package/dist/cjs/processors/ChatProcessor.d.ts.map +1 -1
- package/dist/cjs/processors/ChatProcessor.test.cjs +333 -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 +2 -2
- package/dist/cjs/processors/index.cjs.map +1 -1
- package/dist/cjs/processors/index.d.ts +2 -2
- package/dist/cjs/processors/index.d.ts.map +1 -1
- package/dist/cjs/services/AIService.cjs +44 -30
- package/dist/cjs/services/AIService.cjs.map +1 -1
- package/dist/cjs/services/AIService.d.ts +13 -4
- 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 +56 -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 +20 -13
- package/dist/esm/helpers/AIHelper.d.ts.map +1 -1
- package/dist/esm/helpers/AIHelper.js +153 -95
- 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 +13 -5
- 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 +39 -13
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +79 -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/ChatProcessor.d.ts +36 -10
- package/dist/esm/processors/ChatProcessor.d.ts.map +1 -1
- package/dist/esm/processors/ChatProcessor.js +134 -151
- 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 +331 -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 +2 -2
- package/dist/esm/processors/index.d.ts.map +1 -1
- package/dist/esm/processors/index.js +2 -2
- package/dist/esm/processors/index.js.map +1 -1
- package/dist/esm/services/AIService.d.ts +13 -4
- package/dist/esm/services/AIService.d.ts.map +1 -1
- package/dist/esm/services/AIService.js +47 -31
- 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
|
@@ -1,54 +1,86 @@
|
|
|
1
1
|
import { AgentStatus, AgentToolCallStatus, ChatType, MessageRole, SortOrder, StreamChunkType } from '@multiplayer-app/ai-agent-types';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { config } from '../config.js';
|
|
8
|
-
import { PassThrough, pipeline } from 'stream';
|
|
9
|
-
import { promisify } from 'util';
|
|
10
|
-
import { logger } from '../libs/logger/index.js';
|
|
11
|
-
const pipelineAsync = promisify(pipeline);
|
|
2
|
+
import { AIHelper, FileHelper } from '../helpers';
|
|
3
|
+
import { AgentProcessEventType } from '../store';
|
|
4
|
+
import { ContextLimiter } from '../helpers';
|
|
5
|
+
import { PassThrough } from 'stream';
|
|
6
|
+
import { logger } from '../libs/logger';
|
|
12
7
|
export class ChatProcessor {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
8
|
+
aiHelper;
|
|
9
|
+
chatRepository;
|
|
10
|
+
messageRepository;
|
|
11
|
+
artifactStore;
|
|
12
|
+
config;
|
|
13
|
+
socketService;
|
|
14
|
+
agentStore;
|
|
15
|
+
constructor(params) {
|
|
16
|
+
this.chatRepository = params.chatRepository;
|
|
17
|
+
this.messageRepository = params.messageRepository;
|
|
18
|
+
this.artifactStore = params.artifactStore;
|
|
19
|
+
this.config = params.config;
|
|
20
|
+
this.socketService = params.socketService;
|
|
21
|
+
this.agentStore = params.agentStore;
|
|
22
|
+
const fileHelper = new FileHelper(params.s3Lib, this.config);
|
|
23
|
+
this.aiHelper = new AIHelper(fileHelper, this.config);
|
|
17
24
|
}
|
|
18
25
|
getTemporaryTitle(contextKey) {
|
|
19
26
|
return `${contextKey} session ${new Date().toISOString()}`;
|
|
20
27
|
}
|
|
28
|
+
isTemporaryTitle(title) {
|
|
29
|
+
// Matches pattern: "{contextKey} session {ISO_DATE_STRING}"
|
|
30
|
+
// Example: "default session 2026-01-23T10:30:45.123Z"
|
|
31
|
+
// toISOString() always includes milliseconds, so we require them
|
|
32
|
+
const pattern = /^.+ session \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/;
|
|
33
|
+
return pattern.test(title);
|
|
34
|
+
}
|
|
21
35
|
async listChats(params) {
|
|
22
|
-
var _a, _b;
|
|
23
36
|
// Build filter object from params
|
|
24
37
|
const filter = {};
|
|
25
|
-
if (params
|
|
38
|
+
if (params?.userId) {
|
|
26
39
|
filter.userId = params.userId;
|
|
27
40
|
}
|
|
28
|
-
if (params
|
|
41
|
+
if (params?.contextKey) {
|
|
29
42
|
filter.contextKey = params.contextKey;
|
|
30
43
|
}
|
|
31
|
-
// Build query options for sort and limit with defaults
|
|
44
|
+
// Build query options for sort and limit with defaults.
|
|
32
45
|
const options = {
|
|
33
46
|
sort: {
|
|
34
|
-
field:
|
|
35
|
-
order:
|
|
47
|
+
field: params?.sortField ?? 'updatedAt',
|
|
48
|
+
order: params?.sortOrder ?? SortOrder.Desc
|
|
36
49
|
},
|
|
37
|
-
|
|
50
|
+
skip: params?.skip,
|
|
51
|
+
limit: params?.limit
|
|
52
|
+
};
|
|
53
|
+
const [total, data] = await Promise.all([
|
|
54
|
+
this.chatRepository.count(filter),
|
|
55
|
+
this.chatRepository.find(filter, options)
|
|
56
|
+
]);
|
|
57
|
+
return {
|
|
58
|
+
cursor: {
|
|
59
|
+
...(params?.skip != null ? { skip: params.skip } : {}),
|
|
60
|
+
...(params?.limit != null ? { limit: params.limit } : {}),
|
|
61
|
+
total
|
|
62
|
+
},
|
|
63
|
+
data
|
|
38
64
|
};
|
|
39
|
-
// Use aggregation to fetch chats with related messages
|
|
40
|
-
return this.chatRepository.findWithMessages(filter, options);
|
|
41
65
|
}
|
|
42
66
|
async getChat(chatId) {
|
|
43
67
|
const chat = await this.chatRepository.findById(chatId);
|
|
44
68
|
if (!chat) {
|
|
45
69
|
throw new Error('Chat not found');
|
|
46
70
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
71
|
+
return chat;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Get messages for a chat with optional cursor pagination.
|
|
75
|
+
* When limit is omitted, returns all messages (backward compatible).
|
|
76
|
+
* Messages are returned in chronological order (oldest → newest).
|
|
77
|
+
*/
|
|
78
|
+
async getMessages(chatId, options) {
|
|
79
|
+
const chat = await this.chatRepository.findById(chatId);
|
|
80
|
+
if (!chat) {
|
|
81
|
+
throw new Error('Chat not found');
|
|
82
|
+
}
|
|
83
|
+
return this.messageRepository.findByChatIdPaginated(chatId, options);
|
|
52
84
|
}
|
|
53
85
|
async deleteChat(chatId) {
|
|
54
86
|
const deleted = await this.chatRepository.delete(chatId);
|
|
@@ -58,8 +90,7 @@ export class ChatProcessor {
|
|
|
58
90
|
this.artifactStore.deleteArtifacts(chatId);
|
|
59
91
|
}
|
|
60
92
|
async upsertAndGetChat(payload, excludeSocketId) {
|
|
61
|
-
|
|
62
|
-
const targetUserId = (_a = payload.userId) !== null && _a !== void 0 ? _a : 'guest';
|
|
93
|
+
const targetUserId = payload.userId ?? 'guest';
|
|
63
94
|
let chat = null;
|
|
64
95
|
if (payload.chatId) {
|
|
65
96
|
chat = await this.chatRepository.findById(payload.chatId);
|
|
@@ -91,7 +122,7 @@ export class ChatProcessor {
|
|
|
91
122
|
if (!content) {
|
|
92
123
|
return this.getTemporaryTitle(payload.contextKey);
|
|
93
124
|
}
|
|
94
|
-
return
|
|
125
|
+
return this.aiHelper.generateTitleForMessage(payload.contextKey, [{
|
|
95
126
|
role: MessageRole.User,
|
|
96
127
|
content: content
|
|
97
128
|
}]);
|
|
@@ -102,18 +133,17 @@ export class ChatProcessor {
|
|
|
102
133
|
role,
|
|
103
134
|
content: messageData.content,
|
|
104
135
|
agentName: messageData.agentName,
|
|
105
|
-
attachments: attachments
|
|
136
|
+
attachments: attachments ?? [],
|
|
106
137
|
reasoning: "",
|
|
107
138
|
toolCalls: []
|
|
108
139
|
});
|
|
109
140
|
if (chat.userId) {
|
|
110
|
-
socketService.emitMessageUpdate(chat.userId, message, excludeSocketId);
|
|
141
|
+
this.socketService.emitMessageUpdate(chat.userId, message, excludeSocketId);
|
|
111
142
|
}
|
|
112
143
|
return message;
|
|
113
144
|
}
|
|
114
145
|
async createChat(payload, excludeSocketId) {
|
|
115
|
-
|
|
116
|
-
const targetUserId = (_a = payload.userId) !== null && _a !== void 0 ? _a : 'guest';
|
|
146
|
+
const targetUserId = payload.userId ?? 'guest';
|
|
117
147
|
const contextKey = 'contextKey' in payload ? payload.contextKey : 'default';
|
|
118
148
|
const metadata = 'metadata' in payload ? payload.metadata : {};
|
|
119
149
|
const chat = await this.chatRepository.create({
|
|
@@ -125,12 +155,7 @@ export class ChatProcessor {
|
|
|
125
155
|
metadata,
|
|
126
156
|
...(payload.model ? { model: payload.model } : {})
|
|
127
157
|
});
|
|
128
|
-
|
|
129
|
-
const initialChatResponse = {
|
|
130
|
-
...chat,
|
|
131
|
-
messages: []
|
|
132
|
-
};
|
|
133
|
-
socketService.emitChatUpdate(targetUserId, initialChatResponse, excludeSocketId);
|
|
158
|
+
this.socketService.emitChatUpdate(targetUserId, chat, excludeSocketId);
|
|
134
159
|
return chat;
|
|
135
160
|
}
|
|
136
161
|
/**
|
|
@@ -138,23 +163,22 @@ export class ChatProcessor {
|
|
|
138
163
|
* This updates the message containing the tool call and optionally appends a System message.
|
|
139
164
|
*/
|
|
140
165
|
async recordToolCallAction(params) {
|
|
141
|
-
var _a, _b, _c, _d;
|
|
142
166
|
const chat = await this.chatRepository.findById(params.chatId);
|
|
143
167
|
if (!chat) {
|
|
144
168
|
throw new Error('Chat not found');
|
|
145
169
|
}
|
|
146
170
|
const messages = await this.messageRepository.findByChatId(params.chatId);
|
|
147
|
-
const message = messages.find((m) =>
|
|
171
|
+
const message = messages.find((m) => (m.toolCalls ?? []).some((c) => c.id === params.toolCallId));
|
|
148
172
|
if (!message) {
|
|
149
173
|
throw new Error('Tool call not found');
|
|
150
174
|
}
|
|
151
|
-
const toolCalls =
|
|
175
|
+
const toolCalls = message.toolCalls ?? [];
|
|
152
176
|
const target = toolCalls.find((c) => c.id === params.toolCallId);
|
|
153
177
|
if (!target) {
|
|
154
178
|
throw new Error('Tool call not found');
|
|
155
179
|
}
|
|
156
180
|
const now = new Date().toISOString();
|
|
157
|
-
const output = (
|
|
181
|
+
const output = (target.output ?? {});
|
|
158
182
|
const mp = (output['_mp'] && typeof output['_mp'] === 'object' && !Array.isArray(output['_mp']))
|
|
159
183
|
? output['_mp']
|
|
160
184
|
: {};
|
|
@@ -164,14 +188,14 @@ export class ChatProcessor {
|
|
|
164
188
|
lastAction: {
|
|
165
189
|
action: params.action,
|
|
166
190
|
at: now,
|
|
167
|
-
data:
|
|
191
|
+
data: params.data ?? {},
|
|
168
192
|
},
|
|
169
193
|
actions: [
|
|
170
194
|
...actions,
|
|
171
195
|
{
|
|
172
196
|
action: params.action,
|
|
173
197
|
at: now,
|
|
174
|
-
data:
|
|
198
|
+
data: params.data ?? {},
|
|
175
199
|
}
|
|
176
200
|
]
|
|
177
201
|
};
|
|
@@ -186,7 +210,7 @@ export class ChatProcessor {
|
|
|
186
210
|
await this.messageRepository.update(message.id, { toolCalls });
|
|
187
211
|
// Bump chat updatedAt so listChats ordering reflects the action.
|
|
188
212
|
await this.chatRepository.update(chat.id, { updatedAt: now });
|
|
189
|
-
socketService.emitMessageUpdate(chat.userId, updatedMessage, params.excludeSocketId);
|
|
213
|
+
this.socketService.emitMessageUpdate(chat.userId, updatedMessage, params.excludeSocketId);
|
|
190
214
|
if (params.systemMessage) {
|
|
191
215
|
//todo discuss support for system messages
|
|
192
216
|
//await this.createMessage(chat, MessageRole.System, params.systemMessage, undefined, params.excludeSocketId);
|
|
@@ -194,26 +218,25 @@ export class ChatProcessor {
|
|
|
194
218
|
return { ok: true };
|
|
195
219
|
}
|
|
196
220
|
async streamMessageStep(params) {
|
|
197
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
198
221
|
const { chat, assistantMessage, existingMessages, signal, excludeSocketId, agentOptions } = params;
|
|
199
222
|
if (signal.aborted) {
|
|
200
223
|
return;
|
|
201
224
|
}
|
|
202
|
-
const result = await
|
|
225
|
+
const result = await this.aiHelper.streamAssistantResponse(existingMessages, signal, agentOptions);
|
|
203
226
|
try {
|
|
204
227
|
for await (const chunk of result.fullStream) {
|
|
205
228
|
if (chunk.type === 'error') {
|
|
206
|
-
await agentStore.shareAgentProcessEvent(chat.id, { type: AgentProcessEventType.Error, data: chunk.error });
|
|
229
|
+
await this.agentStore.shareAgentProcessEvent(chat.id, { type: AgentProcessEventType.Error, data: chunk.error });
|
|
207
230
|
assistantMessage.content = chunk.error.message || 'Sorry, I cannot process you request due to the error';
|
|
208
231
|
await this.messageRepository.update(assistantMessage.id, assistantMessage);
|
|
209
232
|
await this.chatRepository.update(chat.id, { status: AgentStatus.Error });
|
|
210
233
|
continue;
|
|
211
234
|
}
|
|
212
235
|
if (chunk.type === 'abort') {
|
|
213
|
-
await agentStore.shareAgentProcessEvent(chat.id, { type: AgentProcessEventType.Aborted, data: undefined });
|
|
236
|
+
await this.agentStore.shareAgentProcessEvent(chat.id, { type: AgentProcessEventType.Aborted, data: undefined });
|
|
214
237
|
await this.chatRepository.update(chat.id, { status: AgentStatus.Aborted });
|
|
215
238
|
await this.messageRepository.update(assistantMessage.id, assistantMessage);
|
|
216
|
-
socketService.emitMessageUpdate(chat.userId, assistantMessage, excludeSocketId);
|
|
239
|
+
this.socketService.emitMessageUpdate(chat.userId, assistantMessage, excludeSocketId);
|
|
217
240
|
continue;
|
|
218
241
|
}
|
|
219
242
|
if (chunk.type === 'finish') {
|
|
@@ -226,41 +249,27 @@ export class ChatProcessor {
|
|
|
226
249
|
}
|
|
227
250
|
if (chunk.totalUsage && typeof chunk.totalUsage === 'object') {
|
|
228
251
|
const totalUsage = chunk.totalUsage;
|
|
229
|
-
assistantMessage.tokens =
|
|
252
|
+
assistantMessage.tokens = totalUsage.totalTokens ??
|
|
253
|
+
((totalUsage.promptTokens ?? 0) + (totalUsage.completionTokens ?? 0));
|
|
230
254
|
}
|
|
231
255
|
await this.messageRepository.update(assistantMessage.id, { ...assistantMessage });
|
|
232
256
|
if (chunk.finishReason === 'stop') {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
await agentStore.shareAgentProcessEvent(chat.id, { type: AgentProcessEventType.Update, data: assistantMessage });
|
|
239
|
-
await this.streamMessageStep(params);
|
|
240
|
-
continue;
|
|
241
|
-
}
|
|
242
|
-
else {
|
|
243
|
-
await this.chatRepository.update(chat.id, { status: AgentStatus.Finished });
|
|
257
|
+
await this.chatRepository.update(chat.id, { status: AgentStatus.Finished });
|
|
258
|
+
if (chat.title && this.isTemporaryTitle(chat.title)) {
|
|
259
|
+
const title = await this.aiHelper.generateTitleForMessage(chat.contextKey, existingMessages);
|
|
260
|
+
await this.chatRepository.update(chat.id, { title });
|
|
261
|
+
this.socketService.emitChatUpdate(chat.userId, { ...chat, title });
|
|
244
262
|
}
|
|
245
|
-
await agentStore.shareAgentProcessEvent(chat.id, { type: AgentProcessEventType.Finished, data: assistantMessage });
|
|
246
|
-
continue;
|
|
247
263
|
}
|
|
248
264
|
if (chunk.finishReason === 'tool-calls') {
|
|
249
|
-
if (
|
|
265
|
+
if (assistantMessage.toolCalls?.some(toolCall => toolCall.requiresConfirmation && toolCall.approvalId && !toolCall.output)) {
|
|
250
266
|
await this.chatRepository.update(chat.id, { status: AgentStatus.WaitingForUserAction });
|
|
251
|
-
await agentStore.shareAgentProcessEvent(chat.id, { type: AgentProcessEventType.Finished, data: assistantMessage });
|
|
252
|
-
|
|
253
|
-
else {
|
|
254
|
-
await agentStore.shareAgentProcessEvent(chat.id, {
|
|
255
|
-
type: AgentProcessEventType.Update,
|
|
256
|
-
data: assistantMessage
|
|
257
|
-
});
|
|
258
|
-
await this.streamMessageStep(params);
|
|
267
|
+
await this.agentStore.shareAgentProcessEvent(chat.id, { type: AgentProcessEventType.Finished, data: assistantMessage });
|
|
268
|
+
continue;
|
|
259
269
|
}
|
|
260
|
-
continue;
|
|
261
270
|
}
|
|
262
271
|
//todo: Handle other finish reasons // length, content, error, other, undefined
|
|
263
|
-
await agentStore.shareAgentProcessEvent(chat.id, { type: AgentProcessEventType.Finished, data: assistantMessage });
|
|
272
|
+
await this.agentStore.shareAgentProcessEvent(chat.id, { type: AgentProcessEventType.Finished, data: assistantMessage });
|
|
264
273
|
continue;
|
|
265
274
|
}
|
|
266
275
|
if (chunk.type === 'text-delta') {
|
|
@@ -269,8 +278,8 @@ export class ChatProcessor {
|
|
|
269
278
|
...assistantMessage,
|
|
270
279
|
content: assistantMessage.content
|
|
271
280
|
};
|
|
272
|
-
socketService.emitMessageUpdate(chat.userId, updatedMessage, excludeSocketId);
|
|
273
|
-
await agentStore.shareAgentProcessEvent(chat.id, { type: AgentProcessEventType.Update, data: updatedMessage });
|
|
281
|
+
this.socketService.emitMessageUpdate(chat.userId, updatedMessage, excludeSocketId);
|
|
282
|
+
await this.agentStore.shareAgentProcessEvent(chat.id, { type: AgentProcessEventType.Update, data: updatedMessage });
|
|
274
283
|
await this.messageRepository.update(assistantMessage.id, { content: assistantMessage.content });
|
|
275
284
|
continue;
|
|
276
285
|
}
|
|
@@ -285,8 +294,8 @@ export class ChatProcessor {
|
|
|
285
294
|
});
|
|
286
295
|
continue;
|
|
287
296
|
}
|
|
288
|
-
if (chunk.type === 'tool-call') {
|
|
289
|
-
const toolCall =
|
|
297
|
+
if (chunk.type === 'tool-call') {
|
|
298
|
+
const toolCall = assistantMessage.toolCalls?.find(toolCall => toolCall.id === chunk.toolCallId);
|
|
290
299
|
if (toolCall) {
|
|
291
300
|
toolCall.status = AgentToolCallStatus.Running;
|
|
292
301
|
toolCall.input = chunk.input;
|
|
@@ -294,15 +303,15 @@ export class ChatProcessor {
|
|
|
294
303
|
continue;
|
|
295
304
|
}
|
|
296
305
|
if (chunk.type === 'tool-error') {
|
|
297
|
-
const toolCall =
|
|
306
|
+
const toolCall = assistantMessage.toolCalls?.find(toolCall => toolCall.id === chunk.toolCallId);
|
|
298
307
|
if (toolCall) {
|
|
299
308
|
toolCall.status = AgentToolCallStatus.Failed;
|
|
300
|
-
toolCall.error = JSON.stringify(chunk.error);
|
|
309
|
+
toolCall.error = chunk.error.message || JSON.stringify(chunk.error);
|
|
301
310
|
}
|
|
302
311
|
continue;
|
|
303
312
|
}
|
|
304
313
|
if (chunk.type === 'tool-approval-request') {
|
|
305
|
-
const toolCall =
|
|
314
|
+
const toolCall = assistantMessage.toolCalls?.find(toolCall => toolCall.id === chunk.toolCall.toolCallId);
|
|
306
315
|
if (toolCall) {
|
|
307
316
|
toolCall.requiresConfirmation = true;
|
|
308
317
|
toolCall.approvalId = chunk.approvalId;
|
|
@@ -310,7 +319,7 @@ export class ChatProcessor {
|
|
|
310
319
|
continue;
|
|
311
320
|
}
|
|
312
321
|
if (chunk.type === 'tool-result') {
|
|
313
|
-
const toolCall =
|
|
322
|
+
const toolCall = assistantMessage.toolCalls?.find(toolCall => toolCall.id === chunk.toolCallId);
|
|
314
323
|
if (toolCall) {
|
|
315
324
|
if (chunk.output.requiresApproval) {
|
|
316
325
|
toolCall.requiresConfirmation = true;
|
|
@@ -325,9 +334,9 @@ export class ChatProcessor {
|
|
|
325
334
|
if (!assistantMessage.reasoning)
|
|
326
335
|
assistantMessage.reasoning = '';
|
|
327
336
|
assistantMessage.reasoning += chunk.text;
|
|
328
|
-
socketService.emitMessageUpdate(chat.userId, assistantMessage, excludeSocketId);
|
|
337
|
+
this.socketService.emitMessageUpdate(chat.userId, assistantMessage, excludeSocketId);
|
|
329
338
|
await this.messageRepository.update(assistantMessage.id, { reasoning: assistantMessage.reasoning });
|
|
330
|
-
await agentStore.shareAgentProcessEvent(chat.id, { type: AgentProcessEventType.Update, data: assistantMessage });
|
|
339
|
+
await this.agentStore.shareAgentProcessEvent(chat.id, { type: AgentProcessEventType.Update, data: assistantMessage });
|
|
331
340
|
continue;
|
|
332
341
|
}
|
|
333
342
|
}
|
|
@@ -336,7 +345,7 @@ export class ChatProcessor {
|
|
|
336
345
|
if (streamError instanceof Error && streamError.name === 'AbortError') {
|
|
337
346
|
return;
|
|
338
347
|
}
|
|
339
|
-
await agentStore.shareAgentProcessEvent(chat.id, { type: AgentProcessEventType.Error, data: streamError });
|
|
348
|
+
await this.agentStore.shareAgentProcessEvent(chat.id, { type: AgentProcessEventType.Error, data: streamError });
|
|
340
349
|
throw streamError;
|
|
341
350
|
}
|
|
342
351
|
}
|
|
@@ -344,16 +353,15 @@ export class ChatProcessor {
|
|
|
344
353
|
return 'approvalId' in payload;
|
|
345
354
|
}
|
|
346
355
|
async processApprovalPayload(chat, payload) {
|
|
347
|
-
var _a, _b, _c;
|
|
348
356
|
const assistantMessage = await this.messageRepository.findById(payload.messageId);
|
|
349
357
|
if (!assistantMessage || assistantMessage.chat !== chat.id) {
|
|
350
358
|
throw new Error(`Assistant message with id ${payload.messageId} not found`);
|
|
351
359
|
}
|
|
352
|
-
const agentOptions = await
|
|
360
|
+
const agentOptions = await this.aiHelper.getAgentOptions({
|
|
353
361
|
agentName: assistantMessage.agentName,
|
|
354
362
|
context: payload.context
|
|
355
363
|
});
|
|
356
|
-
const toolCall =
|
|
364
|
+
const toolCall = assistantMessage.toolCalls?.find(tc => tc.approvalId === payload.approvalId);
|
|
357
365
|
if (!toolCall) {
|
|
358
366
|
// continue, tool is not found
|
|
359
367
|
return {
|
|
@@ -371,7 +379,7 @@ export class ChatProcessor {
|
|
|
371
379
|
toolCall.status = AgentToolCallStatus.Failed;
|
|
372
380
|
}
|
|
373
381
|
else {
|
|
374
|
-
const executeFunction =
|
|
382
|
+
const executeFunction = agentOptions.tools?.[toolCall.name]?.execute;
|
|
375
383
|
if (executeFunction) {
|
|
376
384
|
try {
|
|
377
385
|
toolCall.output = await executeFunction(toolCall.input, { toolCallId: toolCall.id, messages: [] });
|
|
@@ -402,15 +410,15 @@ export class ChatProcessor {
|
|
|
402
410
|
}
|
|
403
411
|
async processNewUserMessage(chat, payload, prevMessages, excludeSocketId) {
|
|
404
412
|
const userMessage = await this.createMessage(chat, MessageRole.User, { content: payload.content, agentName: undefined }, payload.attachments);
|
|
405
|
-
await agentStore.shareAgentProcessEvent(chat.id, { type: AgentProcessEventType.Update, data: userMessage });
|
|
406
|
-
const agentOptions = await
|
|
413
|
+
await this.agentStore.shareAgentProcessEvent(chat.id, { type: AgentProcessEventType.Update, data: userMessage });
|
|
414
|
+
const agentOptions = await this.aiHelper.getAgentOptions({
|
|
407
415
|
contextKey: chat.contextKey,
|
|
408
|
-
messages:
|
|
416
|
+
messages: [...prevMessages, userMessage],
|
|
409
417
|
context: payload.context,
|
|
410
418
|
agentName: undefined,
|
|
411
419
|
modelId: chat.model,
|
|
412
420
|
});
|
|
413
|
-
const assistantMessage = await this.createMessage(chat, MessageRole.Assistant, { content: '
|
|
421
|
+
const assistantMessage = await this.createMessage(chat, MessageRole.Assistant, { content: '', agentName: agentOptions.name }, undefined, excludeSocketId);
|
|
414
422
|
assistantMessage.content = '';
|
|
415
423
|
return {
|
|
416
424
|
userMessage,
|
|
@@ -420,14 +428,14 @@ export class ChatProcessor {
|
|
|
420
428
|
}
|
|
421
429
|
async streamMessage(chat, payload, excludeSocketId, onAgentStart) {
|
|
422
430
|
try {
|
|
423
|
-
const abortController = agentStore.registerAgentProcess(chat.id);
|
|
424
|
-
onAgentStart
|
|
431
|
+
const abortController = this.agentStore.registerAgentProcess(chat.id);
|
|
432
|
+
onAgentStart?.();
|
|
425
433
|
let assistantMessage;
|
|
426
434
|
let agentOptions;
|
|
427
435
|
const existingMessages = await this.messageRepository.findByChatId(chat.id);
|
|
428
436
|
// Limit context to prevent exceeding token limits
|
|
429
437
|
const limitedMessages = ContextLimiter.limitContext(existingMessages, {
|
|
430
|
-
maxMessages: config.ai.maxContextMessages,
|
|
438
|
+
maxMessages: this.config.ai.maxContextMessages,
|
|
431
439
|
keepFirstUserMessage: true,
|
|
432
440
|
keepSystemMessages: true,
|
|
433
441
|
});
|
|
@@ -492,7 +500,7 @@ export class ChatProcessor {
|
|
|
492
500
|
return null;
|
|
493
501
|
}
|
|
494
502
|
}
|
|
495
|
-
getMessageStream(chatId) {
|
|
503
|
+
getMessageStream(chatId, signal) {
|
|
496
504
|
const stream = new PassThrough();
|
|
497
505
|
let ended = false;
|
|
498
506
|
const endStream = (error) => {
|
|
@@ -513,13 +521,15 @@ export class ChatProcessor {
|
|
|
513
521
|
}
|
|
514
522
|
};
|
|
515
523
|
const pushChunk = (chunk) => {
|
|
516
|
-
if (ended || stream.destroyed || stream.writableEnded)
|
|
524
|
+
if (ended || stream.destroyed || stream.writableEnded || signal?.aborted)
|
|
517
525
|
return;
|
|
518
526
|
stream.write(`data: ${JSON.stringify(chunk)}\n\n`);
|
|
519
527
|
};
|
|
520
528
|
const listener = (event) => {
|
|
521
|
-
if (
|
|
529
|
+
if (signal?.aborted) {
|
|
530
|
+
endStream();
|
|
522
531
|
return;
|
|
532
|
+
}
|
|
523
533
|
try {
|
|
524
534
|
const chunk = this.eventToChunk(event);
|
|
525
535
|
if (chunk) {
|
|
@@ -529,7 +539,6 @@ export class ChatProcessor {
|
|
|
529
539
|
event.type === AgentProcessEventType.Error ||
|
|
530
540
|
event.type === AgentProcessEventType.Aborted) {
|
|
531
541
|
endStream();
|
|
532
|
-
agentStore.removeListener(chatId, listener);
|
|
533
542
|
}
|
|
534
543
|
}
|
|
535
544
|
catch (err) {
|
|
@@ -538,21 +547,18 @@ export class ChatProcessor {
|
|
|
538
547
|
error: err instanceof Error ? err.message : 'Unknown error occurred',
|
|
539
548
|
});
|
|
540
549
|
endStream(err);
|
|
541
|
-
agentStore.removeListener(chatId, listener);
|
|
542
550
|
}
|
|
543
551
|
};
|
|
544
|
-
// Cleanup on consumer side closing
|
|
545
552
|
const closeHandler = () => {
|
|
546
|
-
agentStore.removeListener(chatId, listener);
|
|
553
|
+
this.agentStore.removeListener(chatId, listener);
|
|
547
554
|
};
|
|
548
555
|
const errorHandler = (err) => {
|
|
549
|
-
|
|
550
|
-
agentStore.removeListener(chatId, listener);
|
|
556
|
+
signal?.removeEventListener('abort', endStream);
|
|
551
557
|
endStream(err);
|
|
552
558
|
};
|
|
553
559
|
stream.on('close', closeHandler);
|
|
554
560
|
stream.on('error', errorHandler);
|
|
555
|
-
const listenerAttached = agentStore.addListener(chatId, listener);
|
|
561
|
+
const listenerAttached = this.agentStore.addListener(chatId, listener);
|
|
556
562
|
if (!listenerAttached) {
|
|
557
563
|
// Remove stream listeners if listener attachment failed to prevent memory leak
|
|
558
564
|
stream.removeListener('close', closeHandler);
|
|
@@ -561,50 +567,27 @@ export class ChatProcessor {
|
|
|
561
567
|
}
|
|
562
568
|
return stream;
|
|
563
569
|
}
|
|
564
|
-
async createMessageStream(payload, excludeSocketId) {
|
|
570
|
+
async createMessageStream(payload, excludeSocketId, signal) {
|
|
565
571
|
const stream = new PassThrough();
|
|
566
|
-
(
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
// Send chat metadata first
|
|
570
|
-
if (!('chatId' in payload) && !('messageId' in payload) && chat) {
|
|
571
|
-
stream.write(`data: ${JSON.stringify({
|
|
572
|
-
type: StreamChunkType.Chat,
|
|
573
|
-
chatId: chat.id,
|
|
574
|
-
chat,
|
|
575
|
-
})}\n\n`);
|
|
576
|
-
}
|
|
577
|
-
await this.streamMessage(chat, payload, excludeSocketId, async () => {
|
|
578
|
-
if (stream.destroyed || stream.writableEnded) {
|
|
579
|
-
return;
|
|
580
|
-
}
|
|
581
|
-
const messageStream = this.getMessageStream(chat.id);
|
|
582
|
-
// If client disconnects, destroy inner stream
|
|
583
|
-
stream.on('close', () => {
|
|
584
|
-
if (!messageStream.destroyed) {
|
|
585
|
-
messageStream.destroy();
|
|
586
|
-
}
|
|
587
|
-
});
|
|
588
|
-
await pipelineAsync(messageStream, stream);
|
|
589
|
-
});
|
|
590
|
-
}
|
|
591
|
-
catch (error) {
|
|
592
|
-
logger.error({ error }, 'createMessageStream failed');
|
|
593
|
-
if (!stream.destroyed && !stream.writableEnded) {
|
|
594
|
-
stream.write(`data: ${JSON.stringify({
|
|
595
|
-
type: StreamChunkType.Error,
|
|
596
|
-
error: error instanceof Error ? error.message : 'Unknown error occurred',
|
|
597
|
-
})}\n\n`);
|
|
598
|
-
stream.write('data: [DONE]\n\n');
|
|
599
|
-
stream.end();
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
})().catch((err) => {
|
|
603
|
-
logger.error({ err }, 'Unhandled stream task error');
|
|
604
|
-
if (!stream.destroyed)
|
|
605
|
-
stream.destroy(err);
|
|
572
|
+
this.runMessageStream(stream, payload, excludeSocketId, signal)
|
|
573
|
+
.catch(err => {
|
|
574
|
+
logger.error({ err }, 'Stream task failed');
|
|
606
575
|
});
|
|
607
576
|
return stream;
|
|
608
577
|
}
|
|
578
|
+
async runMessageStream(stream, payload, excludeSocketId, signal) {
|
|
579
|
+
const chat = await this.upsertAndGetChat(payload, excludeSocketId);
|
|
580
|
+
if (!('chatId' in payload) && !('messageId' in payload) && chat) {
|
|
581
|
+
stream.write(`data: ${JSON.stringify({
|
|
582
|
+
type: StreamChunkType.Chat,
|
|
583
|
+
chatId: chat.id,
|
|
584
|
+
chat,
|
|
585
|
+
})}\n\n`);
|
|
586
|
+
}
|
|
587
|
+
await this.streamMessage(chat, payload, excludeSocketId, () => {
|
|
588
|
+
const messageStream = this.getMessageStream(chat.id, signal);
|
|
589
|
+
messageStream.pipe(stream);
|
|
590
|
+
});
|
|
591
|
+
}
|
|
609
592
|
}
|
|
610
593
|
//# sourceMappingURL=ChatProcessor.js.map
|