@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.
Files changed (274) hide show
  1. package/README.md +2 -2
  2. package/dist/cjs/config.cjs +88 -37
  3. package/dist/cjs/config.cjs.map +1 -1
  4. package/dist/cjs/config.d.ts +57 -23
  5. package/dist/cjs/config.d.ts.map +1 -1
  6. package/dist/cjs/helpers/AIHelper.cjs +127 -65
  7. package/dist/cjs/helpers/AIHelper.cjs.map +1 -1
  8. package/dist/cjs/helpers/AIHelper.d.ts +22 -16
  9. package/dist/cjs/helpers/AIHelper.d.ts.map +1 -1
  10. package/dist/cjs/helpers/AIHelper.test.cjs +22 -15
  11. package/dist/cjs/helpers/AIHelper.test.cjs.map +1 -1
  12. package/dist/cjs/helpers/ConfigHelper.cjs +15 -6
  13. package/dist/cjs/helpers/ConfigHelper.cjs.map +1 -1
  14. package/dist/cjs/helpers/ConfigHelper.d.ts.map +1 -1
  15. package/dist/cjs/helpers/FileHelper.cjs +131 -151
  16. package/dist/cjs/helpers/FileHelper.cjs.map +1 -1
  17. package/dist/cjs/helpers/FileHelper.d.ts +19 -25
  18. package/dist/cjs/helpers/FileHelper.d.ts.map +1 -1
  19. package/dist/cjs/helpers/index.cjs +0 -1
  20. package/dist/cjs/helpers/index.cjs.map +1 -1
  21. package/dist/cjs/helpers/index.d.ts +0 -1
  22. package/dist/cjs/helpers/index.d.ts.map +1 -1
  23. package/dist/cjs/index.cjs +120 -28
  24. package/dist/cjs/index.cjs.map +1 -1
  25. package/dist/cjs/index.d.ts +43 -11
  26. package/dist/cjs/index.d.ts.map +1 -1
  27. package/dist/cjs/libs/index.cjs +0 -1
  28. package/dist/cjs/libs/index.cjs.map +1 -1
  29. package/dist/cjs/libs/index.d.ts +0 -1
  30. package/dist/cjs/libs/index.d.ts.map +1 -1
  31. package/dist/cjs/libs/s3/index.cjs +3 -39
  32. package/dist/cjs/libs/s3/index.cjs.map +1 -1
  33. package/dist/cjs/libs/s3/index.d.ts +1 -2
  34. package/dist/cjs/libs/s3/index.d.ts.map +1 -1
  35. package/dist/cjs/libs/s3/s3.lib.cjs +173 -186
  36. package/dist/cjs/libs/s3/s3.lib.cjs.map +1 -1
  37. package/dist/cjs/libs/s3/s3.lib.d.ts +29 -22
  38. package/dist/cjs/libs/s3/s3.lib.d.ts.map +1 -1
  39. package/dist/cjs/processors/ActivityProcessor.cjs +39 -0
  40. package/dist/cjs/processors/ActivityProcessor.cjs.map +1 -0
  41. package/dist/cjs/processors/ActivityProcessor.d.ts +32 -0
  42. package/dist/cjs/processors/ActivityProcessor.d.ts.map +1 -0
  43. package/dist/cjs/processors/ActivityProcessor.test.cjs +84 -0
  44. package/dist/cjs/processors/ActivityProcessor.test.cjs.map +1 -0
  45. package/dist/cjs/processors/ActivityProcessor.test.d.ts +2 -0
  46. package/dist/cjs/processors/ActivityProcessor.test.d.ts.map +1 -0
  47. package/dist/cjs/processors/AgentProcessor.cjs +46 -0
  48. package/dist/cjs/processors/AgentProcessor.cjs.map +1 -0
  49. package/dist/cjs/processors/AgentProcessor.d.ts +25 -0
  50. package/dist/cjs/processors/AgentProcessor.d.ts.map +1 -0
  51. package/dist/cjs/processors/AgentProcessor.test.cjs +103 -0
  52. package/dist/cjs/processors/AgentProcessor.test.cjs.map +1 -0
  53. package/dist/cjs/processors/AgentProcessor.test.d.ts +2 -0
  54. package/dist/cjs/processors/AgentProcessor.test.d.ts.map +1 -0
  55. package/dist/cjs/processors/ChatProcessor.cjs +355 -122
  56. package/dist/cjs/processors/ChatProcessor.cjs.map +1 -1
  57. package/dist/cjs/processors/ChatProcessor.d.ts +71 -11
  58. package/dist/cjs/processors/ChatProcessor.d.ts.map +1 -1
  59. package/dist/cjs/processors/ChatProcessor.test.cjs +762 -0
  60. package/dist/cjs/processors/ChatProcessor.test.cjs.map +1 -0
  61. package/dist/cjs/processors/ChatProcessor.test.d.ts +2 -0
  62. package/dist/cjs/processors/ChatProcessor.test.d.ts.map +1 -0
  63. package/dist/cjs/processors/index.cjs +2 -0
  64. package/dist/cjs/processors/index.cjs.map +1 -1
  65. package/dist/cjs/processors/index.d.ts +2 -0
  66. package/dist/cjs/processors/index.d.ts.map +1 -1
  67. package/dist/cjs/services/AIService.cjs +87 -21
  68. package/dist/cjs/services/AIService.cjs.map +1 -1
  69. package/dist/cjs/services/AIService.d.ts +19 -7
  70. package/dist/cjs/services/AIService.d.ts.map +1 -1
  71. package/dist/cjs/services/InternalEventsHandler.cjs +3 -3
  72. package/dist/cjs/services/InternalEventsHandler.cjs.map +1 -1
  73. package/dist/cjs/services/InternalEventsHandler.d.ts +3 -1
  74. package/dist/cjs/services/InternalEventsHandler.d.ts.map +1 -1
  75. package/dist/cjs/services/ModelFetcher.cjs +2 -8
  76. package/dist/cjs/services/ModelFetcher.cjs.map +1 -1
  77. package/dist/cjs/services/ModelFetcher.d.ts +2 -7
  78. package/dist/cjs/services/ModelFetcher.d.ts.map +1 -1
  79. package/dist/cjs/services/RedisService.cjs +20 -16
  80. package/dist/cjs/services/RedisService.cjs.map +1 -1
  81. package/dist/cjs/services/RedisService.d.ts +5 -2
  82. package/dist/cjs/services/RedisService.d.ts.map +1 -1
  83. package/dist/cjs/services/SocketService.cjs +8 -8
  84. package/dist/cjs/services/SocketService.cjs.map +1 -1
  85. package/dist/cjs/services/SocketService.d.ts +9 -6
  86. package/dist/cjs/services/SocketService.d.ts.map +1 -1
  87. package/dist/cjs/services/index.cjs +0 -1
  88. package/dist/cjs/services/index.cjs.map +1 -1
  89. package/dist/cjs/services/index.d.ts +0 -1
  90. package/dist/cjs/services/index.d.ts.map +1 -1
  91. package/dist/cjs/store/AgentStore.cjs +3 -4
  92. package/dist/cjs/store/AgentStore.cjs.map +1 -1
  93. package/dist/cjs/store/AgentStore.d.ts +2 -1
  94. package/dist/cjs/store/AgentStore.d.ts.map +1 -1
  95. package/dist/cjs/store/ConfigStore.cjs +7 -3
  96. package/dist/cjs/store/ConfigStore.cjs.map +1 -1
  97. package/dist/cjs/store/ConfigStore.d.ts +1 -0
  98. package/dist/cjs/store/ConfigStore.d.ts.map +1 -1
  99. package/dist/cjs/tools/generateChartTool.d.ts +2 -2
  100. package/dist/cjs/tools/proposeFormValuesTool.d.ts +2 -2
  101. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  102. package/dist/esm/config.d.ts +57 -23
  103. package/dist/esm/config.d.ts.map +1 -1
  104. package/dist/esm/config.js +88 -35
  105. package/dist/esm/config.js.map +1 -1
  106. package/dist/esm/helpers/AIHelper.d.ts +22 -16
  107. package/dist/esm/helpers/AIHelper.d.ts.map +1 -1
  108. package/dist/esm/helpers/AIHelper.js +134 -70
  109. package/dist/esm/helpers/AIHelper.js.map +1 -1
  110. package/dist/esm/helpers/AIHelper.test.js +22 -15
  111. package/dist/esm/helpers/AIHelper.test.js.map +1 -1
  112. package/dist/esm/helpers/ConfigHelper.d.ts.map +1 -1
  113. package/dist/esm/helpers/ConfigHelper.js +15 -6
  114. package/dist/esm/helpers/ConfigHelper.js.map +1 -1
  115. package/dist/esm/helpers/FileHelper.d.ts +19 -25
  116. package/dist/esm/helpers/FileHelper.d.ts.map +1 -1
  117. package/dist/esm/helpers/FileHelper.js +131 -146
  118. package/dist/esm/helpers/FileHelper.js.map +1 -1
  119. package/dist/esm/helpers/index.d.ts +0 -1
  120. package/dist/esm/helpers/index.d.ts.map +1 -1
  121. package/dist/esm/helpers/index.js +0 -1
  122. package/dist/esm/helpers/index.js.map +1 -1
  123. package/dist/esm/index.d.ts +43 -11
  124. package/dist/esm/index.d.ts.map +1 -1
  125. package/dist/esm/index.js +92 -11
  126. package/dist/esm/index.js.map +1 -1
  127. package/dist/esm/libs/index.d.ts +0 -1
  128. package/dist/esm/libs/index.d.ts.map +1 -1
  129. package/dist/esm/libs/index.js +0 -1
  130. package/dist/esm/libs/index.js.map +1 -1
  131. package/dist/esm/libs/s3/index.d.ts +1 -2
  132. package/dist/esm/libs/s3/index.d.ts.map +1 -1
  133. package/dist/esm/libs/s3/index.js +1 -2
  134. package/dist/esm/libs/s3/index.js.map +1 -1
  135. package/dist/esm/libs/s3/s3.lib.d.ts +29 -22
  136. package/dist/esm/libs/s3/s3.lib.d.ts.map +1 -1
  137. package/dist/esm/libs/s3/s3.lib.js +177 -172
  138. package/dist/esm/libs/s3/s3.lib.js.map +1 -1
  139. package/dist/esm/processors/ActivityProcessor.d.ts +32 -0
  140. package/dist/esm/processors/ActivityProcessor.d.ts.map +1 -0
  141. package/dist/esm/processors/ActivityProcessor.js +36 -0
  142. package/dist/esm/processors/ActivityProcessor.js.map +1 -0
  143. package/dist/esm/processors/ActivityProcessor.test.d.ts +2 -0
  144. package/dist/esm/processors/ActivityProcessor.test.d.ts.map +1 -0
  145. package/dist/esm/processors/ActivityProcessor.test.js +82 -0
  146. package/dist/esm/processors/ActivityProcessor.test.js.map +1 -0
  147. package/dist/esm/processors/AgentProcessor.d.ts +25 -0
  148. package/dist/esm/processors/AgentProcessor.d.ts.map +1 -0
  149. package/dist/esm/processors/AgentProcessor.js +43 -0
  150. package/dist/esm/processors/AgentProcessor.js.map +1 -0
  151. package/dist/esm/processors/AgentProcessor.test.d.ts +2 -0
  152. package/dist/esm/processors/AgentProcessor.test.d.ts.map +1 -0
  153. package/dist/esm/processors/AgentProcessor.test.js +101 -0
  154. package/dist/esm/processors/AgentProcessor.test.js.map +1 -0
  155. package/dist/esm/processors/ChatProcessor.d.ts +71 -11
  156. package/dist/esm/processors/ChatProcessor.d.ts.map +1 -1
  157. package/dist/esm/processors/ChatProcessor.js +366 -126
  158. package/dist/esm/processors/ChatProcessor.js.map +1 -1
  159. package/dist/esm/processors/ChatProcessor.test.d.ts +2 -0
  160. package/dist/esm/processors/ChatProcessor.test.d.ts.map +1 -0
  161. package/dist/esm/processors/ChatProcessor.test.js +760 -0
  162. package/dist/esm/processors/ChatProcessor.test.js.map +1 -0
  163. package/dist/esm/processors/index.d.ts +2 -0
  164. package/dist/esm/processors/index.d.ts.map +1 -1
  165. package/dist/esm/processors/index.js +2 -0
  166. package/dist/esm/processors/index.js.map +1 -1
  167. package/dist/esm/services/AIService.d.ts +19 -7
  168. package/dist/esm/services/AIService.d.ts.map +1 -1
  169. package/dist/esm/services/AIService.js +91 -24
  170. package/dist/esm/services/AIService.js.map +1 -1
  171. package/dist/esm/services/InternalEventsHandler.d.ts +3 -1
  172. package/dist/esm/services/InternalEventsHandler.d.ts.map +1 -1
  173. package/dist/esm/services/InternalEventsHandler.js +4 -3
  174. package/dist/esm/services/InternalEventsHandler.js.map +1 -1
  175. package/dist/esm/services/ModelFetcher.d.ts +2 -7
  176. package/dist/esm/services/ModelFetcher.d.ts.map +1 -1
  177. package/dist/esm/services/ModelFetcher.js +2 -8
  178. package/dist/esm/services/ModelFetcher.js.map +1 -1
  179. package/dist/esm/services/RedisService.d.ts +5 -2
  180. package/dist/esm/services/RedisService.d.ts.map +1 -1
  181. package/dist/esm/services/RedisService.js +21 -14
  182. package/dist/esm/services/RedisService.js.map +1 -1
  183. package/dist/esm/services/SocketService.d.ts +9 -6
  184. package/dist/esm/services/SocketService.d.ts.map +1 -1
  185. package/dist/esm/services/SocketService.js +10 -6
  186. package/dist/esm/services/SocketService.js.map +1 -1
  187. package/dist/esm/services/index.d.ts +0 -1
  188. package/dist/esm/services/index.d.ts.map +1 -1
  189. package/dist/esm/services/index.js +0 -1
  190. package/dist/esm/services/index.js.map +1 -1
  191. package/dist/esm/store/AgentStore.d.ts +2 -1
  192. package/dist/esm/store/AgentStore.d.ts.map +1 -1
  193. package/dist/esm/store/AgentStore.js +4 -2
  194. package/dist/esm/store/AgentStore.js.map +1 -1
  195. package/dist/esm/store/ConfigStore.d.ts +1 -0
  196. package/dist/esm/store/ConfigStore.d.ts.map +1 -1
  197. package/dist/esm/store/ConfigStore.js +7 -3
  198. package/dist/esm/store/ConfigStore.js.map +1 -1
  199. package/dist/esm/tools/generateChartTool.d.ts +2 -2
  200. package/dist/esm/tools/proposeFormValuesTool.d.ts +2 -2
  201. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  202. package/package.json +12 -12
  203. package/dist/cjs/helpers/SetupHelper.cjs +0 -37
  204. package/dist/cjs/helpers/SetupHelper.cjs.map +0 -1
  205. package/dist/cjs/helpers/SetupHelper.d.ts +0 -5
  206. package/dist/cjs/helpers/SetupHelper.d.ts.map +0 -1
  207. package/dist/cjs/libs/kafka/config.cjs +0 -8
  208. package/dist/cjs/libs/kafka/config.cjs.map +0 -1
  209. package/dist/cjs/libs/kafka/config.d.ts +0 -5
  210. package/dist/cjs/libs/kafka/config.d.ts.map +0 -1
  211. package/dist/cjs/libs/kafka/consumer.cjs +0 -131
  212. package/dist/cjs/libs/kafka/consumer.cjs.map +0 -1
  213. package/dist/cjs/libs/kafka/consumer.d.ts +0 -16
  214. package/dist/cjs/libs/kafka/consumer.d.ts.map +0 -1
  215. package/dist/cjs/libs/kafka/index.cjs +0 -19
  216. package/dist/cjs/libs/kafka/index.cjs.map +0 -1
  217. package/dist/cjs/libs/kafka/index.d.ts +0 -3
  218. package/dist/cjs/libs/kafka/index.d.ts.map +0 -1
  219. package/dist/cjs/libs/kafka/kafka.cjs +0 -27
  220. package/dist/cjs/libs/kafka/kafka.cjs.map +0 -1
  221. package/dist/cjs/libs/kafka/kafka.d.ts +0 -3
  222. package/dist/cjs/libs/kafka/kafka.d.ts.map +0 -1
  223. package/dist/cjs/libs/kafka/producer.cjs +0 -48
  224. package/dist/cjs/libs/kafka/producer.cjs.map +0 -1
  225. package/dist/cjs/libs/kafka/producer.d.ts +0 -11
  226. package/dist/cjs/libs/kafka/producer.d.ts.map +0 -1
  227. package/dist/cjs/libs/logger/config.cjs +0 -8
  228. package/dist/cjs/libs/logger/config.cjs.map +0 -1
  229. package/dist/cjs/libs/logger/config.d.ts +0 -5
  230. package/dist/cjs/libs/logger/config.d.ts.map +0 -1
  231. package/dist/cjs/libs/s3/config.cjs +0 -10
  232. package/dist/cjs/libs/s3/config.cjs.map +0 -1
  233. package/dist/cjs/libs/s3/config.d.ts +0 -7
  234. package/dist/cjs/libs/s3/config.d.ts.map +0 -1
  235. package/dist/cjs/services/KafkaService.cjs +0 -122
  236. package/dist/cjs/services/KafkaService.cjs.map +0 -1
  237. package/dist/cjs/services/KafkaService.d.ts +0 -35
  238. package/dist/cjs/services/KafkaService.d.ts.map +0 -1
  239. package/dist/esm/helpers/SetupHelper.d.ts +0 -5
  240. package/dist/esm/helpers/SetupHelper.d.ts.map +0 -1
  241. package/dist/esm/helpers/SetupHelper.js +0 -32
  242. package/dist/esm/helpers/SetupHelper.js.map +0 -1
  243. package/dist/esm/libs/kafka/config.d.ts +0 -5
  244. package/dist/esm/libs/kafka/config.d.ts.map +0 -1
  245. package/dist/esm/libs/kafka/config.js +0 -5
  246. package/dist/esm/libs/kafka/config.js.map +0 -1
  247. package/dist/esm/libs/kafka/consumer.d.ts +0 -16
  248. package/dist/esm/libs/kafka/consumer.d.ts.map +0 -1
  249. package/dist/esm/libs/kafka/consumer.js +0 -125
  250. package/dist/esm/libs/kafka/consumer.js.map +0 -1
  251. package/dist/esm/libs/kafka/index.d.ts +0 -3
  252. package/dist/esm/libs/kafka/index.d.ts.map +0 -1
  253. package/dist/esm/libs/kafka/index.js +0 -3
  254. package/dist/esm/libs/kafka/index.js.map +0 -1
  255. package/dist/esm/libs/kafka/kafka.d.ts +0 -3
  256. package/dist/esm/libs/kafka/kafka.d.ts.map +0 -1
  257. package/dist/esm/libs/kafka/kafka.js +0 -24
  258. package/dist/esm/libs/kafka/kafka.js.map +0 -1
  259. package/dist/esm/libs/kafka/producer.d.ts +0 -11
  260. package/dist/esm/libs/kafka/producer.d.ts.map +0 -1
  261. package/dist/esm/libs/kafka/producer.js +0 -45
  262. package/dist/esm/libs/kafka/producer.js.map +0 -1
  263. package/dist/esm/libs/logger/config.d.ts +0 -5
  264. package/dist/esm/libs/logger/config.d.ts.map +0 -1
  265. package/dist/esm/libs/logger/config.js +0 -5
  266. package/dist/esm/libs/logger/config.js.map +0 -1
  267. package/dist/esm/libs/s3/config.d.ts +0 -7
  268. package/dist/esm/libs/s3/config.d.ts.map +0 -1
  269. package/dist/esm/libs/s3/config.js +0 -7
  270. package/dist/esm/libs/s3/config.js.map +0 -1
  271. package/dist/esm/services/KafkaService.d.ts +0 -35
  272. package/dist/esm/services/KafkaService.d.ts.map +0 -1
  273. package/dist/esm/services/KafkaService.js +0 -123
  274. package/dist/esm/services/KafkaService.js.map +0 -1
@@ -0,0 +1,762 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const ChatProcessor_1 = require("./ChatProcessor.cjs");
5
+ const ai_agent_types_1 = require("@multiplayer-app/ai-agent-types");
6
+ const ConfigStore_1 = require("../store/ConfigStore.cjs");
7
+ const ModelStore_1 = require("../store/ModelStore.cjs");
8
+ const config_1 = require("../config.cjs");
9
+ const s3_1 = require("../libs/s3/index.cjs");
10
+ const zod_1 = require("zod");
11
+ (0, vitest_1.describe)('ChatProcessor.streamMessage', () => {
12
+ let chatProcessor;
13
+ let mockChatRepository;
14
+ let mockMessageRepository;
15
+ let mockAgentConfigRepository;
16
+ let mockArtifactStore;
17
+ let mockAgentStore;
18
+ let mockSocketService;
19
+ let mockActivityRepository;
20
+ let configStore;
21
+ let capturedOptions;
22
+ const userId = 'test-user-id';
23
+ (0, vitest_1.beforeEach)(() => {
24
+ vitest_1.vi.clearAllMocks();
25
+ capturedOptions = undefined;
26
+ ModelStore_1.ModelStore.getInstance().setModels([
27
+ { id: 'openai/gpt-4o', provider: 'openai', label: 'GPT-4o' }
28
+ ]);
29
+ // Mock repositories
30
+ mockChatRepository = {
31
+ findById: vitest_1.vi.fn(),
32
+ create: vitest_1.vi.fn(),
33
+ update: vitest_1.vi.fn(),
34
+ delete: vitest_1.vi.fn(),
35
+ findWithMessages: vitest_1.vi.fn(),
36
+ };
37
+ mockMessageRepository = {
38
+ findByChatId: vitest_1.vi.fn().mockResolvedValue([]),
39
+ findByChatIdPaginated: vitest_1.vi.fn().mockResolvedValue({ messages: [], hasMore: false }),
40
+ findById: vitest_1.vi.fn(),
41
+ create: vitest_1.vi.fn(),
42
+ deleteByChatId: vitest_1.vi.fn(),
43
+ update: vitest_1.vi.fn().mockImplementation(async (id, updates) => ({
44
+ id,
45
+ chat: 'test-chat-id',
46
+ role: ai_agent_types_1.MessageRole.Assistant,
47
+ content: '',
48
+ createdAt: new Date().toISOString(),
49
+ ...updates
50
+ })),
51
+ };
52
+ mockAgentConfigRepository = {
53
+ findByUserIdAndAgentName: vitest_1.vi.fn().mockResolvedValue(null),
54
+ };
55
+ // Mock artifact store
56
+ mockArtifactStore = {
57
+ listArtifacts: vitest_1.vi.fn().mockReturnValue([]),
58
+ deleteArtifacts: vitest_1.vi.fn(),
59
+ };
60
+ // Mock agent store
61
+ mockAgentStore = {
62
+ registerAgentProcess: vitest_1.vi.fn().mockReturnValue({
63
+ signal: new AbortController().signal,
64
+ }),
65
+ shareAgentProcessEvent: vitest_1.vi.fn(),
66
+ addListener: vitest_1.vi.fn(),
67
+ removeListener: vitest_1.vi.fn(),
68
+ };
69
+ // Mock socket service
70
+ mockSocketService = {
71
+ emitMessageUpdate: vitest_1.vi.fn(),
72
+ emitChatUpdate: vitest_1.vi.fn(),
73
+ };
74
+ // Setup config store with agent config
75
+ configStore = ConfigStore_1.ConfigStore.getInstance();
76
+ configStore.clear();
77
+ const agentConfig = {
78
+ name: 'test-agent',
79
+ description: 'Test agent for property verification',
80
+ defaultModel: 'openai/gpt-4o',
81
+ systemPrompt: 'You are a helpful assistant',
82
+ temperature: 0.8,
83
+ maxOutputTokens: 3000,
84
+ topP: 0.95,
85
+ topK: 50,
86
+ presencePenalty: 0.6,
87
+ frequencyPenalty: 0.4,
88
+ stopSequences: ['\n\n', '---', 'END'],
89
+ seed: 42,
90
+ tools: [],
91
+ toolChoice: 'auto',
92
+ };
93
+ // Use addAgent to bypass ConfigHelper conversion
94
+ configStore.addAgent(['test-context'], agentConfig);
95
+ const config = config_1.ConfigProvider.getInstance().getConfig();
96
+ const s3Lib = new s3_1.S3Lib(config.s3);
97
+ mockActivityRepository = {
98
+ create: vitest_1.vi.fn().mockResolvedValue({
99
+ id: 'activity-1',
100
+ ownerId: 'test-chat-id',
101
+ groupId: 'test-chat-id',
102
+ name: 'Message processing',
103
+ tenants: { userId: 'test-user-id' },
104
+ sourceId: 'user-msg-1',
105
+ sourceType: 'AgentMessage',
106
+ metadata: {}
107
+ }),
108
+ update: vitest_1.vi.fn().mockResolvedValue({
109
+ id: 'activity-1',
110
+ ownerId: 'test-chat-id',
111
+ groupId: 'test-chat-id',
112
+ name: 'Message processing',
113
+ tenants: { userId: 'test-user-id' },
114
+ sourceId: 'user-msg-1',
115
+ sourceType: 'AgentMessage',
116
+ metadata: {}
117
+ }),
118
+ deleteByGroupId: vitest_1.vi.fn().mockResolvedValue(1),
119
+ getGroupedMetadataByParentId: vitest_1.vi.fn().mockResolvedValue({}),
120
+ updateMetadata: vitest_1.vi.fn().mockResolvedValue({
121
+ id: 'activity-1',
122
+ metadata: {}
123
+ }),
124
+ };
125
+ // Create ChatProcessor
126
+ chatProcessor = new ChatProcessor_1.ChatProcessor({
127
+ chatRepository: mockChatRepository,
128
+ messageRepository: mockMessageRepository,
129
+ agentConfigRepository: mockAgentConfigRepository,
130
+ artifactStore: mockArtifactStore,
131
+ s3Lib,
132
+ config,
133
+ socketService: mockSocketService,
134
+ agentStore: mockAgentStore,
135
+ activityRepository: mockActivityRepository
136
+ });
137
+ });
138
+ (0, vitest_1.it)('should delete chat, messages, activities, and artifacts', async () => {
139
+ mockChatRepository.delete.mockResolvedValue(true);
140
+ await chatProcessor.deleteChat('chat-1');
141
+ (0, vitest_1.expect)(mockChatRepository.delete).toHaveBeenCalledWith('chat-1');
142
+ (0, vitest_1.expect)(mockMessageRepository.deleteByChatId).toHaveBeenCalledWith('chat-1');
143
+ (0, vitest_1.expect)(mockActivityRepository.deleteByGroupId).toHaveBeenCalledWith('chat-1');
144
+ (0, vitest_1.expect)(mockArtifactStore.deleteArtifacts).toHaveBeenCalledWith('chat-1');
145
+ });
146
+ (0, vitest_1.it)('should throw when chat does not exist and skip cleanup', async () => {
147
+ mockChatRepository.delete.mockResolvedValue(false);
148
+ await (0, vitest_1.expect)(chatProcessor.deleteChat('missing-chat')).rejects.toThrow('Chat not found');
149
+ (0, vitest_1.expect)(mockMessageRepository.deleteByChatId).not.toHaveBeenCalled();
150
+ (0, vitest_1.expect)(mockActivityRepository.deleteByGroupId).not.toHaveBeenCalled();
151
+ (0, vitest_1.expect)(mockArtifactStore.deleteArtifacts).not.toHaveBeenCalled();
152
+ });
153
+ (0, vitest_1.it)('should pass all agent properties correctly to streamAssistantResponse', async () => {
154
+ const chat = {
155
+ id: 'test-chat-id',
156
+ userId,
157
+ contextKey: 'test-context',
158
+ type: ai_agent_types_1.ChatType.Chat,
159
+ status: ai_agent_types_1.AgentStatus.Processing,
160
+ createdAt: new Date().toISOString(),
161
+ updatedAt: new Date().toISOString(),
162
+ };
163
+ const payload = {
164
+ chatId: chat.id,
165
+ content: 'Hello, test message',
166
+ contextKey: 'test-context',
167
+ };
168
+ // Mock chat repository
169
+ mockChatRepository.findById.mockResolvedValue(chat);
170
+ // Mock message creation
171
+ const userMessage = {
172
+ id: 'user-msg-1',
173
+ chat: chat.id,
174
+ role: ai_agent_types_1.MessageRole.User,
175
+ content: payload.content,
176
+ createdAt: new Date().toISOString(),
177
+ };
178
+ const assistantMessage = {
179
+ id: 'assistant-msg-1',
180
+ chat: chat.id,
181
+ role: ai_agent_types_1.MessageRole.Assistant,
182
+ content: '',
183
+ createdAt: new Date().toISOString(),
184
+ agentName: 'test-agent',
185
+ };
186
+ mockMessageRepository.create
187
+ .mockResolvedValueOnce(userMessage)
188
+ .mockResolvedValueOnce(assistantMessage);
189
+ // Mock stream to prevent actual API calls
190
+ const mockStream = {
191
+ fullStream: (async function* () {
192
+ yield { type: 'finish', finishReason: 'stop', text: 'Test response' };
193
+ })(),
194
+ };
195
+ // Capture options passed to streamAssistantResponse
196
+ const aiHelper = chatProcessor.aiHelper;
197
+ vitest_1.vi.spyOn(aiHelper, 'streamAssistantResponse').mockImplementation(async (messages, signal, options) => {
198
+ capturedOptions = options;
199
+ return mockStream;
200
+ });
201
+ // Call streamMessage
202
+ await chatProcessor.streamMessage(chat, payload);
203
+ // Verify options were captured
204
+ (0, vitest_1.expect)(capturedOptions).toBeDefined();
205
+ // Verify all agent properties are present in the options
206
+ if (capturedOptions) {
207
+ (0, vitest_1.expect)(capturedOptions).toHaveProperty('name', 'test-agent');
208
+ (0, vitest_1.expect)(capturedOptions).toHaveProperty('system', 'You are a helpful assistant');
209
+ (0, vitest_1.expect)(capturedOptions).toHaveProperty('temperature', 0.8);
210
+ (0, vitest_1.expect)(capturedOptions).toHaveProperty('maxOutputTokens', 3000);
211
+ (0, vitest_1.expect)(capturedOptions).toHaveProperty('topP', 0.95);
212
+ (0, vitest_1.expect)(capturedOptions).toHaveProperty('topK', 50);
213
+ (0, vitest_1.expect)(capturedOptions).toHaveProperty('presencePenalty', 0.6);
214
+ (0, vitest_1.expect)(capturedOptions).toHaveProperty('frequencyPenalty', 0.4);
215
+ (0, vitest_1.expect)(capturedOptions).toHaveProperty('stopSequences', ['\n\n', '---', 'END']);
216
+ (0, vitest_1.expect)(capturedOptions).toHaveProperty('seed', 42);
217
+ (0, vitest_1.expect)(capturedOptions).toHaveProperty('toolChoice', 'auto');
218
+ (0, vitest_1.expect)(capturedOptions).toHaveProperty('tools');
219
+ }
220
+ });
221
+ (0, vitest_1.it)('should handle optional agent properties when not provided', async () => {
222
+ configStore.clear();
223
+ const minimalAgentConfig = {
224
+ name: 'minimal-agent',
225
+ description: 'Minimal agent config',
226
+ systemPrompt: 'You are helpful',
227
+ tools: [],
228
+ };
229
+ configStore.addAgent(['test-context'], minimalAgentConfig);
230
+ const chat = {
231
+ id: 'test-chat-id-2',
232
+ userId,
233
+ contextKey: 'test-context',
234
+ type: ai_agent_types_1.ChatType.Chat,
235
+ status: ai_agent_types_1.AgentStatus.Processing,
236
+ createdAt: new Date().toISOString(),
237
+ updatedAt: new Date().toISOString(),
238
+ };
239
+ const payload = {
240
+ chatId: chat.id,
241
+ content: 'Test',
242
+ contextKey: 'test-context',
243
+ };
244
+ mockChatRepository.findById.mockResolvedValue(chat);
245
+ const userMessage = {
246
+ id: 'user-msg-2',
247
+ chat: chat.id,
248
+ role: ai_agent_types_1.MessageRole.User,
249
+ content: payload.content,
250
+ createdAt: new Date().toISOString(),
251
+ };
252
+ const assistantMessage = {
253
+ id: 'assistant-msg-2',
254
+ chat: chat.id,
255
+ role: ai_agent_types_1.MessageRole.Assistant,
256
+ content: '',
257
+ createdAt: new Date().toISOString(),
258
+ agentName: 'minimal-agent',
259
+ };
260
+ mockMessageRepository.create
261
+ .mockResolvedValueOnce(userMessage)
262
+ .mockResolvedValueOnce(assistantMessage);
263
+ const mockStream = {
264
+ fullStream: (async function* () {
265
+ yield { type: 'finish', finishReason: 'stop', text: 'Response' };
266
+ })(),
267
+ };
268
+ const aiHelper = chatProcessor.aiHelper;
269
+ vitest_1.vi.spyOn(aiHelper, 'streamAssistantResponse').mockImplementation(async (messages, signal, options) => {
270
+ capturedOptions = options;
271
+ return mockStream;
272
+ });
273
+ await chatProcessor.streamMessage(chat, payload);
274
+ // Verify required properties are present
275
+ (0, vitest_1.expect)(capturedOptions).toBeDefined();
276
+ if (capturedOptions) {
277
+ (0, vitest_1.expect)(capturedOptions).toHaveProperty('name', 'minimal-agent');
278
+ (0, vitest_1.expect)(capturedOptions).toHaveProperty('system', 'You are helpful');
279
+ (0, vitest_1.expect)(capturedOptions).toHaveProperty('tools');
280
+ }
281
+ });
282
+ (0, vitest_1.it)('should pass stopWhen condition when provided', async () => {
283
+ configStore.clear();
284
+ const stopWhenFn = vitest_1.vi.fn(() => false);
285
+ const agentConfigWithStopWhen = {
286
+ name: 'agent-with-stopwhen',
287
+ description: 'Agent with stopWhen',
288
+ systemPrompt: 'You are helpful',
289
+ tools: [],
290
+ stopWhen: stopWhenFn,
291
+ };
292
+ configStore.addAgent(['test-context'], agentConfigWithStopWhen);
293
+ const chat = {
294
+ id: 'test-chat-id-3',
295
+ userId,
296
+ contextKey: 'test-context',
297
+ type: ai_agent_types_1.ChatType.Chat,
298
+ status: ai_agent_types_1.AgentStatus.Processing,
299
+ createdAt: new Date().toISOString(),
300
+ updatedAt: new Date().toISOString(),
301
+ };
302
+ const payload = {
303
+ chatId: chat.id,
304
+ content: 'Test',
305
+ contextKey: 'test-context',
306
+ };
307
+ mockChatRepository.findById.mockResolvedValue(chat);
308
+ const userMessage = {
309
+ id: 'user-msg-3',
310
+ chat: chat.id,
311
+ role: ai_agent_types_1.MessageRole.User,
312
+ content: payload.content,
313
+ createdAt: new Date().toISOString(),
314
+ };
315
+ const assistantMessage = {
316
+ id: 'assistant-msg-3',
317
+ chat: chat.id,
318
+ role: ai_agent_types_1.MessageRole.Assistant,
319
+ content: '',
320
+ createdAt: new Date().toISOString(),
321
+ agentName: 'agent-with-stopwhen',
322
+ };
323
+ mockMessageRepository.create
324
+ .mockResolvedValueOnce(userMessage)
325
+ .mockResolvedValueOnce(assistantMessage);
326
+ const mockStream = {
327
+ fullStream: (async function* () {
328
+ yield { type: 'finish', finishReason: 'stop', text: 'Response' };
329
+ })(),
330
+ };
331
+ const aiHelper = chatProcessor.aiHelper;
332
+ vitest_1.vi.spyOn(aiHelper, 'streamAssistantResponse').mockImplementation(async (messages, signal, options) => {
333
+ capturedOptions = options;
334
+ return mockStream;
335
+ });
336
+ await chatProcessor.streamMessage(chat, payload);
337
+ // Verify stopWhen is passed
338
+ (0, vitest_1.expect)(capturedOptions).toBeDefined();
339
+ if (capturedOptions) {
340
+ (0, vitest_1.expect)(capturedOptions).toHaveProperty('stopWhen', stopWhenFn);
341
+ }
342
+ });
343
+ (0, vitest_1.it)('should merge only cost-related provider usage into stored activity metadata', async () => {
344
+ const chat = {
345
+ id: 'test-chat-id-usage',
346
+ userId,
347
+ contextKey: 'test-context',
348
+ type: ai_agent_types_1.ChatType.Chat,
349
+ status: ai_agent_types_1.AgentStatus.Processing,
350
+ createdAt: new Date().toISOString(),
351
+ updatedAt: new Date().toISOString(),
352
+ };
353
+ await chatProcessor.storeStepActivity({
354
+ chat,
355
+ stepResult: {
356
+ finishReason: 'stop',
357
+ usage: {
358
+ inputTokens: 205,
359
+ outputTokens: 3,
360
+ totalTokens: 209,
361
+ inputTokenDetails: { cacheReadTokens: 0 },
362
+ },
363
+ response: {
364
+ timestamp: new Date().toISOString(),
365
+ modelId: 'openai/gpt-4o',
366
+ },
367
+ providerMetadata: {
368
+ openrouter: {
369
+ provider: 'OpenAI',
370
+ usage: {
371
+ promptTokens: 205,
372
+ promptTokensDetails: { cachedTokens: 0 },
373
+ completionTokens: 3,
374
+ totalTokens: 208,
375
+ cost: 0.0005425,
376
+ costDetails: {
377
+ upstreamInferenceCost: 0.0005425,
378
+ },
379
+ },
380
+ },
381
+ },
382
+ },
383
+ name: 'titleGeneration',
384
+ sourceId: chat.id,
385
+ sourceType: 'Chat',
386
+ });
387
+ (0, vitest_1.expect)(mockActivityRepository.create).toHaveBeenCalledTimes(1);
388
+ const [activityPayload] = mockActivityRepository.create.mock.calls[0];
389
+ (0, vitest_1.expect)(activityPayload.metadata.usage).toMatchObject({
390
+ inputTokens: 205,
391
+ outputTokens: 3,
392
+ totalTokens: 209,
393
+ inputTokenDetails: { cacheReadTokens: 0 },
394
+ cost: 0.0005425,
395
+ costDetails: { upstreamInferenceCost: 0.0005425 },
396
+ });
397
+ (0, vitest_1.expect)(activityPayload.metadata.usage.promptTokens).toBeUndefined();
398
+ (0, vitest_1.expect)(activityPayload.metadata.usage.completionTokens).toBeUndefined();
399
+ (0, vitest_1.expect)(activityPayload.metadata.usage.promptTokensDetails).toBeUndefined();
400
+ });
401
+ });
402
+ (0, vitest_1.describe)('ChatProcessor.getMessages', () => {
403
+ let chatProcessor;
404
+ let mockChatRepository;
405
+ let mockMessageRepository;
406
+ let mockAgentConfigRepository;
407
+ let mockActivityRepository;
408
+ (0, vitest_1.beforeEach)(() => {
409
+ vitest_1.vi.clearAllMocks();
410
+ mockChatRepository = { findById: vitest_1.vi.fn() };
411
+ mockMessageRepository = {
412
+ findByChatIdPaginated: vitest_1.vi.fn().mockResolvedValue({ messages: [], hasMore: false }),
413
+ };
414
+ mockAgentConfigRepository = {
415
+ findByUserIdAndAgentName: vitest_1.vi.fn().mockResolvedValue(null),
416
+ };
417
+ mockActivityRepository = {
418
+ create: vitest_1.vi.fn(),
419
+ update: vitest_1.vi.fn(),
420
+ deleteByGroupId: vitest_1.vi.fn(),
421
+ };
422
+ const config = config_1.ConfigProvider.getInstance().getConfig();
423
+ const s3Lib = new s3_1.S3Lib(config.s3);
424
+ chatProcessor = new ChatProcessor_1.ChatProcessor({
425
+ chatRepository: mockChatRepository,
426
+ messageRepository: mockMessageRepository,
427
+ agentConfigRepository: mockAgentConfigRepository,
428
+ artifactStore: { listArtifacts: vitest_1.vi.fn().mockReturnValue([]), deleteArtifacts: vitest_1.vi.fn() },
429
+ s3Lib,
430
+ config,
431
+ socketService: { emitMessageUpdate: vitest_1.vi.fn(), emitChatUpdate: vitest_1.vi.fn() },
432
+ agentStore: {
433
+ registerAgentProcess: vitest_1.vi.fn().mockReturnValue({ signal: new AbortController().signal }),
434
+ shareAgentProcessEvent: vitest_1.vi.fn(),
435
+ addListener: vitest_1.vi.fn(),
436
+ removeListener: vitest_1.vi.fn(),
437
+ },
438
+ activityRepository: mockActivityRepository,
439
+ });
440
+ const aiHelper = chatProcessor.aiHelper;
441
+ vitest_1.vi.spyOn(aiHelper, 'getAgentOptions').mockResolvedValue({
442
+ name: 'test-agent',
443
+ tools: {
444
+ test_tool: {
445
+ inputSchema: zod_1.z.object({
446
+ foo: zod_1.z.any().optional(),
447
+ count: zod_1.z.any().optional(),
448
+ x: zod_1.z.any().optional(),
449
+ }),
450
+ },
451
+ },
452
+ });
453
+ });
454
+ (0, vitest_1.it)('returns messages page when chat exists', async () => {
455
+ const chatId = 'chat-1';
456
+ const messages = [
457
+ {
458
+ id: 'm1',
459
+ chat: chatId,
460
+ role: ai_agent_types_1.MessageRole.User,
461
+ content: 'Hi',
462
+ createdAt: new Date().toISOString(),
463
+ },
464
+ ];
465
+ mockChatRepository.findById.mockResolvedValue({ id: chatId });
466
+ mockMessageRepository.findByChatIdPaginated.mockResolvedValue({
467
+ messages,
468
+ hasMore: true,
469
+ });
470
+ const result = await chatProcessor.getMessages(chatId, { limit: 30 });
471
+ (0, vitest_1.expect)(result).toEqual({ messages, hasMore: true });
472
+ (0, vitest_1.expect)(mockMessageRepository.findByChatIdPaginated).toHaveBeenCalledWith(chatId, {
473
+ limit: 30,
474
+ before: undefined,
475
+ });
476
+ });
477
+ (0, vitest_1.it)('throws when chat not found', async () => {
478
+ mockChatRepository.findById.mockResolvedValue(null);
479
+ await (0, vitest_1.expect)(chatProcessor.getMessages('missing-chat')).rejects.toThrow('Chat not found');
480
+ (0, vitest_1.expect)(mockMessageRepository.findByChatIdPaginated).not.toHaveBeenCalled();
481
+ });
482
+ });
483
+ (0, vitest_1.describe)('ChatProcessor.updateToolCall', () => {
484
+ let chatProcessor;
485
+ let mockChatRepository;
486
+ let mockMessageRepository;
487
+ let mockAgentConfigRepository;
488
+ let mockActivityRepository;
489
+ let mockSocketService;
490
+ (0, vitest_1.beforeEach)(() => {
491
+ vitest_1.vi.clearAllMocks();
492
+ mockChatRepository = {
493
+ findById: vitest_1.vi.fn(),
494
+ update: vitest_1.vi.fn(),
495
+ };
496
+ mockMessageRepository = {
497
+ findById: vitest_1.vi.fn(),
498
+ updateToolCall: vitest_1.vi.fn(),
499
+ };
500
+ mockAgentConfigRepository = {
501
+ findByUserIdAndAgentName: vitest_1.vi.fn().mockResolvedValue(null),
502
+ };
503
+ mockActivityRepository = {
504
+ create: vitest_1.vi.fn(),
505
+ update: vitest_1.vi.fn(),
506
+ deleteByGroupId: vitest_1.vi.fn(),
507
+ };
508
+ mockSocketService = {
509
+ emitMessageUpdate: vitest_1.vi.fn(),
510
+ emitChatUpdate: vitest_1.vi.fn(),
511
+ };
512
+ const config = config_1.ConfigProvider.getInstance().getConfig();
513
+ const s3Lib = new s3_1.S3Lib(config.s3);
514
+ chatProcessor = new ChatProcessor_1.ChatProcessor({
515
+ chatRepository: mockChatRepository,
516
+ messageRepository: mockMessageRepository,
517
+ agentConfigRepository: mockAgentConfigRepository,
518
+ artifactStore: { listArtifacts: vitest_1.vi.fn().mockReturnValue([]), deleteArtifacts: vitest_1.vi.fn() },
519
+ s3Lib,
520
+ config,
521
+ socketService: mockSocketService,
522
+ agentStore: {
523
+ registerAgentProcess: vitest_1.vi.fn().mockReturnValue({ signal: new AbortController().signal }),
524
+ shareAgentProcessEvent: vitest_1.vi.fn(),
525
+ addListener: vitest_1.vi.fn(),
526
+ removeListener: vitest_1.vi.fn(),
527
+ },
528
+ activityRepository: mockActivityRepository,
529
+ });
530
+ });
531
+ (0, vitest_1.it)('updates targeted tool call input and emits update', async () => {
532
+ const chatId = 'chat-1';
533
+ const messageId = 'message-1';
534
+ const toolCallId = 'tool-call-1';
535
+ const userId = 'user-1';
536
+ const updatedInput = { foo: 'bar', count: 1 };
537
+ const now = new Date().toISOString();
538
+ mockChatRepository.findById.mockResolvedValue({
539
+ id: chatId,
540
+ userId,
541
+ });
542
+ mockMessageRepository.findById.mockResolvedValue({
543
+ id: messageId,
544
+ chat: chatId,
545
+ role: ai_agent_types_1.MessageRole.Assistant,
546
+ content: '',
547
+ createdAt: now,
548
+ toolCalls: [
549
+ {
550
+ id: toolCallId,
551
+ name: 'test_tool',
552
+ input: { foo: 'old' },
553
+ status: ai_agent_types_1.AgentToolCallStatus.Pending,
554
+ },
555
+ ],
556
+ });
557
+ mockMessageRepository.updateToolCall.mockResolvedValue({
558
+ id: messageId,
559
+ chat: chatId,
560
+ role: ai_agent_types_1.MessageRole.Assistant,
561
+ content: '',
562
+ createdAt: now,
563
+ toolCalls: [
564
+ {
565
+ id: toolCallId,
566
+ name: 'test_tool',
567
+ input: updatedInput,
568
+ status: ai_agent_types_1.AgentToolCallStatus.Pending,
569
+ },
570
+ ],
571
+ });
572
+ const aiHelper = chatProcessor.aiHelper;
573
+ vitest_1.vi.spyOn(aiHelper, 'getAgentOptions').mockResolvedValue({
574
+ name: 'test-agent',
575
+ tools: {
576
+ test_tool: {
577
+ inputSchema: zod_1.z.object({
578
+ foo: zod_1.z.any().optional(),
579
+ count: zod_1.z.any().optional(),
580
+ }),
581
+ },
582
+ },
583
+ });
584
+ const result = await chatProcessor.updateToolCall({
585
+ chatId,
586
+ messageId,
587
+ toolCallId,
588
+ input: updatedInput,
589
+ excludeSocketId: 'socket-1',
590
+ });
591
+ (0, vitest_1.expect)(mockMessageRepository.updateToolCall).toHaveBeenCalledWith(messageId, toolCallId, {
592
+ input: updatedInput,
593
+ });
594
+ (0, vitest_1.expect)(mockChatRepository.update).toHaveBeenCalledWith(chatId, vitest_1.expect.objectContaining({ updatedAt: vitest_1.expect.any(String) }));
595
+ (0, vitest_1.expect)(mockSocketService.emitMessageUpdate).toHaveBeenCalledWith(userId, result, 'socket-1');
596
+ (0, vitest_1.expect)(result.toolCalls?.[0].input).toEqual(updatedInput);
597
+ });
598
+ (0, vitest_1.it)('updates targeted tool call output and status', async () => {
599
+ const chatId = 'chat-1';
600
+ const messageId = 'message-1';
601
+ const toolCallId = 'tool-call-1';
602
+ const userId = 'user-1';
603
+ const now = new Date().toISOString();
604
+ mockChatRepository.findById.mockResolvedValue({
605
+ id: chatId,
606
+ userId,
607
+ });
608
+ mockMessageRepository.findById.mockResolvedValue({
609
+ id: messageId,
610
+ chat: chatId,
611
+ role: ai_agent_types_1.MessageRole.Assistant,
612
+ content: '',
613
+ createdAt: now,
614
+ toolCalls: [
615
+ {
616
+ id: toolCallId,
617
+ name: 'test_tool',
618
+ input: { foo: 'old' },
619
+ status: ai_agent_types_1.AgentToolCallStatus.Running,
620
+ },
621
+ ],
622
+ });
623
+ mockMessageRepository.updateToolCall.mockResolvedValue({
624
+ id: messageId,
625
+ chat: chatId,
626
+ role: ai_agent_types_1.MessageRole.Assistant,
627
+ content: '',
628
+ createdAt: now,
629
+ toolCalls: [
630
+ {
631
+ id: toolCallId,
632
+ name: 'test_tool',
633
+ input: { foo: 'old' },
634
+ output: { result: 'ok' },
635
+ status: ai_agent_types_1.AgentToolCallStatus.Succeeded,
636
+ },
637
+ ],
638
+ });
639
+ const result = await chatProcessor.updateToolCall({
640
+ chatId,
641
+ messageId,
642
+ toolCallId,
643
+ output: { result: 'ok' },
644
+ status: ai_agent_types_1.AgentToolCallStatus.Succeeded,
645
+ excludeSocketId: 'socket-1',
646
+ });
647
+ (0, vitest_1.expect)(mockMessageRepository.updateToolCall).toHaveBeenCalledWith(messageId, toolCallId, {
648
+ output: { result: 'ok' },
649
+ status: ai_agent_types_1.AgentToolCallStatus.Succeeded,
650
+ });
651
+ (0, vitest_1.expect)(mockChatRepository.update).toHaveBeenCalledWith(chatId, vitest_1.expect.objectContaining({ updatedAt: vitest_1.expect.any(String) }));
652
+ (0, vitest_1.expect)(mockSocketService.emitMessageUpdate).toHaveBeenCalledWith(userId, result, 'socket-1');
653
+ (0, vitest_1.expect)(result.toolCalls?.[0].status).toBe(ai_agent_types_1.AgentToolCallStatus.Succeeded);
654
+ (0, vitest_1.expect)(result.toolCalls?.[0].output).toEqual({ result: 'ok' });
655
+ });
656
+ (0, vitest_1.it)('throws when message is not in chat', async () => {
657
+ mockChatRepository.findById.mockResolvedValue({ id: 'chat-1', userId: 'user-1' });
658
+ mockMessageRepository.findById.mockResolvedValue({
659
+ id: 'message-1',
660
+ chat: 'other-chat',
661
+ role: ai_agent_types_1.MessageRole.Assistant,
662
+ content: '',
663
+ createdAt: new Date().toISOString(),
664
+ toolCalls: [],
665
+ });
666
+ await (0, vitest_1.expect)(chatProcessor.updateToolCall({
667
+ chatId: 'chat-1',
668
+ messageId: 'message-1',
669
+ toolCallId: 'tool-call-1',
670
+ input: { x: 1 },
671
+ })).rejects.toThrow('Message not found or does not belong to this chat');
672
+ (0, vitest_1.expect)(mockMessageRepository.updateToolCall).not.toHaveBeenCalled();
673
+ });
674
+ (0, vitest_1.it)('throws when chat does not belong to user', async () => {
675
+ mockChatRepository.findById.mockResolvedValue({ id: 'chat-1', userId: 'owner-1' });
676
+ await (0, vitest_1.expect)(chatProcessor.updateToolCall({
677
+ chatId: 'chat-1',
678
+ messageId: 'message-1',
679
+ toolCallId: 'tool-call-1',
680
+ userId: 'other-user',
681
+ input: { x: 1 },
682
+ })).rejects.toThrow('Chat does not belong to this user');
683
+ (0, vitest_1.expect)(mockMessageRepository.findById).not.toHaveBeenCalled();
684
+ (0, vitest_1.expect)(mockMessageRepository.updateToolCall).not.toHaveBeenCalled();
685
+ });
686
+ (0, vitest_1.it)('throws when tool call does not exist in message', async () => {
687
+ mockChatRepository.findById.mockResolvedValue({ id: 'chat-1', userId: 'user-1' });
688
+ mockMessageRepository.findById.mockResolvedValue({
689
+ id: 'message-1',
690
+ chat: 'chat-1',
691
+ role: ai_agent_types_1.MessageRole.Assistant,
692
+ content: '',
693
+ createdAt: new Date().toISOString(),
694
+ toolCalls: [
695
+ {
696
+ id: 'other-tool-call',
697
+ name: 'test_tool',
698
+ input: {},
699
+ status: ai_agent_types_1.AgentToolCallStatus.Pending,
700
+ },
701
+ ],
702
+ });
703
+ await (0, vitest_1.expect)(chatProcessor.updateToolCall({
704
+ chatId: 'chat-1',
705
+ messageId: 'message-1',
706
+ toolCallId: 'tool-call-1',
707
+ input: { x: 1 },
708
+ })).rejects.toThrow('Tool call not found in message');
709
+ (0, vitest_1.expect)(mockMessageRepository.updateToolCall).not.toHaveBeenCalled();
710
+ });
711
+ (0, vitest_1.it)('throws when no tool call fields are provided', async () => {
712
+ await (0, vitest_1.expect)(chatProcessor.updateToolCall({
713
+ chatId: 'chat-1',
714
+ messageId: 'message-1',
715
+ toolCallId: 'tool-call-1',
716
+ })).rejects.toThrow('At least one of input, output, or status must be provided');
717
+ });
718
+ (0, vitest_1.it)('throws when input does not match tool schema', async () => {
719
+ const chatId = 'chat-1';
720
+ const messageId = 'message-1';
721
+ const toolCallId = 'tool-call-1';
722
+ mockChatRepository.findById.mockResolvedValue({
723
+ id: chatId,
724
+ userId: 'user-1',
725
+ });
726
+ mockMessageRepository.findById.mockResolvedValue({
727
+ id: messageId,
728
+ chat: chatId,
729
+ role: ai_agent_types_1.MessageRole.Assistant,
730
+ content: '',
731
+ createdAt: new Date().toISOString(),
732
+ toolCalls: [
733
+ {
734
+ id: toolCallId,
735
+ name: 'test_tool',
736
+ input: {},
737
+ status: ai_agent_types_1.AgentToolCallStatus.Pending,
738
+ },
739
+ ],
740
+ agentName: 'test-agent',
741
+ });
742
+ const aiHelper = chatProcessor.aiHelper;
743
+ vitest_1.vi.spyOn(aiHelper, 'getAgentOptions').mockResolvedValue({
744
+ name: 'test-agent',
745
+ tools: {
746
+ test_tool: {
747
+ inputSchema: zod_1.z.object({
748
+ x: zod_1.z.number(),
749
+ }),
750
+ },
751
+ },
752
+ });
753
+ await (0, vitest_1.expect)(chatProcessor.updateToolCall({
754
+ chatId,
755
+ messageId,
756
+ toolCallId,
757
+ input: { x: 'invalid' },
758
+ })).rejects.toThrow('Invalid tool input for "test_tool"');
759
+ (0, vitest_1.expect)(mockMessageRepository.updateToolCall).not.toHaveBeenCalled();
760
+ });
761
+ });
762
+ //# sourceMappingURL=ChatProcessor.test.js.map