@dexto/core 1.3.0 → 1.4.0

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 (479) hide show
  1. package/README.md +17 -9
  2. package/dist/agent/DextoAgent.cjs +548 -207
  3. package/dist/agent/DextoAgent.d.ts +156 -33
  4. package/dist/agent/DextoAgent.d.ts.map +1 -1
  5. package/dist/agent/DextoAgent.js +545 -204
  6. package/dist/agent/agentCard.js +1 -1
  7. package/dist/agent/error-codes.cjs +1 -0
  8. package/dist/agent/error-codes.d.ts +2 -1
  9. package/dist/agent/error-codes.d.ts.map +1 -1
  10. package/dist/agent/error-codes.js +2 -1
  11. package/dist/agent/errors.cjs +13 -0
  12. package/dist/agent/errors.d.ts +4 -0
  13. package/dist/agent/errors.d.ts.map +1 -1
  14. package/dist/agent/errors.js +14 -1
  15. package/dist/agent/index.d.ts +1 -1
  16. package/dist/agent/index.d.ts.map +1 -1
  17. package/dist/agent/index.js +1 -1
  18. package/dist/agent/schemas.cjs +3 -0
  19. package/dist/agent/schemas.d.ts +92 -55
  20. package/dist/agent/schemas.d.ts.map +1 -1
  21. package/dist/agent/schemas.js +6 -2
  22. package/dist/agent/state-manager.cjs +5 -5
  23. package/dist/agent/state-manager.d.ts +4 -4
  24. package/dist/agent/state-manager.js +6 -6
  25. package/dist/agent/types.d.ts +24 -10
  26. package/dist/agent/types.d.ts.map +1 -1
  27. package/dist/approval/error-codes.js +1 -1
  28. package/dist/approval/errors.js +1 -1
  29. package/dist/approval/factory.js +1 -1
  30. package/dist/approval/index.js +1 -1
  31. package/dist/approval/manager.cjs +69 -3
  32. package/dist/approval/manager.d.ts +41 -3
  33. package/dist/approval/manager.d.ts.map +1 -1
  34. package/dist/approval/manager.js +70 -4
  35. package/dist/approval/schemas.cjs +18 -4
  36. package/dist/approval/schemas.d.ts +106 -32
  37. package/dist/approval/schemas.d.ts.map +1 -1
  38. package/dist/approval/schemas.js +19 -5
  39. package/dist/approval/types.d.ts +6 -0
  40. package/dist/approval/types.d.ts.map +1 -1
  41. package/dist/approval/types.js +1 -1
  42. package/dist/{chunk-C6A6W6XS.js → chunk-PTJYTZNU.js} +44 -1
  43. package/dist/{llm/tokenizer/default.cjs → context/compression/overflow.cjs} +20 -18
  44. package/dist/context/compression/overflow.d.ts +33 -0
  45. package/dist/context/compression/overflow.d.ts.map +1 -0
  46. package/dist/context/compression/overflow.js +19 -0
  47. package/dist/context/compression/reactive-overflow.cjs +201 -0
  48. package/dist/context/compression/reactive-overflow.d.ts +81 -0
  49. package/dist/context/compression/reactive-overflow.d.ts.map +1 -0
  50. package/dist/context/compression/reactive-overflow.js +178 -0
  51. package/dist/context/compression/types.d.ts +9 -7
  52. package/dist/context/compression/types.d.ts.map +1 -1
  53. package/dist/context/error-codes.cjs +3 -0
  54. package/dist/context/error-codes.d.ts +4 -1
  55. package/dist/context/error-codes.d.ts.map +1 -1
  56. package/dist/context/error-codes.js +4 -1
  57. package/dist/context/errors.cjs +28 -0
  58. package/dist/context/errors.d.ts +7 -0
  59. package/dist/context/errors.d.ts.map +1 -1
  60. package/dist/context/errors.js +29 -1
  61. package/dist/context/index.js +1 -1
  62. package/dist/context/manager.cjs +280 -323
  63. package/dist/context/manager.d.ts +65 -111
  64. package/dist/context/manager.d.ts.map +1 -1
  65. package/dist/context/manager.js +280 -328
  66. package/dist/context/media-helpers.js +1 -1
  67. package/dist/context/types.cjs +49 -0
  68. package/dist/context/types.d.ts +181 -72
  69. package/dist/context/types.d.ts.map +1 -1
  70. package/dist/context/types.js +35 -0
  71. package/dist/context/utils.cjs +266 -283
  72. package/dist/context/utils.d.ts +32 -18
  73. package/dist/context/utils.d.ts.map +1 -1
  74. package/dist/context/utils.js +266 -283
  75. package/dist/errors/DextoBaseError.js +1 -1
  76. package/dist/errors/DextoRuntimeError.js +1 -1
  77. package/dist/errors/DextoValidationError.js +1 -1
  78. package/dist/errors/index.js +1 -1
  79. package/dist/errors/result-bridge.js +1 -1
  80. package/dist/errors/types.js +1 -1
  81. package/dist/events/index.cjs +18 -1
  82. package/dist/events/index.d.ts +149 -12
  83. package/dist/events/index.d.ts.map +1 -1
  84. package/dist/events/index.js +19 -2
  85. package/dist/filesystem/error-codes.js +1 -1
  86. package/dist/filesystem/errors.js +1 -1
  87. package/dist/filesystem/filesystem-service.js +1 -1
  88. package/dist/filesystem/index.js +1 -1
  89. package/dist/filesystem/path-validator.js +1 -1
  90. package/dist/index.browser.cjs +23 -8
  91. package/dist/index.browser.d.ts +4 -3
  92. package/dist/index.browser.d.ts.map +1 -1
  93. package/dist/index.browser.js +20 -3
  94. package/dist/index.js +1 -1
  95. package/dist/llm/error-codes.cjs +0 -1
  96. package/dist/llm/error-codes.d.ts +0 -1
  97. package/dist/llm/error-codes.d.ts.map +1 -1
  98. package/dist/llm/error-codes.js +1 -2
  99. package/dist/llm/errors.cjs +10 -10
  100. package/dist/llm/errors.d.ts +5 -6
  101. package/dist/llm/errors.d.ts.map +1 -1
  102. package/dist/llm/errors.js +12 -12
  103. package/dist/llm/executor/stream-processor.cjs +367 -0
  104. package/dist/llm/executor/stream-processor.d.ts +55 -0
  105. package/dist/llm/executor/stream-processor.d.ts.map +1 -0
  106. package/dist/llm/executor/stream-processor.js +344 -0
  107. package/dist/llm/executor/tool-output-truncator.cjs +75 -0
  108. package/dist/llm/executor/tool-output-truncator.d.ts +27 -0
  109. package/dist/llm/executor/tool-output-truncator.d.ts.map +1 -0
  110. package/dist/llm/executor/tool-output-truncator.js +48 -0
  111. package/dist/llm/executor/turn-executor.cjs +753 -0
  112. package/dist/llm/executor/turn-executor.d.ts +166 -0
  113. package/dist/llm/executor/turn-executor.d.ts.map +1 -0
  114. package/dist/llm/executor/turn-executor.js +684 -0
  115. package/dist/llm/executor/types.d.ts +27 -0
  116. package/dist/llm/executor/types.d.ts.map +1 -0
  117. package/dist/llm/formatters/vercel.cjs +20 -186
  118. package/dist/llm/formatters/vercel.d.ts +2 -14
  119. package/dist/llm/formatters/vercel.d.ts.map +1 -1
  120. package/dist/llm/formatters/vercel.js +19 -185
  121. package/dist/llm/registry.cjs +36 -45
  122. package/dist/llm/registry.d.ts +53 -39
  123. package/dist/llm/registry.d.ts.map +1 -1
  124. package/dist/llm/registry.js +34 -42
  125. package/dist/llm/resolver.cjs +1 -31
  126. package/dist/llm/resolver.d.ts.map +1 -1
  127. package/dist/llm/resolver.js +2 -34
  128. package/dist/llm/schemas.cjs +2 -17
  129. package/dist/llm/schemas.d.ts +10 -23
  130. package/dist/llm/schemas.d.ts.map +1 -1
  131. package/dist/llm/schemas.js +5 -22
  132. package/dist/llm/services/factory.cjs +3 -92
  133. package/dist/llm/services/factory.d.ts +14 -4
  134. package/dist/llm/services/factory.d.ts.map +1 -1
  135. package/dist/llm/services/factory.js +4 -83
  136. package/dist/llm/services/test-utils.integration.cjs +6 -8
  137. package/dist/llm/services/test-utils.integration.d.ts.map +1 -1
  138. package/dist/llm/services/test-utils.integration.js +7 -9
  139. package/dist/llm/services/types.d.ts +1 -28
  140. package/dist/llm/services/types.d.ts.map +1 -1
  141. package/dist/llm/services/vercel.cjs +54 -468
  142. package/dist/llm/services/vercel.d.ts +38 -21
  143. package/dist/llm/services/vercel.d.ts.map +1 -1
  144. package/dist/llm/services/vercel.js +56 -475
  145. package/dist/llm/types.cjs +0 -3
  146. package/dist/llm/types.d.ts +8 -8
  147. package/dist/llm/types.d.ts.map +1 -1
  148. package/dist/llm/types.js +1 -3
  149. package/dist/llm/validation.js +1 -1
  150. package/dist/logger/browser.js +1 -1
  151. package/dist/logger/factory.js +1 -1
  152. package/dist/logger/index.js +1 -1
  153. package/dist/logger/logger.js +1 -1
  154. package/dist/logger/v2/dexto-logger.cjs +34 -6
  155. package/dist/logger/v2/dexto-logger.d.ts +20 -2
  156. package/dist/logger/v2/dexto-logger.d.ts.map +1 -1
  157. package/dist/logger/v2/dexto-logger.js +35 -7
  158. package/dist/logger/v2/error-codes.js +1 -1
  159. package/dist/logger/v2/errors.js +1 -1
  160. package/dist/logger/v2/schemas.js +1 -1
  161. package/dist/logger/v2/test-utils.cjs +70 -0
  162. package/dist/logger/v2/test-utils.d.ts +17 -0
  163. package/dist/logger/v2/test-utils.d.ts.map +1 -0
  164. package/dist/logger/v2/test-utils.js +46 -0
  165. package/dist/logger/v2/transport-factory.js +1 -1
  166. package/dist/logger/v2/transports/console-transport.js +1 -1
  167. package/dist/logger/v2/transports/file-transport.cjs +6 -0
  168. package/dist/logger/v2/transports/file-transport.d.ts +4 -0
  169. package/dist/logger/v2/transports/file-transport.d.ts.map +1 -1
  170. package/dist/logger/v2/transports/file-transport.js +7 -1
  171. package/dist/logger/v2/types.cjs +1 -0
  172. package/dist/logger/v2/types.d.ts +18 -2
  173. package/dist/logger/v2/types.d.ts.map +1 -1
  174. package/dist/logger/v2/types.js +2 -1
  175. package/dist/mcp/error-codes.cjs +1 -0
  176. package/dist/mcp/error-codes.d.ts +1 -0
  177. package/dist/mcp/error-codes.d.ts.map +1 -1
  178. package/dist/mcp/error-codes.js +2 -1
  179. package/dist/mcp/errors.cjs +13 -0
  180. package/dist/mcp/errors.d.ts +7 -0
  181. package/dist/mcp/errors.d.ts.map +1 -1
  182. package/dist/mcp/errors.js +14 -1
  183. package/dist/mcp/manager.cjs +4 -0
  184. package/dist/mcp/manager.d.ts.map +1 -1
  185. package/dist/mcp/manager.js +5 -1
  186. package/dist/mcp/mcp-client.js +1 -1
  187. package/dist/mcp/resolver.js +1 -1
  188. package/dist/mcp/schemas.cjs +6 -0
  189. package/dist/mcp/schemas.d.ts +52 -0
  190. package/dist/mcp/schemas.d.ts.map +1 -1
  191. package/dist/mcp/schemas.js +6 -1
  192. package/dist/memory/error-codes.js +1 -1
  193. package/dist/memory/errors.js +1 -1
  194. package/dist/memory/index.js +1 -1
  195. package/dist/memory/manager.js +1 -1
  196. package/dist/memory/schemas.d.ts +2 -2
  197. package/dist/memory/schemas.js +1 -1
  198. package/dist/plugins/builtins/content-policy.js +1 -1
  199. package/dist/plugins/builtins/response-sanitizer.js +1 -1
  200. package/dist/plugins/error-codes.js +1 -1
  201. package/dist/plugins/index.js +1 -1
  202. package/dist/plugins/loader.js +1 -1
  203. package/dist/plugins/manager.js +1 -1
  204. package/dist/plugins/registrations/builtins.js +1 -1
  205. package/dist/plugins/schemas.d.ts +3 -3
  206. package/dist/plugins/schemas.js +1 -1
  207. package/dist/plugins/types.d.ts +0 -1
  208. package/dist/plugins/types.d.ts.map +1 -1
  209. package/dist/process/command-validator.js +1 -1
  210. package/dist/process/error-codes.js +1 -1
  211. package/dist/process/errors.js +1 -1
  212. package/dist/process/index.js +1 -1
  213. package/dist/process/process-service.cjs +78 -26
  214. package/dist/process/process-service.d.ts +6 -1
  215. package/dist/process/process-service.d.ts.map +1 -1
  216. package/dist/process/process-service.js +79 -27
  217. package/dist/process/types.d.ts +2 -2
  218. package/dist/process/types.d.ts.map +1 -1
  219. package/dist/prompts/error-codes.cjs +1 -0
  220. package/dist/prompts/error-codes.d.ts +2 -1
  221. package/dist/prompts/error-codes.d.ts.map +1 -1
  222. package/dist/prompts/error-codes.js +2 -1
  223. package/dist/prompts/errors.cjs +15 -0
  224. package/dist/prompts/errors.d.ts +4 -0
  225. package/dist/prompts/errors.d.ts.map +1 -1
  226. package/dist/prompts/errors.js +16 -1
  227. package/dist/prompts/index.js +1 -1
  228. package/dist/prompts/name-validation.js +1 -1
  229. package/dist/prompts/prompt-manager.cjs +13 -2
  230. package/dist/prompts/prompt-manager.d.ts +7 -0
  231. package/dist/prompts/prompt-manager.d.ts.map +1 -1
  232. package/dist/prompts/prompt-manager.js +14 -3
  233. package/dist/prompts/providers/config-prompt-provider.cjs +12 -3
  234. package/dist/prompts/providers/config-prompt-provider.d.ts +2 -1
  235. package/dist/prompts/providers/config-prompt-provider.d.ts.map +1 -1
  236. package/dist/prompts/providers/config-prompt-provider.js +13 -4
  237. package/dist/prompts/providers/custom-prompt-provider.js +1 -1
  238. package/dist/prompts/providers/mcp-prompt-provider.js +1 -1
  239. package/dist/prompts/schemas.d.ts +12 -0
  240. package/dist/prompts/schemas.d.ts.map +1 -1
  241. package/dist/prompts/schemas.js +1 -1
  242. package/dist/prompts/types.d.ts +2 -0
  243. package/dist/prompts/types.d.ts.map +1 -1
  244. package/dist/prompts/utils.js +1 -1
  245. package/dist/resources/error-codes.js +1 -1
  246. package/dist/resources/errors.js +1 -1
  247. package/dist/resources/handlers/blob-handler.js +1 -1
  248. package/dist/resources/handlers/factory.js +1 -1
  249. package/dist/resources/handlers/filesystem-handler.js +1 -1
  250. package/dist/resources/index.js +1 -1
  251. package/dist/resources/internal-provider.js +1 -1
  252. package/dist/resources/manager.js +1 -1
  253. package/dist/resources/reference-parser.js +1 -1
  254. package/dist/resources/schemas.js +1 -1
  255. package/dist/search/index.js +1 -1
  256. package/dist/search/search-service.js +1 -1
  257. package/dist/session/chat-session.cjs +149 -51
  258. package/dist/session/chat-session.d.ts +69 -29
  259. package/dist/session/chat-session.d.ts.map +1 -1
  260. package/dist/session/chat-session.js +150 -52
  261. package/dist/session/error-codes.js +1 -1
  262. package/dist/session/errors.js +1 -1
  263. package/dist/session/history/database.cjs +134 -21
  264. package/dist/session/history/database.d.ts +37 -8
  265. package/dist/session/history/database.d.ts.map +1 -1
  266. package/dist/session/history/database.js +135 -22
  267. package/dist/session/history/factory.js +1 -1
  268. package/dist/session/history/memory.cjs +18 -0
  269. package/dist/session/history/memory.d.ts +8 -0
  270. package/dist/session/history/memory.d.ts.map +1 -1
  271. package/dist/session/history/memory.js +19 -1
  272. package/dist/session/history/types.d.ts +13 -1
  273. package/dist/session/history/types.d.ts.map +1 -1
  274. package/dist/session/index.cjs +3 -0
  275. package/dist/session/index.d.ts +3 -0
  276. package/dist/session/index.d.ts.map +1 -1
  277. package/dist/session/index.js +3 -1
  278. package/dist/session/message-queue.cjs +201 -0
  279. package/dist/session/message-queue.d.ts +114 -0
  280. package/dist/session/message-queue.d.ts.map +1 -0
  281. package/dist/session/message-queue.js +178 -0
  282. package/dist/session/schemas.js +1 -1
  283. package/dist/session/session-manager.cjs +57 -7
  284. package/dist/session/session-manager.d.ts +18 -0
  285. package/dist/session/session-manager.d.ts.map +1 -1
  286. package/dist/session/session-manager.js +58 -8
  287. package/dist/session/title-generator.cjs +4 -8
  288. package/dist/session/title-generator.d.ts +1 -2
  289. package/dist/session/title-generator.d.ts.map +1 -1
  290. package/dist/session/title-generator.js +5 -9
  291. package/dist/session/types.cjs +16 -0
  292. package/dist/session/types.d.ts +14 -0
  293. package/dist/session/types.d.ts.map +1 -0
  294. package/dist/session/types.js +0 -0
  295. package/dist/storage/blob/factory.js +1 -1
  296. package/dist/storage/blob/local-blob-store.js +1 -1
  297. package/dist/storage/blob/memory-blob-store.js +1 -1
  298. package/dist/storage/blob/schemas.js +1 -1
  299. package/dist/storage/cache/factory.js +1 -1
  300. package/dist/storage/cache/memory-cache-store.js +1 -1
  301. package/dist/storage/cache/redis-store.js +1 -1
  302. package/dist/storage/cache/schemas.js +1 -1
  303. package/dist/storage/database/factory.js +1 -1
  304. package/dist/storage/database/memory-database-store.js +1 -1
  305. package/dist/storage/database/postgres-store.cjs +12 -0
  306. package/dist/storage/database/postgres-store.d.ts.map +1 -1
  307. package/dist/storage/database/postgres-store.js +13 -1
  308. package/dist/storage/database/schemas.js +1 -1
  309. package/dist/storage/database/sqlite-store.js +1 -1
  310. package/dist/storage/error-codes.js +1 -1
  311. package/dist/storage/errors.js +1 -1
  312. package/dist/storage/index.js +1 -1
  313. package/dist/storage/schemas.js +1 -1
  314. package/dist/storage/storage-manager.js +1 -1
  315. package/dist/systemPrompt/contributors.js +1 -1
  316. package/dist/systemPrompt/error-codes.js +1 -1
  317. package/dist/systemPrompt/errors.js +1 -1
  318. package/dist/systemPrompt/in-built-prompts.js +1 -1
  319. package/dist/systemPrompt/index.js +1 -1
  320. package/dist/systemPrompt/manager.js +1 -1
  321. package/dist/systemPrompt/registry.js +1 -1
  322. package/dist/systemPrompt/schemas.d.ts +5 -5
  323. package/dist/systemPrompt/schemas.js +1 -1
  324. package/dist/telemetry/decorators.js +1 -1
  325. package/dist/telemetry/error-codes.js +1 -1
  326. package/dist/telemetry/errors.js +1 -1
  327. package/dist/telemetry/exporters.js +1 -1
  328. package/dist/telemetry/index.js +1 -1
  329. package/dist/telemetry/schemas.js +1 -1
  330. package/dist/telemetry/telemetry.js +1 -1
  331. package/dist/telemetry/utils.js +1 -1
  332. package/dist/tools/bash-pattern-utils.cjs +91 -0
  333. package/dist/tools/bash-pattern-utils.d.ts +58 -0
  334. package/dist/tools/bash-pattern-utils.d.ts.map +1 -0
  335. package/dist/tools/bash-pattern-utils.js +64 -0
  336. package/dist/tools/confirmation/allowed-tools-provider/factory.js +1 -1
  337. package/dist/tools/confirmation/allowed-tools-provider/in-memory.js +1 -1
  338. package/dist/tools/confirmation/allowed-tools-provider/storage.js +1 -1
  339. package/dist/tools/display-types.cjs +60 -0
  340. package/dist/tools/display-types.d.ts +133 -0
  341. package/dist/tools/display-types.d.ts.map +1 -0
  342. package/dist/tools/display-types.js +32 -0
  343. package/dist/tools/error-codes.cjs +2 -0
  344. package/dist/tools/error-codes.d.ts +3 -1
  345. package/dist/tools/error-codes.d.ts.map +1 -1
  346. package/dist/tools/error-codes.js +3 -1
  347. package/dist/tools/errors.cjs +30 -0
  348. package/dist/tools/errors.d.ts +16 -0
  349. package/dist/tools/errors.d.ts.map +1 -1
  350. package/dist/tools/errors.js +31 -1
  351. package/dist/tools/index.cjs +2 -0
  352. package/dist/tools/index.d.ts +1 -0
  353. package/dist/tools/index.d.ts.map +1 -1
  354. package/dist/tools/index.js +2 -1
  355. package/dist/tools/internal-tools/constants.js +1 -1
  356. package/dist/tools/internal-tools/implementations/ask-user-tool.cjs +1 -1
  357. package/dist/tools/internal-tools/implementations/ask-user-tool.js +2 -2
  358. package/dist/tools/internal-tools/implementations/bash-exec-tool.cjs +42 -18
  359. package/dist/tools/internal-tools/implementations/bash-exec-tool.d.ts +3 -3
  360. package/dist/tools/internal-tools/implementations/bash-exec-tool.d.ts.map +1 -1
  361. package/dist/tools/internal-tools/implementations/bash-exec-tool.js +43 -19
  362. package/dist/tools/internal-tools/implementations/bash-output-tool.js +1 -1
  363. package/dist/tools/internal-tools/implementations/delegate-to-url-tool.js +1 -1
  364. package/dist/tools/internal-tools/implementations/edit-file-tool.cjs +66 -1
  365. package/dist/tools/internal-tools/implementations/edit-file-tool.d.ts.map +1 -1
  366. package/dist/tools/internal-tools/implementations/edit-file-tool.js +67 -2
  367. package/dist/tools/internal-tools/implementations/glob-files-tool.cjs +14 -1
  368. package/dist/tools/internal-tools/implementations/glob-files-tool.d.ts.map +1 -1
  369. package/dist/tools/internal-tools/implementations/glob-files-tool.js +15 -2
  370. package/dist/tools/internal-tools/implementations/grep-content-tool.cjs +16 -1
  371. package/dist/tools/internal-tools/implementations/grep-content-tool.d.ts.map +1 -1
  372. package/dist/tools/internal-tools/implementations/grep-content-tool.js +17 -2
  373. package/dist/tools/internal-tools/implementations/kill-process-tool.js +1 -1
  374. package/dist/tools/internal-tools/implementations/read-file-tool.cjs +9 -1
  375. package/dist/tools/internal-tools/implementations/read-file-tool.d.ts.map +1 -1
  376. package/dist/tools/internal-tools/implementations/read-file-tool.js +10 -2
  377. package/dist/tools/internal-tools/implementations/search-history-tool.js +1 -1
  378. package/dist/tools/internal-tools/implementations/write-file-tool.cjs +69 -1
  379. package/dist/tools/internal-tools/implementations/write-file-tool.d.ts.map +1 -1
  380. package/dist/tools/internal-tools/implementations/write-file-tool.js +72 -2
  381. package/dist/tools/internal-tools/provider.cjs +27 -10
  382. package/dist/tools/internal-tools/provider.d.ts +8 -5
  383. package/dist/tools/internal-tools/provider.d.ts.map +1 -1
  384. package/dist/tools/internal-tools/provider.js +28 -11
  385. package/dist/tools/internal-tools/registry.cjs +4 -3
  386. package/dist/tools/internal-tools/registry.d.ts +28 -7
  387. package/dist/tools/internal-tools/registry.d.ts.map +1 -1
  388. package/dist/tools/internal-tools/registry.js +5 -4
  389. package/dist/tools/schemas.cjs +16 -6
  390. package/dist/tools/schemas.d.ts +31 -4
  391. package/dist/tools/schemas.d.ts.map +1 -1
  392. package/dist/tools/schemas.js +14 -6
  393. package/dist/tools/tool-manager.cjs +140 -18
  394. package/dist/tools/tool-manager.d.ts +23 -1
  395. package/dist/tools/tool-manager.d.ts.map +1 -1
  396. package/dist/tools/tool-manager.js +145 -19
  397. package/dist/tools/types.d.ts +20 -0
  398. package/dist/tools/types.d.ts.map +1 -1
  399. package/dist/utils/api-key-resolver.js +1 -1
  400. package/dist/utils/async-context.js +1 -1
  401. package/dist/utils/debug.js +1 -1
  402. package/dist/{llm/tokenizer/types.cjs → utils/defer.cjs} +19 -10
  403. package/dist/utils/defer.d.ts +63 -0
  404. package/dist/utils/defer.d.ts.map +1 -0
  405. package/dist/utils/defer.js +19 -0
  406. package/dist/utils/env-file.js +1 -1
  407. package/dist/utils/error-conversion.js +1 -1
  408. package/dist/utils/execution-context.js +1 -1
  409. package/dist/utils/fs-walk.js +1 -1
  410. package/dist/utils/index.cjs +3 -1
  411. package/dist/utils/index.d.ts +1 -0
  412. package/dist/utils/index.d.ts.map +1 -1
  413. package/dist/utils/index.js +1 -0
  414. package/dist/utils/path.js +1 -1
  415. package/dist/utils/redactor.js +1 -1
  416. package/dist/utils/result.js +1 -1
  417. package/dist/utils/safe-stringify.js +1 -1
  418. package/dist/utils/schema-metadata.js +1 -1
  419. package/dist/utils/schema.js +1 -1
  420. package/dist/utils/service-initializer.cjs +6 -2
  421. package/dist/utils/service-initializer.d.ts.map +1 -1
  422. package/dist/utils/service-initializer.js +7 -3
  423. package/dist/utils/user-info.js +1 -1
  424. package/dist/utils/zod-schema-converter.js +1 -1
  425. package/package.json +6 -7
  426. package/dist/context/compression/middle-removal.cjs +0 -95
  427. package/dist/context/compression/middle-removal.d.ts +0 -47
  428. package/dist/context/compression/middle-removal.d.ts.map +0 -1
  429. package/dist/context/compression/middle-removal.js +0 -72
  430. package/dist/context/compression/oldest-removal.cjs +0 -83
  431. package/dist/context/compression/oldest-removal.d.ts +0 -42
  432. package/dist/context/compression/oldest-removal.d.ts.map +0 -1
  433. package/dist/context/compression/oldest-removal.js +0 -60
  434. package/dist/llm/formatters/anthropic.cjs +0 -257
  435. package/dist/llm/formatters/anthropic.d.ts +0 -46
  436. package/dist/llm/formatters/anthropic.d.ts.map +0 -1
  437. package/dist/llm/formatters/anthropic.js +0 -239
  438. package/dist/llm/formatters/factory.cjs +0 -50
  439. package/dist/llm/formatters/factory.d.ts +0 -10
  440. package/dist/llm/formatters/factory.d.ts.map +0 -1
  441. package/dist/llm/formatters/factory.js +0 -27
  442. package/dist/llm/formatters/openai.cjs +0 -203
  443. package/dist/llm/formatters/openai.d.ts +0 -39
  444. package/dist/llm/formatters/openai.d.ts.map +0 -1
  445. package/dist/llm/formatters/openai.js +0 -184
  446. package/dist/llm/formatters/types.d.ts +0 -41
  447. package/dist/llm/formatters/types.d.ts.map +0 -1
  448. package/dist/llm/services/anthropic.cjs +0 -511
  449. package/dist/llm/services/anthropic.d.ts +0 -48
  450. package/dist/llm/services/anthropic.d.ts.map +0 -1
  451. package/dist/llm/services/anthropic.js +0 -447
  452. package/dist/llm/services/openai.cjs +0 -611
  453. package/dist/llm/services/openai.d.ts +0 -48
  454. package/dist/llm/services/openai.d.ts.map +0 -1
  455. package/dist/llm/services/openai.js +0 -547
  456. package/dist/llm/tokenizer/anthropic.cjs +0 -43
  457. package/dist/llm/tokenizer/anthropic.d.ts +0 -19
  458. package/dist/llm/tokenizer/anthropic.d.ts.map +0 -1
  459. package/dist/llm/tokenizer/anthropic.js +0 -20
  460. package/dist/llm/tokenizer/default.d.ts +0 -14
  461. package/dist/llm/tokenizer/default.d.ts.map +0 -1
  462. package/dist/llm/tokenizer/default.js +0 -18
  463. package/dist/llm/tokenizer/factory.cjs +0 -44
  464. package/dist/llm/tokenizer/factory.d.ts +0 -12
  465. package/dist/llm/tokenizer/factory.d.ts.map +0 -1
  466. package/dist/llm/tokenizer/factory.js +0 -21
  467. package/dist/llm/tokenizer/google.cjs +0 -52
  468. package/dist/llm/tokenizer/google.d.ts +0 -29
  469. package/dist/llm/tokenizer/google.d.ts.map +0 -1
  470. package/dist/llm/tokenizer/google.js +0 -29
  471. package/dist/llm/tokenizer/openai.cjs +0 -115
  472. package/dist/llm/tokenizer/openai.d.ts +0 -41
  473. package/dist/llm/tokenizer/openai.d.ts.map +0 -1
  474. package/dist/llm/tokenizer/openai.js +0 -91
  475. package/dist/llm/tokenizer/types.d.ts +0 -18
  476. package/dist/llm/tokenizer/types.d.ts.map +0 -1
  477. package/dist/llm/tokenizer/types.js +0 -10
  478. /package/dist/llm/{formatters → executor}/types.cjs +0 -0
  479. /package/dist/llm/{formatters → executor}/types.js +0 -0
@@ -66,6 +66,8 @@ __export(DextoAgent_exports, {
66
66
  DextoAgent: () => DextoAgent
67
67
  });
68
68
  module.exports = __toCommonJS(DextoAgent_exports);
69
+ var import_crypto = require("crypto");
70
+ var import_events = require("events");
69
71
  var import_resources = require("../resources/index.js");
70
72
  var import_utils = require("../context/utils.js");
71
73
  var import_prompts = require("../prompts/index.js");
@@ -81,13 +83,14 @@ var import_errors = require("../llm/errors.js");
81
83
  var import_errors2 = require("./errors.js");
82
84
  var import_errors3 = require("../mcp/errors.js");
83
85
  var import_DextoRuntimeError = require("../errors/DextoRuntimeError.js");
86
+ var import_DextoValidationError = require("../errors/DextoValidationError.js");
84
87
  var import_result_bridge = require("../errors/result-bridge.cjs");
85
88
  var import_result = require("../utils/result.cjs");
86
89
  var import_resolver2 = require("../mcp/resolver.js");
87
90
  var import_registry = require("../llm/registry.js");
88
91
  var import_service_initializer2 = require("../utils/service-initializer.js");
89
92
  var import_schemas2 = require("./schemas.js");
90
- var import_events = require("../events/index.js");
93
+ var import_events2 = require("../events/index.js");
91
94
  var import_safe_stringify = require("../utils/safe-stringify.cjs");
92
95
  var import_title_generator = require("../session/title-generator.js");
93
96
  var _DextoAgent_decorators, _init;
@@ -127,7 +130,7 @@ class DextoAgent {
127
130
  agentId: this.config.agentId,
128
131
  component: import_types.DextoLogComponent.AGENT
129
132
  });
130
- this.agentEventBus = new import_events.AgentEventBus();
133
+ this.agentEventBus = new import_events2.AgentEventBus();
131
134
  this.logger.info("DextoAgent created.");
132
135
  }
133
136
  /**
@@ -159,6 +162,8 @@ class DextoAgent {
159
162
  // Approval handler for manual tool confirmation and elicitation
160
163
  // Set via setApprovalHandler() before start() if needed
161
164
  approvalHandler;
165
+ // Active stream controllers per session - allows cancel() to abort iterators
166
+ activeStreamControllers = /* @__PURE__ */ new Map();
162
167
  // Logger instance for this agent (dependency injection)
163
168
  logger;
164
169
  /**
@@ -234,10 +239,6 @@ Either:
234
239
  for (const subscriber of this.eventSubscribers) {
235
240
  subscriber.subscribe(this.agentEventBus);
236
241
  }
237
- const fileTransport = this.config.logger?.transports?.find((t) => t.type === "file");
238
- if (fileTransport && "path" in fileTransport) {
239
- console.log(`\u{1F4CB} Logs available at: ${fileTransport.path}`);
240
- }
241
242
  } catch (error) {
242
243
  this.logger.error("Failed to start DextoAgent", {
243
244
  error: error instanceof Error ? error.message : String(error)
@@ -368,173 +369,88 @@ Either:
368
369
  }
369
370
  // ============= CORE AGENT FUNCTIONALITY =============
370
371
  /**
371
- * Main method for processing user input.
372
- * Processes user input through the agent's LLM service and returns the response.
372
+ * Process user input and return the response.
373
+ *
374
+ * @deprecated Use generate() or stream() instead for multi-image support.
375
+ * This method is kept for backward compatibility and only supports single image/file.
373
376
  *
374
- * @param textInput - The user's text message or query to process
375
- * @param imageDataInput - Optional image data and MIME type for multimodal input
376
- * @param fileDataInput - Optional file data and MIME type for file input
377
+ * @param textInput - The user's text message
378
+ * @param imageDataInput - Optional single image data
379
+ * @param fileDataInput - Optional single file data
377
380
  * @param sessionId - Session ID for the conversation (required)
378
- * @param stream - Whether to stream the response (default: false)
379
- * @returns Promise that resolves to the AI's response text, or null if no significant response
380
- * @throws Error if processing fails
381
+ * @param _stream - Ignored (streaming is handled internally)
382
+ * @returns Promise that resolves to the AI's response text
381
383
  */
382
- async run(textInput, imageDataInput, fileDataInput, sessionId, stream = false) {
383
- this.ensureStarted();
384
- if (!sessionId || typeof sessionId !== "string") {
385
- throw new Error("sessionId is required and must be a non-empty string");
386
- }
387
- const targetSessionId = sessionId;
388
- const activeContext = import_api.context.active();
389
- const span = import_api.trace.getActiveSpan();
390
- if (span) {
391
- span.setAttribute("sessionId", targetSessionId);
392
- }
393
- const existingBaggage = import_api.propagation.getBaggage(activeContext);
394
- const baggageEntries = {};
395
- if (existingBaggage) {
396
- existingBaggage.getAllEntries().forEach(([key, entry]) => {
397
- baggageEntries[key] = { ...entry };
384
+ async run(textInput, imageDataInput, fileDataInput, sessionId, _stream = false) {
385
+ const parts = [];
386
+ if (textInput) {
387
+ parts.push({ type: "text", text: textInput });
388
+ }
389
+ if (imageDataInput) {
390
+ parts.push({
391
+ type: "image",
392
+ image: imageDataInput.image,
393
+ mimeType: imageDataInput.mimeType
398
394
  });
399
395
  }
400
- baggageEntries.sessionId = { ...baggageEntries.sessionId, value: targetSessionId };
401
- const updatedContext = import_api.propagation.setBaggage(
402
- activeContext,
403
- import_api.propagation.createBaggage(baggageEntries)
404
- );
405
- const verifyBaggage = import_api.propagation.getBaggage(updatedContext);
406
- this.logger.debug(
407
- `Baggage after setting sessionId: ${JSON.stringify(
408
- Array.from(verifyBaggage?.getAllEntries() || [])
409
- )}`
410
- );
411
- return await import_api.context.with(updatedContext, async () => {
412
- try {
413
- const llmConfig = this.stateManager.getLLMConfig(targetSessionId);
414
- const validation = (0, import_validation.validateInputForLLM)(
415
- {
416
- text: textInput,
417
- ...imageDataInput && { imageData: imageDataInput },
418
- ...fileDataInput && { fileData: fileDataInput }
419
- },
420
- {
421
- provider: llmConfig.provider,
422
- model: llmConfig.model
423
- },
424
- this.logger
425
- );
426
- (0, import_result_bridge.ensureOk)(validation, this.logger);
427
- const session = await this.sessionManager.getSession(targetSessionId) || await this.sessionManager.createSession(targetSessionId);
428
- this.logger.debug(
429
- `DextoAgent.run: sessionId=${targetSessionId}, textLength=${textInput?.length ?? 0}, hasImage=${Boolean(
430
- imageDataInput
431
- )}, hasFile=${Boolean(fileDataInput)}`
432
- );
433
- let finalText = textInput;
434
- let finalImageData = imageDataInput;
435
- if (textInput && textInput.includes("@")) {
436
- try {
437
- const resources = await this.resourceManager.list();
438
- const expansion = await (0, import_resources.expandMessageReferences)(
439
- textInput,
440
- resources,
441
- (uri) => this.resourceManager.read(uri)
442
- );
443
- if (expansion.unresolvedReferences.length > 0) {
444
- const unresolvedNames = expansion.unresolvedReferences.map((ref) => ref.originalRef).join(", ");
445
- this.logger.warn(
446
- `Could not resolve ${expansion.unresolvedReferences.length} resource reference(s): ${unresolvedNames}`
447
- );
448
- }
449
- const MAX_EXPANDED_SIZE = 5 * 1024 * 1024;
450
- const expandedSize = Buffer.byteLength(expansion.expandedMessage, "utf-8");
451
- if (expandedSize > MAX_EXPANDED_SIZE) {
452
- this.logger.warn(
453
- `Expanded message size (${(expandedSize / 1024 / 1024).toFixed(2)}MB) exceeds limit (${MAX_EXPANDED_SIZE / 1024 / 1024}MB). Content may be truncated.`
454
- );
455
- }
456
- finalText = expansion.expandedMessage;
457
- if (expansion.extractedImages.length > 0 && !imageDataInput) {
458
- const firstImage = expansion.extractedImages[0];
459
- if (firstImage) {
460
- finalImageData = {
461
- image: firstImage.image,
462
- mimeType: firstImage.mimeType
463
- };
464
- this.logger.debug(
465
- `Using extracted image: ${firstImage.name} (${firstImage.mimeType})`
466
- );
467
- }
468
- }
469
- } catch (error) {
470
- this.logger.error(
471
- `Failed to expand resource references: ${error instanceof Error ? error.message : String(error)}. Continuing with original message.`
472
- );
473
- }
474
- }
475
- if (!finalText.trim() && !finalImageData && !fileDataInput) {
476
- this.logger.warn(
477
- "Resource expansion resulted in empty content. Using original message."
478
- );
479
- finalText = textInput;
480
- }
481
- const response = await session.run(
482
- finalText,
483
- finalImageData,
484
- fileDataInput,
485
- stream
486
- );
487
- this.sessionManager.incrementMessageCount(session.id).catch(
488
- (error) => this.logger.warn(
489
- `Failed to increment message count: ${error instanceof Error ? error.message : String(error)}`
490
- )
491
- );
492
- return response;
493
- } catch (error) {
494
- this.logger.error(
495
- `Error during DextoAgent.run: ${error instanceof Error ? error.message : JSON.stringify(error)}`
496
- );
497
- throw error;
498
- }
499
- });
396
+ if (fileDataInput) {
397
+ parts.push({
398
+ type: "file",
399
+ data: fileDataInput.data,
400
+ mimeType: fileDataInput.mimeType,
401
+ ...fileDataInput.filename && { filename: fileDataInput.filename }
402
+ });
403
+ }
404
+ const response = await this.generate(parts.length > 0 ? parts : textInput, sessionId);
405
+ return response.content;
500
406
  }
501
407
  /**
502
408
  * Generate a complete response (waits for full completion).
503
409
  * This is the recommended method for non-streaming use cases.
504
410
  *
505
- * @param message The user's message
506
- * @param options Configuration options (sessionId is required, imageData, fileData, signal are optional)
411
+ * @param content String message or array of content parts (text, images, files)
412
+ * @param sessionId Session ID for the conversation
413
+ * @param options Optional configuration (signal for cancellation)
507
414
  * @returns Promise that resolves to the complete response
508
415
  *
509
416
  * @example
510
417
  * ```typescript
511
- * const response = await agent.generate("What is 2+2?", { sessionId: "default" });
418
+ * // Simple text message
419
+ * const response = await agent.generate('What is 2+2?', 'session-1');
512
420
  * console.log(response.content); // "4"
513
- * console.log(response.usage.totalTokens); // 50
421
+ *
422
+ * // Multimodal with image
423
+ * const response = await agent.generate(
424
+ * [
425
+ * { type: 'text', text: 'Describe this image' },
426
+ * { type: 'image', image: base64Data, mimeType: 'image/png' }
427
+ * ],
428
+ * 'session-1'
429
+ * );
514
430
  * ```
515
431
  */
516
- async generate(message, options) {
432
+ async generate(content, sessionId, options) {
517
433
  const events = [];
518
- for await (const event of await this.stream(message, options)) {
434
+ for await (const event of await this.stream(content, sessionId, options)) {
519
435
  events.push(event);
520
436
  }
521
- const errorEvent = events.find(
522
- (e) => e.name === "llm:error"
437
+ const fatalErrorEvent = events.find(
438
+ (e) => e.name === "llm:error" && e.recoverable !== true
523
439
  );
524
- if (errorEvent) {
525
- if (errorEvent.error instanceof import_DextoRuntimeError.DextoRuntimeError) {
526
- throw errorEvent.error;
440
+ if (fatalErrorEvent) {
441
+ if (fatalErrorEvent.error instanceof import_DextoRuntimeError.DextoRuntimeError || fatalErrorEvent.error instanceof import_DextoValidationError.DextoValidationError) {
442
+ throw fatalErrorEvent.error;
527
443
  }
528
- const llmConfig = this.stateManager.getLLMConfig(options.sessionId);
444
+ const llmConfig = this.stateManager.getLLMConfig(sessionId);
529
445
  throw import_errors.LLMError.generationFailed(
530
- errorEvent.error.message,
446
+ fatalErrorEvent.error.message,
531
447
  llmConfig.provider,
532
448
  llmConfig.model
533
449
  );
534
450
  }
535
451
  const responseEvent = events.find((e) => e.name === "llm:response");
536
452
  if (!responseEvent || responseEvent.name !== "llm:response") {
537
- const llmConfig = this.stateManager.getLLMConfig(options.sessionId);
453
+ const llmConfig = this.stateManager.getLLMConfig(sessionId);
538
454
  throw import_errors.LLMError.generationFailed(
539
455
  "Stream did not complete successfully - no response received",
540
456
  llmConfig.provider,
@@ -570,7 +486,7 @@ Either:
570
486
  reasoning: responseEvent.reasoning,
571
487
  usage,
572
488
  toolCalls,
573
- sessionId: options.sessionId
489
+ sessionId
574
490
  };
575
491
  }
576
492
  /**
@@ -584,36 +500,38 @@ Either:
584
500
  * Events are forwarded directly from the AgentEventBus with no mapping layer,
585
501
  * providing a unified event system across all API layers.
586
502
  *
587
- * @param message The user's message
588
- * @param options Configuration options (sessionId is required, imageData, fileData, signal are optional)
503
+ * @param content String message or array of content parts (text, images, files)
504
+ * @param sessionId Session ID for the conversation
505
+ * @param options Optional configuration (signal for cancellation)
589
506
  * @returns AsyncIterator that yields StreamingEvent objects (core events with name property)
590
507
  *
591
508
  * @example
592
509
  * ```typescript
593
- * for await (const event of await agent.stream("Write a poem", { sessionId: "default" })) {
594
- * if (event.name === 'llm:chunk') {
595
- * process.stdout.write(event.content);
596
- * }
597
- * if (event.name === 'llm:tool-call') {
598
- * console.log(`\n[Using ${event.toolName}]\n`);
599
- * }
510
+ * // Simple text
511
+ * for await (const event of await agent.stream('Write a poem', 'session-1')) {
512
+ * if (event.name === 'llm:chunk') process.stdout.write(event.content);
600
513
  * }
514
+ *
515
+ * // Multimodal
516
+ * for await (const event of await agent.stream(
517
+ * [{ type: 'text', text: 'Describe this' }, { type: 'image', image: data, mimeType: 'image/png' }],
518
+ * 'session-1'
519
+ * )) { ... }
601
520
  * ```
602
521
  */
603
- async stream(message, options) {
522
+ async stream(content, sessionId, options) {
604
523
  this.ensureStarted();
605
- if (!options.sessionId) {
606
- throw new Error("sessionId is required in StreamOptions");
524
+ if (!sessionId) {
525
+ throw import_errors2.AgentError.apiValidationError("sessionId is required");
607
526
  }
608
- const sessionId = options.sessionId;
609
- const imageData = options.imageData;
610
- const fileData = options.fileData;
611
- const signal = options.signal;
527
+ const signal = options?.signal;
528
+ let contentParts = typeof content === "string" ? [{ type: "text", text: content }] : [...content];
612
529
  const eventQueue = [];
613
530
  let completed = false;
614
- let _streamError = null;
615
531
  const controller = new AbortController();
616
532
  const cleanupSignal = controller.signal;
533
+ this.activeStreamControllers.set(sessionId, controller);
534
+ (0, import_events.setMaxListeners)(30, cleanupSignal);
617
535
  const listeners = [];
618
536
  const cleanupListeners = () => {
619
537
  if (listeners.length === 0) {
@@ -626,6 +544,7 @@ Either:
626
544
  );
627
545
  }
628
546
  listeners.length = 0;
547
+ this.activeStreamControllers.delete(sessionId);
629
548
  };
630
549
  if (signal) {
631
550
  const abortHandler = () => {
@@ -649,7 +568,6 @@ Either:
649
568
  const responseListener = (data) => {
650
569
  if (data.sessionId !== sessionId) return;
651
570
  eventQueue.push({ name: "llm:response", ...data });
652
- completed = true;
653
571
  };
654
572
  this.agentEventBus.on("llm:response", responseListener, { signal: cleanupSignal });
655
573
  listeners.push({ event: "llm:response", listener: responseListener });
@@ -706,34 +624,191 @@ Either:
706
624
  signal: cleanupSignal
707
625
  });
708
626
  listeners.push({ event: "approval:response", listener: approvalResponseListener });
709
- const imageDataForRun = imageData ? {
710
- image: typeof imageData.image === "string" ? imageData.image : imageData.image.toString(),
711
- mimeType: imageData.mimeType || "image/png"
712
- } : void 0;
713
- const fileDataForRun = fileData ? {
714
- data: typeof fileData.data === "string" ? fileData.data : fileData.data.toString(),
715
- mimeType: fileData.mimeType,
716
- ...fileData.filename && { filename: fileData.filename }
717
- } : void 0;
718
- this.run(message, imageDataForRun, fileDataForRun, sessionId, true).catch((err) => {
719
- const error = err instanceof Error ? err : new Error(String(err));
720
- _streamError = error;
627
+ const toolRunningListener = (data) => {
628
+ if (data.sessionId !== sessionId) return;
629
+ eventQueue.push({ name: "tool:running", ...data });
630
+ };
631
+ this.agentEventBus.on("tool:running", toolRunningListener, {
632
+ signal: cleanupSignal
633
+ });
634
+ listeners.push({ event: "tool:running", listener: toolRunningListener });
635
+ const messageQueuedListener = (data) => {
636
+ if (data.sessionId !== sessionId) return;
637
+ eventQueue.push({ name: "message:queued", ...data });
638
+ };
639
+ this.agentEventBus.on("message:queued", messageQueuedListener, {
640
+ signal: cleanupSignal
641
+ });
642
+ listeners.push({ event: "message:queued", listener: messageQueuedListener });
643
+ const messageDequeuedListener = (data) => {
644
+ if (data.sessionId !== sessionId) return;
645
+ eventQueue.push({ name: "message:dequeued", ...data });
646
+ };
647
+ this.agentEventBus.on("message:dequeued", messageDequeuedListener, {
648
+ signal: cleanupSignal
649
+ });
650
+ listeners.push({ event: "message:dequeued", listener: messageDequeuedListener });
651
+ const runCompleteListener = (data) => {
652
+ if (data.sessionId !== sessionId) return;
653
+ eventQueue.push({ name: "run:complete", ...data });
721
654
  completed = true;
722
- this.logger.error(`Error in DextoAgent.stream: ${error.message}`);
723
- const errorEvent = {
724
- name: "llm:error",
725
- error,
726
- recoverable: false,
727
- context: "run_failed",
728
- sessionId
729
- };
730
- eventQueue.push(errorEvent);
655
+ };
656
+ this.agentEventBus.on("run:complete", runCompleteListener, {
657
+ signal: cleanupSignal
731
658
  });
659
+ listeners.push({ event: "run:complete", listener: runCompleteListener });
660
+ (async () => {
661
+ const activeContext = import_api.context.active();
662
+ const activeSpan = import_api.trace.getActiveSpan();
663
+ if (activeSpan) {
664
+ activeSpan.setAttribute("sessionId", sessionId);
665
+ }
666
+ const existingBaggage = import_api.propagation.getBaggage(activeContext);
667
+ const baggageEntries = {};
668
+ if (existingBaggage) {
669
+ existingBaggage.getAllEntries().forEach(([key, entry]) => {
670
+ baggageEntries[key] = { ...entry };
671
+ });
672
+ }
673
+ baggageEntries.sessionId = { ...baggageEntries.sessionId, value: sessionId };
674
+ const updatedContext = import_api.propagation.setBaggage(
675
+ activeContext,
676
+ import_api.propagation.createBaggage(baggageEntries)
677
+ );
678
+ await import_api.context.with(updatedContext, async () => {
679
+ try {
680
+ const llmConfig = this.stateManager.getLLMConfig(sessionId);
681
+ const textParts = contentParts.filter(
682
+ (p) => p.type === "text"
683
+ );
684
+ const textContent = textParts.map((p) => p.text).join("\n");
685
+ const imageParts = contentParts.filter(
686
+ (p) => p.type === "image"
687
+ );
688
+ const fileParts = contentParts.filter(
689
+ (p) => p.type === "file"
690
+ );
691
+ this.logger.debug(
692
+ `DextoAgent.stream: sessionId=${sessionId}, textLength=${textContent?.length ?? 0}, imageCount=${imageParts.length}, fileCount=${fileParts.length}`
693
+ );
694
+ const textValidation = (0, import_validation.validateInputForLLM)(
695
+ { text: textContent },
696
+ { provider: llmConfig.provider, model: llmConfig.model },
697
+ this.logger
698
+ );
699
+ (0, import_result_bridge.ensureOk)(textValidation, this.logger);
700
+ for (const imagePart of imageParts) {
701
+ const imageValidation = (0, import_validation.validateInputForLLM)(
702
+ {
703
+ imageData: {
704
+ image: typeof imagePart.image === "string" ? imagePart.image : imagePart.image.toString(),
705
+ mimeType: imagePart.mimeType || "image/png"
706
+ }
707
+ },
708
+ { provider: llmConfig.provider, model: llmConfig.model },
709
+ this.logger
710
+ );
711
+ (0, import_result_bridge.ensureOk)(imageValidation, this.logger);
712
+ }
713
+ for (const filePart of fileParts) {
714
+ const fileValidation = (0, import_validation.validateInputForLLM)(
715
+ {
716
+ fileData: {
717
+ data: typeof filePart.data === "string" ? filePart.data : filePart.data.toString(),
718
+ mimeType: filePart.mimeType
719
+ }
720
+ },
721
+ { provider: llmConfig.provider, model: llmConfig.model },
722
+ this.logger
723
+ );
724
+ (0, import_result_bridge.ensureOk)(fileValidation, this.logger);
725
+ }
726
+ if (textContent.includes("@")) {
727
+ try {
728
+ const resources = await this.resourceManager.list();
729
+ const expansion = await (0, import_resources.expandMessageReferences)(
730
+ textContent,
731
+ resources,
732
+ (uri) => this.resourceManager.read(uri)
733
+ );
734
+ if (expansion.unresolvedReferences.length > 0) {
735
+ const unresolvedNames = expansion.unresolvedReferences.map((ref) => ref.originalRef).join(", ");
736
+ this.logger.warn(
737
+ `Could not resolve ${expansion.unresolvedReferences.length} resource reference(s): ${unresolvedNames}`
738
+ );
739
+ }
740
+ const MAX_EXPANDED_SIZE = 5 * 1024 * 1024;
741
+ const expandedSize = Buffer.byteLength(
742
+ expansion.expandedMessage,
743
+ "utf-8"
744
+ );
745
+ if (expandedSize > MAX_EXPANDED_SIZE) {
746
+ this.logger.warn(
747
+ `Expanded message size (${(expandedSize / 1024 / 1024).toFixed(2)}MB) exceeds limit (${MAX_EXPANDED_SIZE / 1024 / 1024}MB). Content may be truncated.`
748
+ );
749
+ }
750
+ contentParts = contentParts.filter((p) => p.type !== "text");
751
+ if (expansion.expandedMessage.trim()) {
752
+ contentParts.unshift({
753
+ type: "text",
754
+ text: expansion.expandedMessage
755
+ });
756
+ }
757
+ for (const img of expansion.extractedImages) {
758
+ contentParts.push({
759
+ type: "image",
760
+ image: img.image,
761
+ mimeType: img.mimeType
762
+ });
763
+ this.logger.debug(
764
+ `Added extracted image: ${img.name} (${img.mimeType})`
765
+ );
766
+ }
767
+ } catch (error) {
768
+ this.logger.error(
769
+ `Failed to expand resource references: ${error instanceof Error ? error.message : String(error)}. Continuing with original message.`
770
+ );
771
+ }
772
+ }
773
+ const hasTextContent = contentParts.some(
774
+ (p) => p.type === "text" && p.text.trim()
775
+ );
776
+ const hasMediaContent = contentParts.some(
777
+ (p) => p.type === "image" || p.type === "file"
778
+ );
779
+ if (!hasTextContent && !hasMediaContent) {
780
+ this.logger.warn(
781
+ "Resource expansion resulted in empty content. Using original message."
782
+ );
783
+ contentParts = [{ type: "text", text: textContent }];
784
+ }
785
+ const session = await this.sessionManager.getSession(sessionId) || await this.sessionManager.createSession(sessionId);
786
+ await session.stream(contentParts, signal ? { signal } : void 0);
787
+ this.sessionManager.incrementMessageCount(session.id).catch(
788
+ (error) => this.logger.warn(
789
+ `Failed to increment message count: ${error instanceof Error ? error.message : String(error)}`
790
+ )
791
+ );
792
+ } catch (err) {
793
+ const error = err instanceof import_DextoRuntimeError.DextoRuntimeError || err instanceof import_DextoValidationError.DextoValidationError ? err : err instanceof Error ? err : import_errors2.AgentError.streamFailed(String(err));
794
+ completed = true;
795
+ this.logger.error(`Error in DextoAgent.stream: ${error.message}`);
796
+ const errorEvent = {
797
+ name: "llm:error",
798
+ error,
799
+ recoverable: false,
800
+ context: "run_failed",
801
+ sessionId
802
+ };
803
+ eventQueue.push(errorEvent);
804
+ }
805
+ });
806
+ })();
732
807
  const iterator = {
733
808
  async next() {
734
809
  while (!completed && eventQueue.length === 0) {
735
810
  await new Promise((resolve) => setTimeout(resolve, 0));
736
- if (signal?.aborted) {
811
+ if (signal?.aborted || cleanupSignal.aborted) {
737
812
  cleanupListeners();
738
813
  controller.abort();
739
814
  return { done: true, value: void 0 };
@@ -761,6 +836,73 @@ Either:
761
836
  };
762
837
  return iterator;
763
838
  }
839
+ /**
840
+ * Check if a session is currently processing a message.
841
+ * @param sessionId Session id
842
+ * @returns true if the session is busy processing; false otherwise
843
+ */
844
+ async isSessionBusy(sessionId) {
845
+ this.ensureStarted();
846
+ const session = await this.sessionManager.getSession(sessionId, false);
847
+ return session?.isBusy() ?? false;
848
+ }
849
+ /**
850
+ * Queue a message for processing when a session is busy.
851
+ * The message will be injected into the conversation when the current turn completes.
852
+ *
853
+ * @param sessionId Session id
854
+ * @param message The user message to queue
855
+ * @returns Queue position and message ID
856
+ * @throws Error if session doesn't support message queueing
857
+ */
858
+ async queueMessage(sessionId, message) {
859
+ this.ensureStarted();
860
+ const session = await this.sessionManager.getSession(sessionId, false);
861
+ if (!session) {
862
+ throw import_session.SessionError.notFound(sessionId);
863
+ }
864
+ return session.queueMessage(message);
865
+ }
866
+ /**
867
+ * Get all queued messages for a session.
868
+ * @param sessionId Session id
869
+ * @returns Array of queued messages
870
+ */
871
+ async getQueuedMessages(sessionId) {
872
+ this.ensureStarted();
873
+ const session = await this.sessionManager.getSession(sessionId, false);
874
+ if (!session) {
875
+ throw import_session.SessionError.notFound(sessionId);
876
+ }
877
+ return session.getQueuedMessages();
878
+ }
879
+ /**
880
+ * Remove a queued message.
881
+ * @param sessionId Session id
882
+ * @param messageId The ID of the queued message to remove
883
+ * @returns true if message was found and removed, false otherwise
884
+ */
885
+ async removeQueuedMessage(sessionId, messageId) {
886
+ this.ensureStarted();
887
+ const session = await this.sessionManager.getSession(sessionId, false);
888
+ if (!session) {
889
+ throw import_session.SessionError.notFound(sessionId);
890
+ }
891
+ return session.removeQueuedMessage(messageId);
892
+ }
893
+ /**
894
+ * Clear all queued messages for a session.
895
+ * @param sessionId Session id
896
+ * @returns Number of messages that were cleared
897
+ */
898
+ async clearMessageQueue(sessionId) {
899
+ this.ensureStarted();
900
+ const session = await this.sessionManager.getSession(sessionId, false);
901
+ if (!session) {
902
+ throw import_session.SessionError.notFound(sessionId);
903
+ }
904
+ return session.clearMessageQueue();
905
+ }
764
906
  /**
765
907
  * Cancels the currently running turn for a session.
766
908
  * Safe to call even if no run is in progress.
@@ -770,13 +912,20 @@ Either:
770
912
  async cancel(sessionId) {
771
913
  this.ensureStarted();
772
914
  if (!sessionId || typeof sessionId !== "string") {
773
- throw new Error("sessionId is required and must be a non-empty string");
915
+ throw import_errors2.AgentError.apiValidationError(
916
+ "sessionId is required and must be a non-empty string"
917
+ );
918
+ }
919
+ const streamController = this.activeStreamControllers.get(sessionId);
920
+ if (streamController) {
921
+ streamController.abort();
922
+ this.activeStreamControllers.delete(sessionId);
774
923
  }
775
924
  const existing = await this.sessionManager.getSession(sessionId, false);
776
925
  if (existing) {
777
926
  return existing.cancel();
778
927
  }
779
- return false;
928
+ return !!streamController;
780
929
  }
781
930
  // ============= SESSION MANAGEMENT =============
782
931
  /**
@@ -883,7 +1032,6 @@ Either:
883
1032
  const llmConfig = this.getEffectiveConfig(sessionId).llm;
884
1033
  const result = await (0, import_title_generator.generateSessionTitle)(
885
1034
  llmConfig,
886
- llmConfig.router,
887
1035
  this.toolManager,
888
1036
  this.systemPromptManager,
889
1037
  this.resourceManager,
@@ -966,7 +1114,9 @@ Either:
966
1114
  async resetConversation(sessionId) {
967
1115
  this.ensureStarted();
968
1116
  if (!sessionId || typeof sessionId !== "string") {
969
- throw new Error("sessionId is required and must be a non-empty string");
1117
+ throw import_errors2.AgentError.apiValidationError(
1118
+ "sessionId is required and must be a non-empty string"
1119
+ );
970
1120
  }
971
1121
  try {
972
1122
  await this.sessionManager.resetSession(sessionId);
@@ -981,6 +1131,37 @@ Either:
981
1131
  throw error;
982
1132
  }
983
1133
  }
1134
+ /**
1135
+ * Clears the context window for a session without deleting history.
1136
+ *
1137
+ * This adds a "context clear" marker to the conversation history. When the
1138
+ * context is loaded for LLM, messages before this marker are filtered out
1139
+ * (via filterCompacted). The full history remains in the database for
1140
+ * review via /resume or session history.
1141
+ *
1142
+ * Use this for /clear command - it preserves history but gives a fresh
1143
+ * context window to the LLM.
1144
+ *
1145
+ * @param sessionId Session ID (required)
1146
+ */
1147
+ async clearContext(sessionId) {
1148
+ this.ensureStarted();
1149
+ if (!sessionId || typeof sessionId !== "string") {
1150
+ throw import_errors2.AgentError.apiValidationError(
1151
+ "sessionId is required and must be a non-empty string"
1152
+ );
1153
+ }
1154
+ const session = await this.sessionManager.getSession(sessionId);
1155
+ if (!session) {
1156
+ throw import_session.SessionError.notFound(sessionId);
1157
+ }
1158
+ const contextManager = session.getContextManager();
1159
+ await contextManager.clearContext();
1160
+ this.logger.info(`Context cleared for session: ${sessionId}`);
1161
+ this.agentEventBus.emit("context:cleared", {
1162
+ sessionId
1163
+ });
1164
+ }
984
1165
  // ============= LLM MANAGEMENT =============
985
1166
  /**
986
1167
  * Gets the current LLM configuration with all defaults applied.
@@ -995,7 +1176,7 @@ Either:
995
1176
  * This is a comprehensive method that handles ALL validation, configuration building, and switching internally.
996
1177
  *
997
1178
  * Design:
998
- * - Input: Partial<LLMConfig> (allows optional fields like maxIterations?, router?)
1179
+ * - Input: Partial<LLMConfig> (allows optional fields like maxIterations?)
999
1180
  * - Output: LLMConfig (user-friendly type with all defaults applied)
1000
1181
  *
1001
1182
  * Key features:
@@ -1020,8 +1201,8 @@ Either:
1020
1201
  * // Switch to a different provider with explicit API key
1021
1202
  * await agent.switchLLM({ provider: 'anthropic', model: 'claude-4-sonnet-20250514', apiKey: 'sk-ant-...' });
1022
1203
  *
1023
- * // Switch with router and session options
1024
- * await agent.switchLLM({ provider: 'anthropic', model: 'claude-4-sonnet-20250514', router: 'in-built' }, 'user-123');
1204
+ * // Switch with session options
1205
+ * await agent.switchLLM({ provider: 'anthropic', model: 'claude-4-sonnet-20250514' }, 'user-123');
1025
1206
  *
1026
1207
  * // Switch for all sessions
1027
1208
  * await agent.switchLLM({ model: 'gpt-5' }, '*');
@@ -1173,19 +1354,23 @@ Either:
1173
1354
  }
1174
1355
  // ============= MCP SERVER MANAGEMENT =============
1175
1356
  /**
1176
- * Connects a new MCP server and adds it to the runtime configuration.
1357
+ * Adds a new MCP server to the runtime configuration and connects it if enabled.
1177
1358
  * This method handles validation, state management, and establishing the connection.
1178
1359
  *
1179
- * @param name The name of the server to connect.
1360
+ * @param name The name of the server to add.
1180
1361
  * @param config The configuration object for the server.
1181
1362
  * @throws DextoError if validation fails or connection fails
1182
1363
  */
1183
- async connectMcpServer(name, config) {
1364
+ async addMcpServer(name, config) {
1184
1365
  this.ensureStarted();
1185
1366
  const existingServerNames = Object.keys(this.stateManager.getRuntimeConfig().mcpServers);
1186
1367
  const validation = (0, import_resolver2.resolveAndValidateMcpServerConfig)(name, config, existingServerNames);
1187
1368
  const validatedConfig = (0, import_result_bridge.ensureOk)(validation, this.logger);
1188
- this.stateManager.addMcpServer(name, validatedConfig);
1369
+ this.stateManager.setMcpServer(name, validatedConfig);
1370
+ if (validatedConfig.enabled === false) {
1371
+ this.logger.info(`MCP server '${name}' added but not connected (disabled)`);
1372
+ return;
1373
+ }
1189
1374
  try {
1190
1375
  await this.mcpManager.connectServer(name, validatedConfig);
1191
1376
  await this.toolManager.refresh();
@@ -1197,9 +1382,7 @@ Either:
1197
1382
  tools: Object.keys(await this.toolManager.getAllTools()),
1198
1383
  source: "mcp"
1199
1384
  });
1200
- this.logger.info(
1201
- `DextoAgent: Successfully added and connected to MCP server '${name}'.`
1202
- );
1385
+ this.logger.info(`MCP server '${name}' added and connected successfully`);
1203
1386
  const warnings = validation.issues.filter((i) => i.severity === "warning");
1204
1387
  if (warnings.length > 0) {
1205
1388
  this.logger.warn(
@@ -1208,9 +1391,7 @@ Either:
1208
1391
  }
1209
1392
  } catch (error) {
1210
1393
  const errorMessage = error instanceof Error ? error.message : String(error);
1211
- this.logger.error(
1212
- `DextoAgent: Failed to connect to MCP server '${name}': ${errorMessage}`
1213
- );
1394
+ this.logger.error(`Failed to connect MCP server '${name}': ${errorMessage}`);
1214
1395
  this.stateManager.removeMcpServer(name);
1215
1396
  this.agentEventBus.emit("mcp:server-connected", {
1216
1397
  name,
@@ -1221,14 +1402,81 @@ Either:
1221
1402
  }
1222
1403
  }
1223
1404
  /**
1224
- * Removes and disconnects an MCP server.
1405
+ * @deprecated Use `addMcpServer` instead. This method will be removed in a future version.
1406
+ */
1407
+ async connectMcpServer(name, config) {
1408
+ return this.addMcpServer(name, config);
1409
+ }
1410
+ /**
1411
+ * Enables a disabled MCP server and connects it.
1412
+ * Updates the runtime state to enabled=true and establishes the connection.
1413
+ *
1414
+ * @param name The name of the server to enable.
1415
+ * @throws MCPError if server is not found or connection fails
1416
+ */
1417
+ async enableMcpServer(name) {
1418
+ this.ensureStarted();
1419
+ const currentConfig = this.stateManager.getRuntimeConfig().mcpServers[name];
1420
+ if (!currentConfig) {
1421
+ throw import_errors3.MCPError.serverNotFound(name);
1422
+ }
1423
+ const updatedConfig = { ...currentConfig, enabled: true };
1424
+ this.stateManager.setMcpServer(name, updatedConfig);
1425
+ try {
1426
+ await this.mcpManager.connectServer(name, updatedConfig);
1427
+ await this.toolManager.refresh();
1428
+ this.agentEventBus.emit("mcp:server-connected", { name, success: true });
1429
+ this.logger.info(`MCP server '${name}' enabled and connected`);
1430
+ } catch (error) {
1431
+ this.stateManager.setMcpServer(name, currentConfig);
1432
+ const errorMessage = error instanceof Error ? error.message : String(error);
1433
+ this.logger.error(`Failed to enable MCP server '${name}': ${errorMessage}`);
1434
+ throw import_errors3.MCPError.connectionFailed(name, errorMessage);
1435
+ }
1436
+ }
1437
+ /**
1438
+ * Disables an MCP server and disconnects it.
1439
+ * Updates the runtime state to enabled=false and closes the connection.
1440
+ *
1441
+ * @param name The name of the server to disable.
1442
+ * @throws MCPError if server is not found or disconnect fails
1443
+ */
1444
+ async disableMcpServer(name) {
1445
+ this.ensureStarted();
1446
+ const currentConfig = this.stateManager.getRuntimeConfig().mcpServers[name];
1447
+ if (!currentConfig) {
1448
+ throw import_errors3.MCPError.serverNotFound(name);
1449
+ }
1450
+ const updatedConfig = { ...currentConfig, enabled: false };
1451
+ this.stateManager.setMcpServer(name, updatedConfig);
1452
+ try {
1453
+ await this.mcpManager.removeClient(name);
1454
+ await this.toolManager.refresh();
1455
+ this.logger.info(`MCP server '${name}' disabled and disconnected`);
1456
+ } catch (error) {
1457
+ this.stateManager.setMcpServer(name, currentConfig);
1458
+ const errorMessage = error instanceof Error ? error.message : String(error);
1459
+ this.logger.error(`Failed to disable MCP server '${name}': ${errorMessage}`);
1460
+ throw import_errors3.MCPError.disconnectionFailed(name, errorMessage);
1461
+ }
1462
+ }
1463
+ /**
1464
+ * Removes and disconnects an MCP server completely.
1465
+ * Use this for deleting a server - removes from both runtime state and disconnects.
1225
1466
  * @param name The name of the server to remove.
1467
+ * @throws MCPError if disconnection fails
1226
1468
  */
1227
1469
  async removeMcpServer(name) {
1228
1470
  this.ensureStarted();
1229
- await this.mcpManager.removeClient(name);
1230
- this.stateManager.removeMcpServer(name);
1231
- await this.toolManager.refresh();
1471
+ try {
1472
+ await this.mcpManager.removeClient(name);
1473
+ this.stateManager.removeMcpServer(name);
1474
+ await this.toolManager.refresh();
1475
+ } catch (error) {
1476
+ const errorMessage = error instanceof Error ? error.message : String(error);
1477
+ this.logger.error(`Failed to remove MCP server '${name}': ${errorMessage}`);
1478
+ throw import_errors3.MCPError.disconnectionFailed(name, errorMessage);
1479
+ }
1232
1480
  }
1233
1481
  /**
1234
1482
  * Restarts an MCP server by disconnecting and reconnecting with its original configuration.
@@ -1261,13 +1509,18 @@ Either:
1261
1509
  /**
1262
1510
  * Executes a tool from any source (MCP servers, custom tools, or internal tools).
1263
1511
  * This is the unified interface for tool execution that can handle all tool types.
1512
+ *
1513
+ * Note: This is for direct/programmatic tool execution outside of LLM flow.
1514
+ * A toolCallId is generated automatically for tracking purposes.
1515
+ *
1264
1516
  * @param toolName The name of the tool to execute
1265
1517
  * @param args The arguments to pass to the tool
1266
1518
  * @returns The result of the tool execution
1267
1519
  */
1268
1520
  async executeTool(toolName, args) {
1269
1521
  this.ensureStarted();
1270
- return await this.toolManager.executeTool(toolName, args);
1522
+ const toolCallId = `direct-${(0, import_crypto.randomUUID)()}`;
1523
+ return await this.toolManager.executeTool(toolName, args, toolCallId);
1271
1524
  }
1272
1525
  /**
1273
1526
  * Gets all available tools from all connected MCP servers.
@@ -1305,6 +1558,79 @@ Either:
1305
1558
  this.ensureStarted();
1306
1559
  return this.mcpManager.getFailedConnections();
1307
1560
  }
1561
+ /**
1562
+ * Gets the connection status of a single MCP server.
1563
+ * @param name The server name
1564
+ * @returns The connection status, or undefined if server not configured
1565
+ *
1566
+ * TODO: Move to MCPManager once it has access to server configs (enabled state).
1567
+ * Currently here because MCPManager only tracks connections, not config.
1568
+ */
1569
+ getMcpServerStatus(name) {
1570
+ this.ensureStarted();
1571
+ const config = this.stateManager.getRuntimeConfig();
1572
+ const serverConfig = config.mcpServers[name];
1573
+ if (!serverConfig) return void 0;
1574
+ const enabled = serverConfig.enabled !== false;
1575
+ const connectedClients = this.mcpManager.getClients();
1576
+ const failedConnections = this.mcpManager.getFailedConnections();
1577
+ let status;
1578
+ if (!enabled) {
1579
+ status = "disconnected";
1580
+ } else if (connectedClients.has(name)) {
1581
+ status = "connected";
1582
+ } else {
1583
+ status = "error";
1584
+ }
1585
+ const result = {
1586
+ name,
1587
+ type: serverConfig.type,
1588
+ enabled,
1589
+ status
1590
+ };
1591
+ if (failedConnections[name]) {
1592
+ result.error = failedConnections[name];
1593
+ }
1594
+ return result;
1595
+ }
1596
+ /**
1597
+ * Gets all configured MCP servers with their connection status.
1598
+ * Centralizes the status computation logic used by CLI, server, and webui.
1599
+ * @returns Array of server info with computed status
1600
+ *
1601
+ * TODO: Move to MCPManager once it has access to server configs (enabled state).
1602
+ * Currently here because MCPManager only tracks connections, not config.
1603
+ */
1604
+ getMcpServersWithStatus() {
1605
+ this.ensureStarted();
1606
+ const config = this.stateManager.getRuntimeConfig();
1607
+ const mcpServers = config.mcpServers || {};
1608
+ const connectedClients = this.mcpManager.getClients();
1609
+ const failedConnections = this.mcpManager.getFailedConnections();
1610
+ const servers = [];
1611
+ for (const [name, serverConfig] of Object.entries(mcpServers)) {
1612
+ const enabled = serverConfig.enabled !== false;
1613
+ let status;
1614
+ if (!enabled) {
1615
+ status = "disconnected";
1616
+ } else if (connectedClients.has(name)) {
1617
+ status = "connected";
1618
+ } else {
1619
+ status = "error";
1620
+ }
1621
+ const server = {
1622
+ name,
1623
+ type: serverConfig.type,
1624
+ enabled,
1625
+ status
1626
+ };
1627
+ if (failedConnections[name]) {
1628
+ server.error = failedConnections[name];
1629
+ }
1630
+ servers.push(server);
1631
+ }
1632
+ return servers;
1633
+ }
1308
1634
  // ============= RESOURCE MANAGEMENT =============
1309
1635
  /**
1310
1636
  * Lists all available resources with their info.
@@ -1400,6 +1726,21 @@ Either:
1400
1726
  this.ensureStarted();
1401
1727
  return await this.promptManager.has(name);
1402
1728
  }
1729
+ /**
1730
+ * Refreshes the prompts cache, reloading from all providers.
1731
+ * Call this after adding/deleting prompts to make them immediately available.
1732
+ *
1733
+ * @param newPrompts Optional - if provided, updates the config prompts before refreshing.
1734
+ * Use this when you've modified the agent config file and need to
1735
+ * update both the runtime config and refresh the cache.
1736
+ */
1737
+ async refreshPrompts(newPrompts) {
1738
+ this.ensureStarted();
1739
+ if (newPrompts) {
1740
+ this.promptManager.updateConfigPrompts(newPrompts);
1741
+ }
1742
+ await this.promptManager.refresh();
1743
+ }
1403
1744
  /**
1404
1745
  * Gets a prompt with its messages.
1405
1746
  * @param name The name of the prompt