@multiplayer-app/ai-agent-node 0.1.0-beta.5 → 0.1.0-beta.51

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
package/README.md CHANGED
@@ -419,7 +419,7 @@ const stream = await chatProcessor.createMessageStream({
419
419
  messageId: 'message-id',
420
420
  approvalId: 'approval-id',
421
421
  approved: true,
422
- reason: 'User approved'
422
+ userResponse: 'User approved'
423
423
  });
424
424
 
425
425
  // Or use streamMessage directly if you already have the chat object
@@ -429,7 +429,7 @@ await chatProcessor.streamMessage(chat, {
429
429
  messageId: 'message-id',
430
430
  approvalId: 'approval-id',
431
431
  approved: true,
432
- reason: 'User approved'
432
+ userResponse: 'User approved'
433
433
  });
434
434
  ```
435
435
 
@@ -1,47 +1,98 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.config = void 0;
4
- exports.getRedisUrl = getRedisUrl;
3
+ exports.ConfigProvider = void 0;
5
4
  require("dotenv/config");
5
+ function createDefaultConfig() {
6
+ return {
7
+ debug: false,
8
+ redis: {
9
+ host: 'localhost',
10
+ port: 6379,
11
+ },
12
+ ai: {
13
+ maxContextMessages: 10,
14
+ },
15
+ s3: {
16
+ bucket: 'ai-agent-attachments',
17
+ presignedUrlExpires: 120,
18
+ region: process.env.AWS_REGION || 'us-east-1',
19
+ },
20
+ fileProcessing: {
21
+ maxExtractedTextSize: 51200,
22
+ enableTextExtraction: true,
23
+ },
24
+ logger: {
25
+ nodeEnv: 'development',
26
+ appName: 'ai-agent-node',
27
+ logLevel: 'debug',
28
+ },
29
+ socket: {
30
+ path: undefined
31
+ },
32
+ };
33
+ }
6
34
  /**
7
- * Centralized configuration for the AI Agent Service
8
- * All environment variables are accessed through this file
35
+ * Deep merge utility function
36
+ * Merges source into target, with source values taking precedence
9
37
  */
10
- exports.config = {
11
- // Redis configuration
12
- redis: {
13
- url: process.env.REDIS_URL,
14
- host: process.env.REDIS_HOST ?? 'localhost',
15
- port: Number(process.env.REDIS_PORT ?? 6379),
16
- password: process.env.REDIS_PASSWORD,
17
- database: process.env.REDIS_DATABASE ? Number(process.env.REDIS_DATABASE) : undefined,
18
- },
19
- // AI Provider API Keys
20
- ai: {
21
- openaiApiKey: process.env.OPENAI_API_KEY,
22
- anthropicApiKey: process.env.ANTHROPIC_API_KEY,
23
- googleApiKey: process.env.GOOGLE_GENERATIVE_AI_API_KEY,
24
- openrouterApiKey: process.env.OPENROUTER_API_KEY,
25
- maxContextMessages: Number(process.env.MAX_CONTEXT_MESSAGES) || 10,
26
- defaultModel: process.env.DEFAULT_MODEL,
27
- },
28
- s3: {
29
- bucket: process.env.S3_ATTACHMENTS_BUCKET || 'ai-agent-attachments',
30
- },
31
- // Kafka configuration
32
- kafka: {
33
- groupId: process.env.KAFKA_GROUP_ID ?? 'ai-agent-node',
34
- chatTitleGenerationTopic: process.env.KAFKA_CHAT_TITLE_GENERATION_TOPIC ?? 'chat-title-generation',
35
- backgroundChatProcessingTopic: process.env.KAFKA_BACKGROUND_CHAT_PROCESSING_TOPIC ?? 'background-chat-processing',
36
- },
37
- };
38
+ function deepMerge(target, source) {
39
+ const result = { ...target };
40
+ for (const key in source) {
41
+ if (source[key] !== undefined) {
42
+ if (typeof source[key] === 'object' &&
43
+ source[key] !== null &&
44
+ !Array.isArray(source[key]) &&
45
+ typeof target[key] === 'object' &&
46
+ target[key] !== null &&
47
+ !Array.isArray(target[key])) {
48
+ // Recursively merge nested objects
49
+ result[key] = deepMerge(target[key], source[key]);
50
+ }
51
+ else {
52
+ // Override with source value
53
+ result[key] = source[key];
54
+ }
55
+ }
56
+ }
57
+ return result;
58
+ }
38
59
  /**
39
- * Get Redis connection URL
60
+ * ConfigProvider manages runtime configuration
61
+ * Allows setting config overrides through AIAgentService
40
62
  */
41
- function getRedisUrl() {
42
- if (exports.config.redis.url) {
43
- return exports.config.redis.url;
63
+ class ConfigProvider {
64
+ constructor() {
65
+ this.runtimeConfig = createDefaultConfig();
66
+ }
67
+ /**
68
+ * Get the singleton instance of ConfigProvider
69
+ */
70
+ static getInstance() {
71
+ if (!ConfigProvider.instance) {
72
+ ConfigProvider.instance = new ConfigProvider();
73
+ }
74
+ return ConfigProvider.instance;
75
+ }
76
+ /**
77
+ * Get the current runtime configuration
78
+ */
79
+ getConfig() {
80
+ return this.runtimeConfig;
81
+ }
82
+ /**
83
+ * Set configuration overrides
84
+ * Merges the provided overrides with existing config (deep merge)
85
+ * @param overrides - Partial config to override existing values
86
+ */
87
+ setConfig(overrides) {
88
+ this.runtimeConfig = deepMerge(this.runtimeConfig, overrides);
89
+ }
90
+ /**
91
+ * Reset configuration to defaults (from environment variables)
92
+ */
93
+ reset() {
94
+ this.runtimeConfig = createDefaultConfig();
44
95
  }
45
- return `redis://${exports.config.redis.host}:${exports.config.redis.port}`;
46
96
  }
97
+ exports.ConfigProvider = ConfigProvider;
47
98
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":";;;AAwCA,kCAKC;AA7CD,yBAAuB;AAEvB;;;GAGG;AAEU,QAAA,MAAM,GAAG;IACpB,sBAAsB;IACtB,KAAK,EAAE;QACL,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS;QAC1B,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,WAAW;QAC3C,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,IAAI,CAAC;QAC5C,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc;QACpC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS;KACtF;IAED,uBAAuB;IACvB,EAAE,EAAE;QACF,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc;QACxC,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB;QAC9C,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,4BAA4B;QACtD,gBAAgB,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB;QAChD,kBAAkB,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAI,EAAE;QAClE,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa;KACxC;IACD,EAAE,EAAE;QACF,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,sBAAsB;KACpE;IACD,sBAAsB;IACtB,KAAK,EAAE;QACL,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,eAAe;QACtD,wBAAwB,EAAE,OAAO,CAAC,GAAG,CAAC,iCAAiC,IAAI,uBAAuB;QAClG,6BAA6B,EAAE,OAAO,CAAC,GAAG,CAAC,sCAAsC,IAAI,4BAA4B;KAClH;CACO,CAAC;AAEX;;GAEG;AACH,SAAgB,WAAW;IACzB,IAAI,cAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QACrB,OAAO,cAAM,CAAC,KAAK,CAAC,GAAG,CAAC;IAC1B,CAAC;IACD,OAAO,WAAW,cAAM,CAAC,KAAK,CAAC,IAAI,IAAI,cAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;AAC7D,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":";;;AAAA,yBAAuB;AA2CvB,SAAS,mBAAmB;IAC1B,OAAO;QACL,KAAK,EAAE,KAAK;QACZ,KAAK,EAAE;YACL,IAAI,EAAE,WAAW;YACjB,IAAI,EAAG,IAAI;SACZ;QACD,EAAE,EAAE;YACF,kBAAkB,EAAE,EAAE;SACvB;QACD,EAAE,EAAE;YACF,MAAM,EAAE,sBAAsB;YAC9B,mBAAmB,EAAE,GAAG;YACxB,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,WAAW;SAC9C;QACD,cAAc,EAAE;YACd,oBAAoB,EAAE,KAAK;YAC3B,oBAAoB,EAAE,IAAI;SAC3B;QACD,MAAM,EAAE;YACN,OAAO,EAAE,aAAa;YACtB,OAAO,EAAE,eAAe;YACxB,QAAQ,EAAE,OAAO;SAClB;QACD,MAAM,EAAE;YACN,IAAI,EAAE,SAAS;SAChB;KACF,CAAC;AACJ,CAAC;AAGD;;;GAGG;AACH,SAAS,SAAS,CAAgC,MAAS,EAAE,MAAkB;IAC7E,MAAM,MAAM,GAAG,EAAE,GAAG,MAAM,EAAE,CAAC;IAE7B,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QACzB,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;YAC9B,IACI,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,QAAQ;gBAC/B,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI;gBACpB,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC3B,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,QAAQ;gBAC/B,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI;gBACpB,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAC7B,CAAC;gBACD,mCAAmC;gBACnC,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,GAAG,CAAQ,CAAC,CAAC;YAC3D,CAAC;iBAAM,CAAC;gBACN,6BAA6B;gBAC7B,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAQ,CAAC;YACnC,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAa,cAAc;IAIzB;QACE,IAAI,CAAC,aAAa,GAAG,mBAAmB,EAAE,CAAC;IAC7C,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,WAAW;QAChB,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,CAAC;YAC7B,cAAc,CAAC,QAAQ,GAAG,IAAI,cAAc,EAAE,CAAC;QACjD,CAAC;QACD,OAAO,cAAc,CAAC,QAAQ,CAAC;IACjC,CAAC;IAED;;OAEG;IACH,SAAS;QACP,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED;;;;OAIG;IACH,SAAS,CAAC,SAA0B;QAClC,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;IAChE,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,aAAa,GAAG,mBAAmB,EAAE,CAAC;IAC7C,CAAC;CACF;AAxCD,wCAwCC"}
@@ -3,33 +3,67 @@ import 'dotenv/config';
3
3
  * Centralized configuration for the AI Agent Service
4
4
  * All environment variables are accessed through this file
5
5
  */
6
- export declare const config: {
7
- readonly redis: {
8
- readonly url: string | undefined;
9
- readonly host: string;
10
- readonly port: number;
11
- readonly password: string | undefined;
12
- readonly database: number | undefined;
6
+ export interface Config {
7
+ debug: boolean;
8
+ redis: {
9
+ url?: string;
10
+ host?: string;
11
+ port?: number;
12
+ password?: string;
13
+ database?: number;
13
14
  };
14
- readonly ai: {
15
- readonly openaiApiKey: string | undefined;
16
- readonly anthropicApiKey: string | undefined;
17
- readonly googleApiKey: string | undefined;
18
- readonly openrouterApiKey: string | undefined;
19
- readonly maxContextMessages: number;
20
- readonly defaultModel: string | undefined;
15
+ ai: {
16
+ openaiApiKey?: string;
17
+ anthropicApiKey?: string;
18
+ googleApiKey?: string;
19
+ openrouterApiKey?: string;
20
+ maxContextMessages?: number;
21
+ defaultModel?: string;
21
22
  };
22
- readonly s3: {
23
- readonly bucket: string;
23
+ s3: {
24
+ bucket?: string;
25
+ host?: string;
26
+ presignedUrlExpires?: number;
27
+ region?: string;
24
28
  };
25
- readonly kafka: {
26
- readonly groupId: string;
27
- readonly chatTitleGenerationTopic: string;
28
- readonly backgroundChatProcessingTopic: string;
29
+ fileProcessing: {
30
+ maxExtractedTextSize?: number;
31
+ enableTextExtraction?: boolean;
29
32
  };
30
- };
33
+ logger: {
34
+ nodeEnv?: string;
35
+ appName?: string;
36
+ logLevel?: string;
37
+ };
38
+ socket: {
39
+ path?: string;
40
+ };
41
+ }
31
42
  /**
32
- * Get Redis connection URL
43
+ * ConfigProvider manages runtime configuration
44
+ * Allows setting config overrides through AIAgentService
33
45
  */
34
- export declare function getRedisUrl(): string;
46
+ export declare class ConfigProvider {
47
+ private static instance;
48
+ private runtimeConfig;
49
+ private constructor();
50
+ /**
51
+ * Get the singleton instance of ConfigProvider
52
+ */
53
+ static getInstance(): ConfigProvider;
54
+ /**
55
+ * Get the current runtime configuration
56
+ */
57
+ getConfig(): Config;
58
+ /**
59
+ * Set configuration overrides
60
+ * Merges the provided overrides with existing config (deep merge)
61
+ * @param overrides - Partial config to override existing values
62
+ */
63
+ setConfig(overrides: Partial<Config>): void;
64
+ /**
65
+ * Reset configuration to defaults (from environment variables)
66
+ */
67
+ reset(): void;
68
+ }
35
69
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC;AAEvB;;;GAGG;AAEH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;CA4BT,CAAC;AAEX;;GAEG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAKpC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC;AAEvB;;;GAGG;AACH,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE;QACL,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,EAAE,EAAE;QACF,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,EAAE,EAAE;QACF,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,cAAc,EAAE;QACd,oBAAoB,CAAC,EAAE,MAAM,CAAC;QAC9B,oBAAoB,CAAC,EAAE,OAAO,CAAC;KAChC,CAAC;IACF,MAAM,EAAE;QACN,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,MAAM,EAAE;QACN,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AA8DD;;;GAGG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAiB;IACxC,OAAO,CAAC,aAAa,CAAS;IAE9B,OAAO;IAIP;;OAEG;IACH,MAAM,CAAC,WAAW,IAAI,cAAc;IAOpC;;OAEG;IACH,SAAS,IAAI,MAAM;IAInB;;;;OAIG;IACH,SAAS,CAAC,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI;IAI3C;;OAEG;IACH,KAAK,IAAI,IAAI;CAGd"}
@@ -6,13 +6,42 @@ const services_1 = require("../services/index.cjs");
6
6
  const store_1 = require("../store/index.cjs");
7
7
  const logger_1 = require("../libs/logger/index.cjs");
8
8
  const store_2 = require("../store/index.cjs");
9
- const FileHelper_1 = require("./FileHelper.cjs");
10
9
  class AIHelper {
11
- static async convertUserMessage(msg, ignoreFileAttachments) {
12
- const userContent = [{
13
- type: "text",
10
+ constructor(fileHelper, config) {
11
+ this.fileHelper = fileHelper;
12
+ this.aiService = new services_1.AIService(store_1.ModelStore.getInstance(), config.ai);
13
+ }
14
+ getLanguageModelId(modelId) {
15
+ const model = this.aiService.getLanguageModelId(modelId);
16
+ return model.id;
17
+ }
18
+ clip(value, max) {
19
+ if (value.length <= max)
20
+ return value;
21
+ return `${value.slice(0, max)}…`;
22
+ }
23
+ renderContextValue(value, limits) {
24
+ if (value === null || value === undefined)
25
+ return '';
26
+ if (typeof value === 'string')
27
+ return this.clip(value, limits.maxString);
28
+ if (typeof value === 'number' || typeof value === 'boolean')
29
+ return String(value);
30
+ try {
31
+ const json = JSON.stringify(value);
32
+ return this.clip(json, limits.maxJson);
33
+ }
34
+ catch {
35
+ return '';
36
+ }
37
+ }
38
+ async convertUserMessage(msg, ignoreFileAttachments) {
39
+ const userContent = [
40
+ {
41
+ type: 'text',
14
42
  text: msg.content
15
- }];
43
+ }
44
+ ];
16
45
  const atts = msg.attachments ?? [];
17
46
  if (!atts.length) {
18
47
  return userContent;
@@ -23,21 +52,21 @@ class AIHelper {
23
52
  if (ignoreFileAttachments) {
24
53
  continue;
25
54
  }
26
- if ((0, FileHelper_1.isImage)(att)) {
27
- const image = await (0, FileHelper_1.prepareImageForVisionAPI)(att);
55
+ if (this.fileHelper.isImage(att)) {
56
+ const image = await this.fileHelper.prepareImageForVisionAPI(att);
28
57
  if (image) {
29
58
  userContent.push({
30
- type: "image",
59
+ type: 'image',
31
60
  image: image.image_url.url,
32
- mediaType: att.mimeType,
61
+ mediaType: att.mimeType
33
62
  });
34
63
  }
35
64
  }
36
65
  else {
37
- const fileText = await (0, FileHelper_1.extractTextFromDocument)(att);
66
+ const fileText = await this.fileHelper.extractTextFromDocument(att);
38
67
  if (fileText) {
39
68
  userContent.push({
40
- type: "text",
69
+ type: 'text',
41
70
  text: `${att.type}: ${att.name}(${att.mimeType})\n ${fileText}`
42
71
  });
43
72
  }
@@ -56,9 +85,8 @@ class AIHelper {
56
85
  if (title)
57
86
  lines.push(` title: ${title}`);
58
87
  if (selectedText) {
59
- const clipped = selectedText.length > 4000 ? `${selectedText.slice(0, 4000)}…` : selectedText;
60
88
  lines.push(' BEGIN_UNTRUSTED_WEB_SNIPPET');
61
- lines.push(clipped);
89
+ lines.push(this.clip(selectedText, 4000));
62
90
  lines.push(' END_UNTRUSTED_WEB_SNIPPET');
63
91
  }
64
92
  continue;
@@ -67,7 +95,7 @@ class AIHelper {
67
95
  const formId = typeof md?.formId === 'string' ? md.formId : undefined;
68
96
  const fieldName = typeof md?.fieldName === 'string' ? md.fieldName : undefined;
69
97
  const fieldLabel = typeof md?.fieldLabel === 'string' ? md.fieldLabel : undefined;
70
- const value = typeof md?.value === 'string' ? md.value : '';
98
+ const value = md?.value;
71
99
  const inputType = typeof md?.inputType === 'string' ? md.inputType : undefined;
72
100
  const options = Array.isArray(md?.options) ? md.options : [];
73
101
  if (formId)
@@ -84,15 +112,18 @@ class AIHelper {
84
112
  const l = typeof o?.label === 'string' ? o.label : '';
85
113
  if (!v && !l)
86
114
  return '';
87
- return l && v ? `${l} (${v})` : (l || v);
115
+ return l && v ? `${l} (${v})` : l || v;
88
116
  })
89
117
  .filter(Boolean)
90
118
  .join(', ');
91
119
  if (rendered)
92
120
  lines.push(` options: ${rendered}${options.length > 30 ? '…' : ''}`);
93
121
  }
94
- if (value)
95
- lines.push(` value: ${value.length > 1000 ? `${value.slice(0, 1000)}…` : value}`);
122
+ if (value !== undefined) {
123
+ const rendered = this.renderContextValue(value, { maxString: 1000, maxJson: 2500 });
124
+ if (rendered)
125
+ lines.push(` value: ${rendered}`);
126
+ }
96
127
  continue;
97
128
  }
98
129
  if (kind === 'formSnapshot') {
@@ -107,17 +138,17 @@ class AIHelper {
107
138
  for (const f of fields.slice(0, 50)) {
108
139
  const name = typeof f?.name === 'string' ? f.name : 'unknown';
109
140
  const label = typeof f?.label === 'string' ? f.label : undefined;
110
- const value = typeof f?.value === 'string' ? f.value : '';
141
+ const value = f?.value;
111
142
  const inputType = typeof f?.inputType === 'string' ? f.inputType : undefined;
112
143
  const options = Array.isArray(f?.options) ? f.options : [];
113
- const clipped = value.length > 1000 ? `${value.slice(0, 1000)}…` : value;
144
+ const clipped = this.renderContextValue(value, { maxString: 1000, maxJson: 2500 });
114
145
  const meta = [];
115
146
  if (inputType)
116
147
  meta.push(`type=${inputType}`);
117
148
  if ((inputType === 'select' || inputType === 'radio') && options.length) {
118
149
  const opts = options
119
150
  .slice(0, 20)
120
- .map((o) => typeof o?.value === 'string' ? o.value : '')
151
+ .map((o) => (typeof o?.value === 'string' ? o.value : ''))
121
152
  .filter(Boolean)
122
153
  .join('|');
123
154
  if (opts)
@@ -127,84 +158,118 @@ class AIHelper {
127
158
  }
128
159
  continue;
129
160
  }
161
+ if (kind === 'pageContext') {
162
+ const url = typeof md?.source?.url === 'string' ? md.source.url : att.url;
163
+ const title = typeof md?.title === 'string' ? md.title : undefined;
164
+ const route = typeof md?.source?.route === 'string' ? md.source.route : undefined;
165
+ const data = md?.data;
166
+ if (url)
167
+ lines.push(` url: ${url}`);
168
+ if (title)
169
+ lines.push(` title: ${title}`);
170
+ if (route)
171
+ lines.push(` route: ${route}`);
172
+ if (data && typeof data === 'object') {
173
+ const entries = Object.entries(data)
174
+ .filter(([k]) => typeof k === 'string' && k.length > 0)
175
+ .sort(([a], [b]) => a.localeCompare(b));
176
+ if (entries.length) {
177
+ lines.push(' data:');
178
+ const limits = { maxString: 1000, maxJson: 1500 };
179
+ for (const [k, v] of entries.slice(0, 40)) {
180
+ const rendered = this.renderContextValue(v, limits);
181
+ if (!rendered)
182
+ continue;
183
+ lines.push(` - ${k}: ${rendered}`);
184
+ }
185
+ if (entries.length > 40) {
186
+ lines.push(` - … (${entries.length - 40} more keys)`);
187
+ }
188
+ }
189
+ }
190
+ else if (data !== undefined) {
191
+ const rendered = this.renderContextValue(data, { maxString: 1000, maxJson: 2000 });
192
+ if (rendered)
193
+ lines.push(` data: ${rendered}`);
194
+ }
195
+ continue;
196
+ }
130
197
  // Custom kind: prefer summary, fall back to minimal JSON.
131
198
  const title = typeof md?.title === 'string' ? md.title : undefined;
132
199
  const summary = typeof md?.summary === 'string' ? md.summary : undefined;
133
200
  if (title)
134
201
  lines.push(` title: ${title}`);
135
202
  if (summary) {
136
- lines.push(` summary: ${summary.length > 4000 ? `${summary.slice(0, 4000)}…` : summary}`);
203
+ lines.push(` summary: ${this.clip(summary, 4000)}`);
137
204
  continue;
138
205
  }
139
206
  if (md?.data !== undefined) {
140
- const json = JSON.stringify(md.data);
141
- lines.push(` data: ${json.length > 2000 ? `${json.slice(0, 2000)}…` : json}`);
207
+ const rendered = this.renderContextValue(md.data, { maxString: 2000, maxJson: 5000 });
208
+ if (rendered)
209
+ lines.push(` data: ${rendered}`);
142
210
  }
143
211
  }
144
212
  if (lines.length) {
145
213
  userContent.push({
146
- type: "text",
214
+ type: 'text',
147
215
  text: `Context attachments (non-authoritative; user message is primary):\n ${lines.join('\n')}`
148
216
  });
149
217
  }
150
218
  return userContent;
151
219
  }
152
- static getAgentConfigs(contextKey) {
220
+ getAgentConfigs(contextKey) {
153
221
  const agents = store_2.ConfigStore.getInstance().getAgentsForContext(contextKey);
154
222
  if (!agents.length) {
155
223
  throw new Error(`Agent configs not found for context key: ${contextKey}`);
156
224
  }
157
225
  return agents;
158
226
  }
159
- static async getAgentOptions(params, options = {}) {
227
+ async getAgentOptions(params, options = {}) {
160
228
  const { contextKey, messages, modelId, context, agentName } = params;
161
229
  let agentConfig = store_2.ConfigStore.getInstance().getAgentConfigByName(agentName);
162
230
  if (contextKey && messages) {
163
- agentConfig = await AIHelper.selectAgentConfig(contextKey, messages);
231
+ agentConfig = await this.selectAgentConfig(contextKey, messages, options.onStepFinish);
164
232
  }
165
- const aiService = new services_1.AIService(store_1.ModelStore.getInstance());
166
- const agentOptions = aiService.getAgentOptions(agentConfig, modelId, context);
233
+ const agentOptions = this.aiService.getAgentOptions(agentConfig, modelId, context);
167
234
  return {
168
235
  ...agentOptions,
169
- ...options,
236
+ ...options
170
237
  };
171
238
  }
172
- static async selectAgentConfig(contextKey, messages) {
173
- const configs = AIHelper.getAgentConfigs(contextKey);
239
+ async selectAgentConfig(contextKey, messages, onStepFinish) {
240
+ const configs = this.getAgentConfigs(contextKey);
174
241
  if (configs.length === 1) {
175
242
  return configs[0];
176
243
  }
177
- const aiService = new services_1.AIService(store_1.ModelStore.getInstance());
178
- const systemPrompt = `Select the most appropriate agent for the given user prompt.
179
- Return only the agent name, no quotes or extra text.
180
- Available agents: ${JSON.stringify(configs.map(config => ({
244
+ const lastUsedAgent = messages.find((message) => message.agentName);
245
+ const systemPrompt = `Select the most appropriate agent for the given user message.
246
+ Return only the agent name, no quotes or extra text. ${lastUsedAgent ? `Latest Used agent: ${lastUsedAgent}` : ''}
247
+ Available agents: ${JSON.stringify(configs.map((config) => ({
181
248
  name: config.name,
182
249
  description: config.description,
183
- tools: config.tools.map(({ data }) => data.title)
250
+ tools: config.tools?.map(({ data }) => data.title)
184
251
  })))}`;
185
- const agentName = await aiService.generateText({
186
- messages,
252
+ const promptMessages = messages.length > 2 ? messages.slice(messages.length - 2) : messages;
253
+ const agentName = await this.aiService.generateText({
254
+ messages: await this.convertMessages(promptMessages, true),
187
255
  system: systemPrompt,
188
- temperature: 0.7,
189
- maxOutputTokens: 2000
256
+ temperature: 0.1,
257
+ maxOutputTokens: 2000,
258
+ onStepFinish
190
259
  });
191
- const agent = configs.find(config => config.name === agentName);
260
+ const agent = configs.find((config) => config.name === agentName);
192
261
  if (!agent) {
193
262
  // fallback, agent not found, grabbing first from the list
194
263
  return configs[0];
195
264
  }
196
265
  return agent;
197
266
  }
198
- static async getAssistantResponse(messages, signal, options = {}) {
267
+ async getAssistantResponse(messages, options = {}) {
199
268
  try {
200
- const aiService = new services_1.AIService(store_1.ModelStore.getInstance());
201
269
  const processedOptions = this.processToolChoice(options, messages);
202
- return aiService.generateText({
203
- temperature: 0.7,
204
- maxOutputTokens: 2000,
270
+ return this.aiService.generateText({
205
271
  ...processedOptions,
206
- messages: await AIHelper.convertMessages(messages),
207
- signal,
272
+ messages: await this.convertMessages(messages),
208
273
  });
209
274
  }
210
275
  catch (error) {
@@ -212,14 +277,12 @@ Available agents: ${JSON.stringify(configs.map(config => ({
212
277
  throw error;
213
278
  }
214
279
  }
215
- static processToolChoice(options, agentMessages) {
280
+ processToolChoice(options, agentMessages) {
216
281
  if (!options?.toolChoice) {
217
282
  return options || {};
218
283
  }
219
284
  // Find the latest assistant message
220
- const latestAssistantMessage = [...agentMessages]
221
- .reverse()
222
- .find(msg => msg.role === ai_agent_types_1.MessageRole.Assistant);
285
+ const latestAssistantMessage = [...agentMessages].reverse().find((msg) => msg.role === ai_agent_types_1.MessageRole.Assistant);
223
286
  // Handle 'required' toolChoice: if any tool was called, set to 'auto'
224
287
  if (options.toolChoice === 'required') {
225
288
  const anyToolWasCalled = (latestAssistantMessage?.toolCalls?.length ?? 0) > 0;
@@ -234,7 +297,7 @@ Available agents: ${JSON.stringify(configs.map(config => ({
234
297
  // Handle specific tool toolChoice: if that specific tool was called, set to 'auto'
235
298
  if (typeof options.toolChoice === 'object' && options.toolChoice.type === 'tool') {
236
299
  const toolName = options.toolChoice.toolName;
237
- const toolWasCalled = latestAssistantMessage?.toolCalls?.some(toolCall => toolCall.name === toolName) ?? false;
300
+ const toolWasCalled = latestAssistantMessage?.toolCalls?.some((toolCall) => toolCall.name === toolName) ?? false;
238
301
  if (toolWasCalled) {
239
302
  return {
240
303
  ...options,
@@ -244,11 +307,10 @@ Available agents: ${JSON.stringify(configs.map(config => ({
244
307
  }
245
308
  return options;
246
309
  }
247
- static async streamAssistantResponse(agentMessages, signal, options) {
248
- const aiService = new services_1.AIService(store_1.ModelStore.getInstance());
310
+ async streamAssistantResponse(agentMessages, signal, options) {
249
311
  const messages = await this.convertMessages(agentMessages);
250
312
  const processedOptions = this.processToolChoice(options, agentMessages);
251
- return aiService.streamText({
313
+ return this.aiService.streamText({
252
314
  messages,
253
315
  temperature: 0.7,
254
316
  maxOutputTokens: 2000,
@@ -256,7 +318,7 @@ Available agents: ${JSON.stringify(configs.map(config => ({
256
318
  ...processedOptions
257
319
  });
258
320
  }
259
- static async convertMessages(agentMessages, ignoreToolsAndAttachments = false) {
321
+ async convertMessages(agentMessages, ignoreToolsAndAttachments = false) {
260
322
  const result = [];
261
323
  for (const msg of agentMessages) {
262
324
  if (msg.role === ai_agent_types_1.MessageRole.User) {
@@ -279,12 +341,12 @@ Available agents: ${JSON.stringify(configs.map(config => ({
279
341
  };
280
342
  if (!ignoreToolsAndAttachments) {
281
343
  msg.toolCalls?.forEach((toolCall) => {
282
- if (toolCall.output) {
344
+ if (toolCall.output || toolCall.error) {
283
345
  assistantMessage.content.push({
284
346
  type: 'tool-call',
285
347
  toolCallId: toolCall.id,
286
348
  toolName: toolCall.name,
287
- input: toolCall.input
349
+ input: Object.keys(toolCall.input).length ? toolCall.input : { stub: 'stub' }, // todo: remove this workaround when openrouter will have new stable version(last tested: 2.2.3 has reasoning issues)
288
350
  });
289
351
  toolMessage.content.push({
290
352
  type: 'tool-result',
@@ -292,7 +354,7 @@ Available agents: ${JSON.stringify(configs.map(config => ({
292
354
  toolName: toolCall.name,
293
355
  output: {
294
356
  type: 'text',
295
- value: JSON.stringify(toolCall.output)
357
+ value: JSON.stringify(toolCall.output || { error: toolCall.error })
296
358
  }
297
359
  });
298
360
  }
@@ -308,13 +370,13 @@ Available agents: ${JSON.stringify(configs.map(config => ({
308
370
  }
309
371
  return result;
310
372
  }
311
- static async generateTitleForMessage(contextKey, messages) {
373
+ async generateTitleForMessage(contextKey, messages, onStepFinish) {
312
374
  try {
313
- const aiService = new services_1.AIService(store_1.ModelStore.getInstance());
314
375
  const systemPrompt = `Generate descriptive title 5 words maximum for a chat conversation. Return only the title, no quotes or extra text. If user question is opaque, assume it is related to ${contextKey} topic.`;
315
- return aiService.generateText({
316
- messages: await AIHelper.convertMessages(messages, true),
376
+ return this.aiService.generateText({
377
+ messages: await this.convertMessages(messages, true),
317
378
  system: systemPrompt,
379
+ onStepFinish
318
380
  });
319
381
  }
320
382
  catch (error) {