@dexto/core 1.2.4 → 1.2.6

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 (551) hide show
  1. package/README.md +60 -0
  2. package/dist/agent/DextoAgent.cjs +579 -345
  3. package/dist/agent/DextoAgent.d.ts +131 -83
  4. package/dist/agent/DextoAgent.d.ts.map +1 -1
  5. package/dist/agent/DextoAgent.js +573 -336
  6. package/dist/agent/agentCard.cjs +4 -2
  7. package/dist/agent/agentCard.d.ts +0 -1
  8. package/dist/agent/agentCard.d.ts.map +1 -1
  9. package/dist/agent/agentCard.js +4 -2
  10. package/dist/agent/index.cjs +3 -7
  11. package/dist/agent/index.d.ts +3 -3
  12. package/dist/agent/index.d.ts.map +1 -1
  13. package/dist/agent/index.js +7 -6
  14. package/dist/agent/schemas.cjs +179 -75
  15. package/dist/agent/schemas.d.ts +2678 -586
  16. package/dist/agent/schemas.d.ts.map +1 -1
  17. package/dist/agent/schemas.js +172 -65
  18. package/dist/agent/state-manager.cjs +28 -23
  19. package/dist/agent/state-manager.d.ts +4 -1
  20. package/dist/agent/state-manager.d.ts.map +1 -1
  21. package/dist/agent/state-manager.js +28 -23
  22. package/dist/{preferences/constants.cjs → agent/types.cjs} +2 -14
  23. package/dist/agent/types.d.ts +54 -0
  24. package/dist/agent/types.d.ts.map +1 -0
  25. package/dist/agent/types.js +0 -0
  26. package/dist/approval/errors.cjs +89 -8
  27. package/dist/approval/errors.d.ts +5 -3
  28. package/dist/approval/errors.d.ts.map +1 -1
  29. package/dist/approval/errors.js +89 -8
  30. package/dist/approval/{providers/factory.d.ts → factory.d.ts} +2 -2
  31. package/dist/approval/factory.d.ts.map +1 -0
  32. package/dist/approval/{providers/factory.js → factory.js} +1 -1
  33. package/dist/approval/index.cjs +4 -6
  34. package/dist/approval/index.d.ts +3 -5
  35. package/dist/approval/index.d.ts.map +1 -1
  36. package/dist/approval/index.js +4 -5
  37. package/dist/approval/manager.cjs +140 -37
  38. package/dist/approval/manager.d.ts +56 -17
  39. package/dist/approval/manager.d.ts.map +1 -1
  40. package/dist/approval/manager.js +141 -38
  41. package/dist/approval/schemas.cjs +9 -1
  42. package/dist/approval/schemas.d.ts +120 -35
  43. package/dist/approval/schemas.d.ts.map +1 -1
  44. package/dist/approval/schemas.js +9 -2
  45. package/dist/approval/types.cjs +14 -2
  46. package/dist/approval/types.d.ts +64 -12
  47. package/dist/approval/types.d.ts.map +1 -1
  48. package/dist/approval/types.js +12 -1
  49. package/dist/context/compression/middle-removal.cjs +11 -11
  50. package/dist/context/compression/middle-removal.d.ts +3 -1
  51. package/dist/context/compression/middle-removal.d.ts.map +1 -1
  52. package/dist/context/compression/middle-removal.js +11 -11
  53. package/dist/context/compression/oldest-removal.cjs +18 -5
  54. package/dist/context/compression/oldest-removal.d.ts +3 -1
  55. package/dist/context/compression/oldest-removal.d.ts.map +1 -1
  56. package/dist/context/compression/oldest-removal.js +18 -5
  57. package/dist/context/manager.cjs +94 -67
  58. package/dist/context/manager.d.ts +13 -10
  59. package/dist/context/manager.d.ts.map +1 -1
  60. package/dist/context/manager.js +94 -67
  61. package/dist/context/utils.cjs +79 -65
  62. package/dist/context/utils.d.ts +15 -12
  63. package/dist/context/utils.d.ts.map +1 -1
  64. package/dist/context/utils.js +45 -31
  65. package/dist/errors/DextoRuntimeError.d.ts +5 -5
  66. package/dist/errors/DextoRuntimeError.d.ts.map +1 -1
  67. package/dist/errors/result-bridge.cjs +2 -3
  68. package/dist/errors/result-bridge.d.ts +5 -3
  69. package/dist/errors/result-bridge.d.ts.map +1 -1
  70. package/dist/errors/result-bridge.js +1 -2
  71. package/dist/errors/types.cjs +1 -2
  72. package/dist/errors/types.d.ts +5 -8
  73. package/dist/errors/types.d.ts.map +1 -1
  74. package/dist/errors/types.js +1 -2
  75. package/dist/events/index.cjs +125 -55
  76. package/dist/events/index.d.ts +204 -97
  77. package/dist/events/index.d.ts.map +1 -1
  78. package/dist/events/index.js +123 -55
  79. package/dist/filesystem/filesystem-service.cjs +40 -30
  80. package/dist/filesystem/filesystem-service.d.ts +9 -1
  81. package/dist/filesystem/filesystem-service.d.ts.map +1 -1
  82. package/dist/filesystem/filesystem-service.js +40 -30
  83. package/dist/filesystem/path-validator.cjs +4 -3
  84. package/dist/filesystem/path-validator.d.ts +3 -1
  85. package/dist/filesystem/path-validator.d.ts.map +1 -1
  86. package/dist/filesystem/path-validator.js +4 -3
  87. package/dist/filesystem/types.d.ts +3 -3
  88. package/dist/filesystem/types.d.ts.map +1 -1
  89. package/dist/index.browser.cjs +7 -0
  90. package/dist/index.browser.d.ts +2 -0
  91. package/dist/index.browser.d.ts.map +1 -1
  92. package/dist/index.browser.js +4 -0
  93. package/dist/index.cjs +0 -7
  94. package/dist/index.d.ts +12 -3
  95. package/dist/index.d.ts.map +1 -1
  96. package/dist/index.js +0 -4
  97. package/dist/llm/formatters/anthropic.cjs +32 -21
  98. package/dist/llm/formatters/anthropic.d.ts +3 -0
  99. package/dist/llm/formatters/anthropic.d.ts.map +1 -1
  100. package/dist/llm/formatters/anthropic.js +32 -21
  101. package/dist/llm/formatters/factory.cjs +6 -7
  102. package/dist/llm/formatters/factory.d.ts +2 -1
  103. package/dist/llm/formatters/factory.d.ts.map +1 -1
  104. package/dist/llm/formatters/factory.js +4 -5
  105. package/dist/llm/formatters/openai.cjs +38 -9
  106. package/dist/llm/formatters/openai.d.ts +3 -0
  107. package/dist/llm/formatters/openai.d.ts.map +1 -1
  108. package/dist/llm/formatters/openai.js +38 -9
  109. package/dist/llm/formatters/vercel.cjs +49 -8
  110. package/dist/llm/formatters/vercel.d.ts +3 -0
  111. package/dist/llm/formatters/vercel.d.ts.map +1 -1
  112. package/dist/llm/formatters/vercel.js +49 -8
  113. package/dist/llm/registry.cjs +153 -17
  114. package/dist/llm/registry.d.ts +5 -2
  115. package/dist/llm/registry.d.ts.map +1 -1
  116. package/dist/llm/registry.js +143 -7
  117. package/dist/llm/resolver.cjs +4 -4
  118. package/dist/llm/resolver.d.ts +3 -2
  119. package/dist/llm/resolver.d.ts.map +1 -1
  120. package/dist/llm/resolver.js +4 -4
  121. package/dist/llm/schemas.cjs +6 -3
  122. package/dist/llm/schemas.d.ts +51 -17
  123. package/dist/llm/schemas.d.ts.map +1 -1
  124. package/dist/llm/schemas.js +5 -3
  125. package/dist/llm/services/anthropic.cjs +216 -183
  126. package/dist/llm/services/anthropic.d.ts +3 -1
  127. package/dist/llm/services/anthropic.d.ts.map +1 -1
  128. package/dist/llm/services/anthropic.js +217 -184
  129. package/dist/llm/services/factory.cjs +15 -9
  130. package/dist/llm/services/factory.d.ts +2 -1
  131. package/dist/llm/services/factory.d.ts.map +1 -1
  132. package/dist/llm/services/factory.js +15 -9
  133. package/dist/llm/services/openai.cjs +262 -225
  134. package/dist/llm/services/openai.d.ts +3 -1
  135. package/dist/llm/services/openai.d.ts.map +1 -1
  136. package/dist/llm/services/openai.js +263 -226
  137. package/dist/llm/services/test-utils.integration.cjs +58 -12
  138. package/dist/llm/services/test-utils.integration.d.ts.map +1 -1
  139. package/dist/llm/services/test-utils.integration.js +58 -12
  140. package/dist/llm/services/types.d.ts +9 -0
  141. package/dist/llm/services/types.d.ts.map +1 -1
  142. package/dist/llm/services/vercel.cjs +163 -111
  143. package/dist/llm/services/vercel.d.ts +3 -1
  144. package/dist/llm/services/vercel.d.ts.map +1 -1
  145. package/dist/llm/services/vercel.js +157 -105
  146. package/dist/llm/tokenizer/factory.cjs +2 -2
  147. package/dist/llm/tokenizer/factory.d.ts +3 -1
  148. package/dist/llm/tokenizer/factory.d.ts.map +1 -1
  149. package/dist/llm/tokenizer/factory.js +2 -2
  150. package/dist/llm/tokenizer/openai.cjs +16 -9
  151. package/dist/llm/tokenizer/openai.d.ts +4 -1
  152. package/dist/llm/tokenizer/openai.d.ts.map +1 -1
  153. package/dist/llm/tokenizer/openai.js +16 -9
  154. package/dist/llm/validation.cjs +8 -9
  155. package/dist/llm/validation.d.ts +3 -1
  156. package/dist/llm/validation.d.ts.map +1 -1
  157. package/dist/llm/validation.js +5 -6
  158. package/dist/logger/factory.cjs +54 -0
  159. package/dist/logger/factory.d.ts +36 -0
  160. package/dist/logger/factory.d.ts.map +1 -0
  161. package/dist/logger/factory.js +31 -0
  162. package/dist/logger/index.cjs +42 -3
  163. package/dist/logger/index.d.ts +17 -1
  164. package/dist/logger/index.d.ts.map +1 -1
  165. package/dist/logger/index.js +26 -1
  166. package/dist/logger/logger.cjs +30 -17
  167. package/dist/logger/logger.d.ts.map +1 -1
  168. package/dist/logger/logger.js +30 -17
  169. package/dist/logger/v2/dexto-logger.cjs +141 -0
  170. package/dist/logger/v2/dexto-logger.d.ts +54 -0
  171. package/dist/logger/v2/dexto-logger.d.ts.map +1 -0
  172. package/dist/logger/v2/dexto-logger.js +118 -0
  173. package/dist/{preferences → logger/v2}/error-codes.cjs +11 -10
  174. package/dist/logger/v2/error-codes.d.ts +13 -0
  175. package/dist/logger/v2/error-codes.d.ts.map +1 -0
  176. package/dist/logger/v2/error-codes.js +13 -0
  177. package/dist/logger/v2/errors.cjs +107 -0
  178. package/dist/logger/v2/errors.d.ts +32 -0
  179. package/dist/logger/v2/errors.d.ts.map +1 -0
  180. package/dist/logger/v2/errors.js +84 -0
  181. package/dist/logger/v2/schemas.cjs +57 -0
  182. package/dist/logger/v2/schemas.d.ts +147 -0
  183. package/dist/logger/v2/schemas.d.ts.map +1 -0
  184. package/dist/logger/v2/schemas.js +33 -0
  185. package/dist/logger/v2/transport-factory.cjs +53 -0
  186. package/dist/logger/v2/transport-factory.d.ts +21 -0
  187. package/dist/logger/v2/transport-factory.d.ts.map +1 -0
  188. package/dist/logger/v2/transport-factory.js +29 -0
  189. package/dist/logger/v2/transports/console-transport.cjs +79 -0
  190. package/dist/logger/v2/transports/console-transport.d.ts +23 -0
  191. package/dist/logger/v2/transports/console-transport.d.ts.map +1 -0
  192. package/dist/logger/v2/transports/console-transport.js +46 -0
  193. package/dist/logger/v2/transports/file-transport.cjs +161 -0
  194. package/dist/logger/v2/transports/file-transport.d.ts +46 -0
  195. package/dist/logger/v2/transports/file-transport.d.ts.map +1 -0
  196. package/dist/logger/v2/transports/file-transport.js +128 -0
  197. package/dist/logger/v2/types.cjs +49 -0
  198. package/dist/logger/v2/types.d.ts +123 -0
  199. package/dist/logger/v2/types.d.ts.map +1 -0
  200. package/dist/logger/v2/types.js +26 -0
  201. package/dist/mcp/manager.cjs +88 -78
  202. package/dist/mcp/manager.d.ts +3 -1
  203. package/dist/mcp/manager.d.ts.map +1 -1
  204. package/dist/mcp/manager.js +88 -78
  205. package/dist/mcp/mcp-client.cjs +109 -79
  206. package/dist/mcp/mcp-client.d.ts +3 -0
  207. package/dist/mcp/mcp-client.d.ts.map +1 -1
  208. package/dist/mcp/mcp-client.js +102 -72
  209. package/dist/memory/index.cjs +2 -0
  210. package/dist/memory/index.d.ts +1 -1
  211. package/dist/memory/index.d.ts.map +1 -1
  212. package/dist/memory/index.js +3 -1
  213. package/dist/memory/manager.cjs +9 -7
  214. package/dist/memory/manager.d.ts +3 -1
  215. package/dist/memory/manager.d.ts.map +1 -1
  216. package/dist/memory/manager.js +9 -7
  217. package/dist/memory/schemas.cjs +10 -0
  218. package/dist/memory/schemas.d.ts +37 -8
  219. package/dist/memory/schemas.d.ts.map +1 -1
  220. package/dist/memory/schemas.js +9 -0
  221. package/dist/plugins/manager.cjs +21 -19
  222. package/dist/plugins/manager.d.ts +3 -1
  223. package/dist/plugins/manager.d.ts.map +1 -1
  224. package/dist/plugins/manager.js +21 -19
  225. package/dist/plugins/schemas.d.ts +9 -9
  226. package/dist/plugins/types.d.ts +2 -2
  227. package/dist/plugins/types.d.ts.map +1 -1
  228. package/dist/process/command-validator.cjs +30 -20
  229. package/dist/process/command-validator.d.ts +4 -1
  230. package/dist/process/command-validator.d.ts.map +1 -1
  231. package/dist/process/command-validator.js +30 -20
  232. package/dist/process/process-service.cjs +23 -21
  233. package/dist/process/process-service.d.ts +3 -1
  234. package/dist/process/process-service.d.ts.map +1 -1
  235. package/dist/process/process-service.js +23 -21
  236. package/dist/prompts/index.cjs +6 -8
  237. package/dist/prompts/index.d.ts +2 -4
  238. package/dist/prompts/index.d.ts.map +1 -1
  239. package/dist/prompts/index.js +4 -6
  240. package/dist/prompts/prompt-manager.cjs +25 -20
  241. package/dist/prompts/prompt-manager.d.ts +3 -1
  242. package/dist/prompts/prompt-manager.d.ts.map +1 -1
  243. package/dist/prompts/prompt-manager.js +25 -20
  244. package/dist/prompts/providers/config-prompt-provider.cjs +331 -0
  245. package/dist/prompts/providers/config-prompt-provider.d.ts +34 -0
  246. package/dist/prompts/providers/config-prompt-provider.d.ts.map +1 -0
  247. package/dist/prompts/providers/config-prompt-provider.js +308 -0
  248. package/dist/prompts/providers/custom-prompt-provider.cjs +11 -7
  249. package/dist/prompts/providers/custom-prompt-provider.d.ts +3 -1
  250. package/dist/prompts/providers/custom-prompt-provider.d.ts.map +1 -1
  251. package/dist/prompts/providers/custom-prompt-provider.js +11 -7
  252. package/dist/prompts/providers/mcp-prompt-provider.cjs +7 -6
  253. package/dist/prompts/providers/mcp-prompt-provider.d.ts +3 -1
  254. package/dist/prompts/providers/mcp-prompt-provider.d.ts.map +1 -1
  255. package/dist/prompts/providers/mcp-prompt-provider.js +7 -6
  256. package/dist/prompts/schemas.cjs +42 -23
  257. package/dist/prompts/schemas.d.ts +123 -14
  258. package/dist/prompts/schemas.d.ts.map +1 -1
  259. package/dist/prompts/schemas.js +39 -22
  260. package/dist/prompts/types.d.ts +1 -1
  261. package/dist/prompts/types.d.ts.map +1 -1
  262. package/dist/resources/handlers/blob-handler.cjs +15 -11
  263. package/dist/resources/handlers/blob-handler.d.ts +3 -1
  264. package/dist/resources/handlers/blob-handler.d.ts.map +1 -1
  265. package/dist/resources/handlers/blob-handler.js +15 -11
  266. package/dist/resources/handlers/factory.cjs +3 -3
  267. package/dist/resources/handlers/factory.d.ts +2 -1
  268. package/dist/resources/handlers/factory.d.ts.map +1 -1
  269. package/dist/resources/handlers/factory.js +3 -3
  270. package/dist/resources/handlers/filesystem-handler.cjs +10 -8
  271. package/dist/resources/handlers/filesystem-handler.d.ts +3 -1
  272. package/dist/resources/handlers/filesystem-handler.d.ts.map +1 -1
  273. package/dist/resources/handlers/filesystem-handler.js +10 -8
  274. package/dist/resources/internal-provider.cjs +28 -20
  275. package/dist/resources/internal-provider.d.ts +3 -1
  276. package/dist/resources/internal-provider.d.ts.map +1 -1
  277. package/dist/resources/internal-provider.js +28 -20
  278. package/dist/resources/manager.cjs +34 -25
  279. package/dist/resources/manager.d.ts +3 -1
  280. package/dist/resources/manager.d.ts.map +1 -1
  281. package/dist/resources/manager.js +34 -25
  282. package/dist/resources/schemas.d.ts +6 -6
  283. package/dist/search/search-service.cjs +8 -6
  284. package/dist/search/search-service.d.ts +3 -1
  285. package/dist/search/search-service.d.ts.map +1 -1
  286. package/dist/search/search-service.js +8 -6
  287. package/dist/session/chat-session.cjs +40 -27
  288. package/dist/session/chat-session.d.ts +10 -7
  289. package/dist/session/chat-session.d.ts.map +1 -1
  290. package/dist/session/chat-session.js +40 -27
  291. package/dist/session/history/database.cjs +18 -11
  292. package/dist/session/history/database.d.ts +3 -1
  293. package/dist/session/history/database.d.ts.map +1 -1
  294. package/dist/session/history/database.js +18 -11
  295. package/dist/session/history/factory.cjs +2 -2
  296. package/dist/session/history/factory.d.ts +5 -1
  297. package/dist/session/history/factory.d.ts.map +1 -1
  298. package/dist/session/history/factory.js +2 -2
  299. package/dist/session/session-manager.cjs +37 -53
  300. package/dist/session/session-manager.d.ts +3 -17
  301. package/dist/session/session-manager.d.ts.map +1 -1
  302. package/dist/session/session-manager.js +37 -53
  303. package/dist/session/title-generator.cjs +3 -2
  304. package/dist/session/title-generator.d.ts +2 -1
  305. package/dist/session/title-generator.d.ts.map +1 -1
  306. package/dist/session/title-generator.js +3 -2
  307. package/dist/storage/blob/factory.cjs +9 -18
  308. package/dist/storage/blob/factory.d.ts +5 -4
  309. package/dist/storage/blob/factory.d.ts.map +1 -1
  310. package/dist/storage/blob/factory.js +8 -17
  311. package/dist/storage/blob/local-blob-store.cjs +25 -32
  312. package/dist/storage/blob/local-blob-store.d.ts +3 -2
  313. package/dist/storage/blob/local-blob-store.d.ts.map +1 -1
  314. package/dist/storage/blob/local-blob-store.js +25 -32
  315. package/dist/storage/blob/memory-blob-store.cjs +326 -0
  316. package/dist/storage/blob/memory-blob-store.d.ts +66 -0
  317. package/dist/storage/blob/memory-blob-store.d.ts.map +1 -0
  318. package/dist/storage/blob/memory-blob-store.js +303 -0
  319. package/dist/storage/blob/schemas.cjs +3 -1
  320. package/dist/storage/blob/schemas.d.ts +6 -6
  321. package/dist/storage/blob/schemas.d.ts.map +1 -1
  322. package/dist/storage/blob/schemas.js +3 -1
  323. package/dist/storage/cache/factory.cjs +7 -8
  324. package/dist/storage/cache/factory.d.ts +4 -1
  325. package/dist/storage/cache/factory.d.ts.map +1 -1
  326. package/dist/storage/cache/factory.js +4 -5
  327. package/dist/storage/cache/redis-store.cjs +4 -1
  328. package/dist/storage/cache/redis-store.d.ts +3 -1
  329. package/dist/storage/cache/redis-store.d.ts.map +1 -1
  330. package/dist/storage/cache/redis-store.js +4 -1
  331. package/dist/storage/database/factory.cjs +13 -16
  332. package/dist/storage/database/factory.d.ts +5 -3
  333. package/dist/storage/database/factory.d.ts.map +1 -1
  334. package/dist/storage/database/factory.js +9 -12
  335. package/dist/storage/database/postgres-store.cjs +4 -1
  336. package/dist/storage/database/postgres-store.d.ts +3 -1
  337. package/dist/storage/database/postgres-store.d.ts.map +1 -1
  338. package/dist/storage/database/postgres-store.js +4 -1
  339. package/dist/storage/database/schemas.cjs +3 -4
  340. package/dist/storage/database/schemas.d.ts +8 -16
  341. package/dist/storage/database/schemas.d.ts.map +1 -1
  342. package/dist/storage/database/schemas.js +3 -4
  343. package/dist/storage/database/sqlite-store.cjs +17 -45
  344. package/dist/storage/database/sqlite-store.d.ts +3 -3
  345. package/dist/storage/database/sqlite-store.d.ts.map +1 -1
  346. package/dist/storage/database/sqlite-store.js +17 -45
  347. package/dist/storage/schemas.cjs +3 -1
  348. package/dist/storage/schemas.d.ts +16 -23
  349. package/dist/storage/schemas.d.ts.map +1 -1
  350. package/dist/storage/schemas.js +3 -1
  351. package/dist/storage/storage-manager.cjs +15 -15
  352. package/dist/storage/storage-manager.d.ts +6 -6
  353. package/dist/storage/storage-manager.d.ts.map +1 -1
  354. package/dist/storage/storage-manager.js +15 -15
  355. package/dist/systemPrompt/contributors.cjs +15 -15
  356. package/dist/systemPrompt/contributors.d.ts +5 -3
  357. package/dist/systemPrompt/contributors.d.ts.map +1 -1
  358. package/dist/systemPrompt/contributors.js +15 -15
  359. package/dist/systemPrompt/in-built-prompts.cjs +0 -5
  360. package/dist/systemPrompt/in-built-prompts.d.ts +1 -2
  361. package/dist/systemPrompt/in-built-prompts.d.ts.map +1 -1
  362. package/dist/systemPrompt/in-built-prompts.js +0 -4
  363. package/dist/systemPrompt/manager.cjs +31 -23
  364. package/dist/systemPrompt/manager.d.ts +5 -3
  365. package/dist/systemPrompt/manager.d.ts.map +1 -1
  366. package/dist/systemPrompt/manager.js +31 -23
  367. package/dist/systemPrompt/registry.cjs +1 -2
  368. package/dist/systemPrompt/registry.d.ts +1 -1
  369. package/dist/systemPrompt/registry.d.ts.map +1 -1
  370. package/dist/systemPrompt/registry.js +1 -2
  371. package/dist/systemPrompt/schemas.cjs +24 -18
  372. package/dist/systemPrompt/schemas.d.ts +46 -222
  373. package/dist/systemPrompt/schemas.d.ts.map +1 -1
  374. package/dist/systemPrompt/schemas.js +14 -18
  375. package/dist/telemetry/decorators.cjs +54 -15
  376. package/dist/telemetry/decorators.d.ts.map +1 -1
  377. package/dist/telemetry/decorators.js +54 -15
  378. package/dist/telemetry/utils.cjs +21 -14
  379. package/dist/telemetry/utils.d.ts +7 -3
  380. package/dist/telemetry/utils.d.ts.map +1 -1
  381. package/dist/telemetry/utils.js +21 -14
  382. package/dist/tools/confirmation/allowed-tools-provider/factory.cjs +2 -2
  383. package/dist/tools/confirmation/allowed-tools-provider/factory.d.ts +2 -1
  384. package/dist/tools/confirmation/allowed-tools-provider/factory.d.ts.map +1 -1
  385. package/dist/tools/confirmation/allowed-tools-provider/factory.js +2 -2
  386. package/dist/tools/confirmation/allowed-tools-provider/storage.cjs +7 -6
  387. package/dist/tools/confirmation/allowed-tools-provider/storage.d.ts +3 -1
  388. package/dist/tools/confirmation/allowed-tools-provider/storage.d.ts.map +1 -1
  389. package/dist/tools/confirmation/allowed-tools-provider/storage.js +7 -6
  390. package/dist/tools/errors.cjs +2 -1
  391. package/dist/tools/errors.d.ts.map +1 -1
  392. package/dist/tools/errors.js +2 -1
  393. package/dist/tools/internal-tools/constants.cjs +2 -1
  394. package/dist/tools/internal-tools/constants.d.ts +1 -1
  395. package/dist/tools/internal-tools/constants.d.ts.map +1 -1
  396. package/dist/tools/internal-tools/constants.js +2 -1
  397. package/dist/tools/internal-tools/implementations/bash-exec-tool.cjs +1 -1
  398. package/dist/tools/internal-tools/implementations/bash-exec-tool.js +1 -1
  399. package/dist/tools/internal-tools/implementations/delegate-to-url-tool.cjs +192 -0
  400. package/dist/tools/internal-tools/implementations/delegate-to-url-tool.d.ts +33 -0
  401. package/dist/tools/internal-tools/implementations/delegate-to-url-tool.d.ts.map +1 -0
  402. package/dist/tools/internal-tools/implementations/delegate-to-url-tool.js +169 -0
  403. package/dist/tools/internal-tools/provider.cjs +21 -17
  404. package/dist/tools/internal-tools/provider.d.ts +3 -1
  405. package/dist/tools/internal-tools/provider.d.ts.map +1 -1
  406. package/dist/tools/internal-tools/provider.js +21 -17
  407. package/dist/tools/internal-tools/registry.cjs +5 -0
  408. package/dist/tools/internal-tools/registry.d.ts.map +1 -1
  409. package/dist/tools/internal-tools/registry.js +5 -0
  410. package/dist/tools/schemas.cjs +16 -4
  411. package/dist/tools/schemas.d.ts +21 -9
  412. package/dist/tools/schemas.d.ts.map +1 -1
  413. package/dist/tools/schemas.js +15 -4
  414. package/dist/tools/tool-manager.cjs +64 -47
  415. package/dist/tools/tool-manager.d.ts +4 -2
  416. package/dist/tools/tool-manager.d.ts.map +1 -1
  417. package/dist/tools/tool-manager.js +61 -44
  418. package/dist/tools/types.d.ts +0 -4
  419. package/dist/tools/types.d.ts.map +1 -1
  420. package/dist/utils/env-file.cjs +118 -0
  421. package/dist/utils/env-file.d.ts +5 -0
  422. package/dist/utils/env-file.d.ts.map +1 -0
  423. package/dist/utils/env-file.js +85 -0
  424. package/dist/utils/error-conversion.cjs +23 -1
  425. package/dist/utils/error-conversion.d.ts +2 -1
  426. package/dist/utils/error-conversion.d.ts.map +1 -1
  427. package/dist/utils/error-conversion.js +23 -1
  428. package/dist/utils/execution-context.d.ts.map +1 -1
  429. package/dist/utils/fs-walk.d.ts.map +1 -1
  430. package/dist/utils/index.cjs +7 -9
  431. package/dist/utils/index.d.ts +3 -4
  432. package/dist/utils/index.d.ts.map +1 -1
  433. package/dist/utils/index.js +3 -4
  434. package/dist/utils/path.cjs +22 -57
  435. package/dist/utils/path.d.ts +8 -7
  436. package/dist/utils/path.d.ts.map +1 -1
  437. package/dist/utils/path.js +21 -54
  438. package/dist/utils/result.cjs +37 -14
  439. package/dist/utils/result.d.ts.map +1 -1
  440. package/dist/utils/result.js +37 -14
  441. package/dist/utils/schema.cjs +2 -3
  442. package/dist/utils/schema.d.ts +2 -1
  443. package/dist/utils/schema.d.ts.map +1 -1
  444. package/dist/utils/schema.js +1 -2
  445. package/dist/utils/service-initializer.cjs +88 -61
  446. package/dist/utils/service-initializer.d.ts +4 -2
  447. package/dist/utils/service-initializer.d.ts.map +1 -1
  448. package/dist/utils/service-initializer.js +70 -43
  449. package/package.json +7 -3
  450. package/dist/Dexto.cjs +0 -251
  451. package/dist/Dexto.d.ts +0 -191
  452. package/dist/Dexto.d.ts.map +0 -1
  453. package/dist/Dexto.js +0 -228
  454. package/dist/agent/registry/error-codes.cjs +0 -44
  455. package/dist/agent/registry/error-codes.d.ts +0 -21
  456. package/dist/agent/registry/error-codes.d.ts.map +0 -1
  457. package/dist/agent/registry/error-codes.js +0 -21
  458. package/dist/agent/registry/errors.cjs +0 -188
  459. package/dist/agent/registry/errors.d.ts +0 -63
  460. package/dist/agent/registry/errors.d.ts.map +0 -1
  461. package/dist/agent/registry/errors.js +0 -165
  462. package/dist/agent/registry/registry.cjs +0 -479
  463. package/dist/agent/registry/registry.d.ts +0 -130
  464. package/dist/agent/registry/registry.d.ts.map +0 -1
  465. package/dist/agent/registry/registry.js +0 -453
  466. package/dist/agent/registry/types.cjs +0 -74
  467. package/dist/agent/registry/types.d.ts +0 -142
  468. package/dist/agent/registry/types.d.ts.map +0 -1
  469. package/dist/agent/registry/types.js +0 -48
  470. package/dist/agent/registry/user-registry.cjs +0 -140
  471. package/dist/agent/registry/user-registry.d.ts +0 -34
  472. package/dist/agent/registry/user-registry.d.ts.map +0 -1
  473. package/dist/agent/registry/user-registry.js +0 -105
  474. package/dist/approval/providers/event-based-approval-provider.cjs +0 -156
  475. package/dist/approval/providers/event-based-approval-provider.d.ts +0 -39
  476. package/dist/approval/providers/event-based-approval-provider.d.ts.map +0 -1
  477. package/dist/approval/providers/event-based-approval-provider.js +0 -133
  478. package/dist/approval/providers/factory.d.ts.map +0 -1
  479. package/dist/approval/providers/noop-approval-provider.cjs +0 -54
  480. package/dist/approval/providers/noop-approval-provider.d.ts +0 -18
  481. package/dist/approval/providers/noop-approval-provider.d.ts.map +0 -1
  482. package/dist/approval/providers/noop-approval-provider.js +0 -31
  483. package/dist/config/agent-resolver.cjs +0 -153
  484. package/dist/config/agent-resolver.d.ts +0 -14
  485. package/dist/config/agent-resolver.d.ts.map +0 -1
  486. package/dist/config/agent-resolver.js +0 -123
  487. package/dist/config/error-codes.cjs +0 -39
  488. package/dist/config/error-codes.d.ts +0 -16
  489. package/dist/config/error-codes.d.ts.map +0 -1
  490. package/dist/config/error-codes.js +0 -16
  491. package/dist/config/errors.cjs +0 -126
  492. package/dist/config/errors.d.ts +0 -34
  493. package/dist/config/errors.d.ts.map +0 -1
  494. package/dist/config/errors.js +0 -103
  495. package/dist/config/index.cjs +0 -26
  496. package/dist/config/index.d.ts +0 -4
  497. package/dist/config/index.d.ts.map +0 -1
  498. package/dist/config/index.js +0 -3
  499. package/dist/config/loader.cjs +0 -119
  500. package/dist/config/loader.d.ts +0 -16
  501. package/dist/config/loader.d.ts.map +0 -1
  502. package/dist/config/loader.js +0 -86
  503. package/dist/config/writer.cjs +0 -182
  504. package/dist/config/writer.d.ts +0 -35
  505. package/dist/config/writer.d.ts.map +0 -1
  506. package/dist/config/writer.js +0 -147
  507. package/dist/preferences/constants.d.ts +0 -2
  508. package/dist/preferences/constants.d.ts.map +0 -1
  509. package/dist/preferences/constants.js +0 -5
  510. package/dist/preferences/error-codes.d.ts +0 -8
  511. package/dist/preferences/error-codes.d.ts.map +0 -1
  512. package/dist/preferences/error-codes.js +0 -12
  513. package/dist/preferences/errors.cjs +0 -75
  514. package/dist/preferences/errors.d.ts +0 -18
  515. package/dist/preferences/errors.d.ts.map +0 -1
  516. package/dist/preferences/errors.js +0 -51
  517. package/dist/preferences/index.cjs +0 -55
  518. package/dist/preferences/index.d.ts +0 -6
  519. package/dist/preferences/index.d.ts.map +0 -1
  520. package/dist/preferences/index.js +0 -32
  521. package/dist/preferences/loader.cjs +0 -138
  522. package/dist/preferences/loader.d.ts +0 -51
  523. package/dist/preferences/loader.d.ts.map +0 -1
  524. package/dist/preferences/loader.js +0 -110
  525. package/dist/preferences/schemas.cjs +0 -75
  526. package/dist/preferences/schemas.d.ts +0 -110
  527. package/dist/preferences/schemas.d.ts.map +0 -1
  528. package/dist/preferences/schemas.js +0 -49
  529. package/dist/prompts/providers/file-prompt-provider.cjs +0 -399
  530. package/dist/prompts/providers/file-prompt-provider.d.ts +0 -47
  531. package/dist/prompts/providers/file-prompt-provider.d.ts.map +0 -1
  532. package/dist/prompts/providers/file-prompt-provider.js +0 -376
  533. package/dist/prompts/providers/starter-prompt-provider.cjs +0 -170
  534. package/dist/prompts/providers/starter-prompt-provider.d.ts +0 -45
  535. package/dist/prompts/providers/starter-prompt-provider.d.ts.map +0 -1
  536. package/dist/prompts/providers/starter-prompt-provider.js +0 -147
  537. package/dist/utils/api-key-store.cjs +0 -56
  538. package/dist/utils/api-key-store.d.ts +0 -24
  539. package/dist/utils/api-key-store.d.ts.map +0 -1
  540. package/dist/utils/api-key-store.js +0 -31
  541. package/dist/utils/env.cjs +0 -154
  542. package/dist/utils/env.d.ts +0 -28
  543. package/dist/utils/env.d.ts.map +0 -1
  544. package/dist/utils/env.js +0 -119
  545. package/dist/utils/port-utils.cjs +0 -37
  546. package/dist/utils/port-utils.d.ts +0 -10
  547. package/dist/utils/port-utils.d.ts.map +0 -1
  548. package/dist/utils/port-utils.js +0 -14
  549. package/dist/utils/port-utils.spec.cjs +0 -26
  550. package/dist/utils/port-utils.spec.js +0 -25
  551. /package/dist/approval/{providers/factory.cjs → factory.cjs} +0 -0
@@ -70,25 +70,25 @@ var import_resources = require("../resources/index.js");
70
70
  var import_utils = require("../context/utils.js");
71
71
  var import_prompts = require("../prompts/index.js");
72
72
  var import_session = require("../session/index.js");
73
- var import_logger = require("../logger/index.js");
73
+ var import_factory = require("../logger/factory.js");
74
+ var import_types = require("../logger/v2/types.js");
74
75
  var import_decorators = require("../telemetry/decorators.js");
76
+ var import_api = require("@opentelemetry/api");
75
77
  var import_schemas = require("../llm/schemas.cjs");
76
78
  var import_resolver = require("../llm/resolver.js");
77
79
  var import_validation = require("../llm/validation.js");
78
- var import_errors = require("./errors.js");
79
- var import_errors2 = require("../mcp/errors.js");
80
+ var import_errors = require("../llm/errors.js");
81
+ var import_errors2 = require("./errors.js");
82
+ var import_errors3 = require("../mcp/errors.js");
83
+ var import_DextoRuntimeError = require("../errors/DextoRuntimeError.js");
80
84
  var import_result_bridge = require("../errors/result-bridge.cjs");
81
85
  var import_result = require("../utils/result.cjs");
82
- var import_DextoValidationError = require("../errors/DextoValidationError.cjs");
83
86
  var import_resolver2 = require("../mcp/resolver.js");
84
87
  var import_registry = require("../llm/registry.js");
85
88
  var import_service_initializer2 = require("../utils/service-initializer.js");
86
89
  var import_schemas2 = require("./schemas.js");
87
- var import_path = require("../utils/path.js");
90
+ var import_events = require("../events/index.js");
88
91
  var import_safe_stringify = require("../utils/safe-stringify.cjs");
89
- var import_loader = require("../config/loader.js");
90
- var import_fs = require("fs");
91
- var import_yaml = require("yaml");
92
92
  var import_title_generator = require("../session/title-generator.js");
93
93
  var _DextoAgent_decorators, _init;
94
94
  const requiredServices = [
@@ -113,10 +113,22 @@ _DextoAgent_decorators = [(0, import_decorators.InstrumentClass)({
113
113
  ]
114
114
  })];
115
115
  class DextoAgent {
116
+ /**
117
+ * Creates a DextoAgent instance.
118
+ *
119
+ * @param config - Agent configuration (validated and enriched)
120
+ * @param configPath - Optional path to config file (for relative path resolution)
121
+ */
116
122
  constructor(config, configPath) {
117
123
  this.configPath = configPath;
118
124
  this.config = import_schemas2.AgentConfigSchema.parse(config);
119
- import_logger.logger.info("DextoAgent created.");
125
+ this.logger = (0, import_factory.createLogger)({
126
+ config: this.config.logger,
127
+ agentId: this.config.agentId,
128
+ component: import_types.DextoLogComponent.AGENT
129
+ });
130
+ this.agentEventBus = new import_events.AgentEventBus();
131
+ this.logger.info("DextoAgent created.");
120
132
  }
121
133
  /**
122
134
  * These services are public for use by the outside world
@@ -135,19 +147,20 @@ class DextoAgent {
135
147
  services;
136
148
  // Search service for conversation search
137
149
  searchService;
138
- // Default session for backward compatibility
139
- defaultSession = null;
140
- // Current default session ID for loadSession functionality
141
- currentDefaultSessionId = "default";
142
150
  // Track initialization state
143
151
  _isStarted = false;
144
152
  _isStopped = false;
145
- // Store config for async initialization
153
+ // Store config for async initialization (accessible before start() for setup)
146
154
  config;
147
- // Event subscribers (e.g., WebSocket, Webhook handlers)
155
+ // Event subscribers (e.g., SSE, Webhook handlers)
148
156
  eventSubscribers = /* @__PURE__ */ new Set();
149
157
  // Telemetry instance for distributed tracing
150
158
  telemetry;
159
+ // Approval handler for manual tool confirmation and elicitation
160
+ // Set via setApprovalHandler() before start() if needed
161
+ approvalHandler;
162
+ // Logger instance for this agent (dependency injection)
163
+ logger;
151
164
  /**
152
165
  * Starts the agent by initializing all async services.
153
166
  * This method handles storage backends, MCP connections, session manager initialization, and other async operations.
@@ -157,24 +170,48 @@ class DextoAgent {
157
170
  */
158
171
  async start() {
159
172
  if (this._isStarted) {
160
- throw import_errors.AgentError.alreadyStarted();
173
+ throw import_errors2.AgentError.alreadyStarted();
161
174
  }
162
175
  try {
163
- import_logger.logger.info("Starting DextoAgent...");
164
- const services = await (0, import_service_initializer2.createAgentServices)(this.config, this.configPath);
176
+ this.logger.info("Starting DextoAgent...");
177
+ const services = await (0, import_service_initializer2.createAgentServices)(
178
+ this.config,
179
+ this.configPath,
180
+ this.logger,
181
+ this.agentEventBus
182
+ );
165
183
  for (const service of requiredServices) {
166
184
  if (!services[service]) {
167
- throw import_errors.AgentError.initializationFailed(
185
+ throw import_errors2.AgentError.initializationFailed(
168
186
  `Required service ${service} is missing during agent start`
169
187
  );
170
188
  }
171
189
  }
190
+ const needsHandler = this.config.toolConfirmation.mode === "manual" || this.config.elicitation.enabled;
191
+ if (needsHandler && !this.approvalHandler) {
192
+ const reasons = [];
193
+ if (this.config.toolConfirmation.mode === "manual") {
194
+ reasons.push('tool confirmation mode is "manual"');
195
+ }
196
+ if (this.config.elicitation.enabled) {
197
+ reasons.push("elicitation is enabled");
198
+ }
199
+ throw import_errors2.AgentError.initializationFailed(
200
+ `An approval handler is required but not configured (${reasons.join(" and ")}).
201
+ Either:
202
+ \u2022 Call agent.setApprovalHandler() before starting
203
+ \u2022 Set toolConfirmation: { mode: "auto-approve" } or { mode: "auto-deny" }
204
+ \u2022 Disable elicitation: { enabled: false }`
205
+ );
206
+ }
207
+ if (this.approvalHandler) {
208
+ services.approvalManager.setHandler(this.approvalHandler);
209
+ }
172
210
  Object.assign(this, {
173
211
  mcpManager: services.mcpManager,
174
212
  toolManager: services.toolManager,
175
213
  resourceManager: services.resourceManager,
176
214
  systemPromptManager: services.systemPromptManager,
177
- agentEventBus: services.agentEventBus,
178
215
  stateManager: services.stateManager,
179
216
  sessionManager: services.sessionManager,
180
217
  memoryManager: services.memoryManager,
@@ -186,20 +223,25 @@ class DextoAgent {
186
223
  this.resourceManager,
187
224
  this.config,
188
225
  this.agentEventBus,
189
- services.storageManager.getDatabase()
226
+ services.storageManager.getDatabase(),
227
+ this.logger
190
228
  );
191
229
  await promptManager.initialize();
192
230
  Object.assign(this, { promptManager });
193
231
  this._isStarted = true;
194
232
  this._isStopped = false;
195
- import_logger.logger.info("DextoAgent started successfully.");
233
+ this.logger.info("DextoAgent started successfully.");
196
234
  for (const subscriber of this.eventSubscribers) {
197
235
  subscriber.subscribe(this.agentEventBus);
198
236
  }
199
- const logPath = (0, import_path.getDextoPath)("logs", "dexto.log");
200
- console.log(`\u{1F4CB} Logs available at: ${logPath}`);
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
+ }
201
241
  } catch (error) {
202
- import_logger.logger.error("Failed to start DextoAgent", error);
242
+ this.logger.error("Failed to start DextoAgent", {
243
+ error: error instanceof Error ? error.message : String(error)
244
+ });
203
245
  throw error;
204
246
  }
205
247
  }
@@ -212,19 +254,19 @@ class DextoAgent {
212
254
  */
213
255
  async stop() {
214
256
  if (this._isStopped) {
215
- import_logger.logger.warn("Agent is already stopped");
257
+ this.logger.warn("Agent is already stopped");
216
258
  return;
217
259
  }
218
260
  if (!this._isStarted) {
219
- throw import_errors.AgentError.notStarted();
261
+ throw import_errors2.AgentError.notStarted();
220
262
  }
221
263
  try {
222
- import_logger.logger.info("Stopping DextoAgent...");
264
+ this.logger.info("Stopping DextoAgent...");
223
265
  const shutdownErrors = [];
224
266
  try {
225
267
  if (this.sessionManager) {
226
268
  await this.sessionManager.cleanup();
227
- import_logger.logger.debug("SessionManager cleaned up successfully");
269
+ this.logger.debug("SessionManager cleaned up successfully");
228
270
  }
229
271
  } catch (error) {
230
272
  const err = error instanceof Error ? error : new Error(String(error));
@@ -233,7 +275,7 @@ class DextoAgent {
233
275
  try {
234
276
  if (this.services?.pluginManager) {
235
277
  await this.services.pluginManager.cleanup();
236
- import_logger.logger.debug("PluginManager cleaned up successfully");
278
+ this.logger.debug("PluginManager cleaned up successfully");
237
279
  }
238
280
  } catch (error) {
239
281
  const err = error instanceof Error ? error : new Error(String(error));
@@ -242,7 +284,7 @@ class DextoAgent {
242
284
  try {
243
285
  if (this.mcpManager) {
244
286
  await this.mcpManager.disconnectAll();
245
- import_logger.logger.debug("MCPManager disconnected all clients successfully");
287
+ this.logger.debug("MCPManager disconnected all clients successfully");
246
288
  }
247
289
  } catch (error) {
248
290
  const err = error instanceof Error ? error : new Error(String(error));
@@ -251,7 +293,7 @@ class DextoAgent {
251
293
  try {
252
294
  if (this.services?.storageManager) {
253
295
  await this.services.storageManager.disconnect();
254
- import_logger.logger.debug("Storage manager disconnected successfully");
296
+ this.logger.debug("Storage manager disconnected successfully");
255
297
  }
256
298
  } catch (error) {
257
299
  const err = error instanceof Error ? error : new Error(String(error));
@@ -261,18 +303,20 @@ class DextoAgent {
261
303
  this._isStarted = false;
262
304
  if (shutdownErrors.length > 0) {
263
305
  const errorMessages = shutdownErrors.map((e) => e.message).join("; ");
264
- import_logger.logger.warn(`DextoAgent stopped with some errors: ${errorMessages}`);
306
+ this.logger.warn(`DextoAgent stopped with some errors: ${errorMessages}`);
265
307
  } else {
266
- import_logger.logger.info("DextoAgent stopped successfully.");
308
+ this.logger.info("DextoAgent stopped successfully.");
267
309
  }
268
310
  } catch (error) {
269
- import_logger.logger.error("Failed to stop DextoAgent", error);
311
+ this.logger.error("Failed to stop DextoAgent", {
312
+ error: error instanceof Error ? error.message : String(error)
313
+ });
270
314
  throw error;
271
315
  }
272
316
  }
273
317
  /**
274
318
  * Register an event subscriber that will be automatically re-subscribed on agent restart.
275
- * Subscribers are typically API layer components (WebSocket, Webhook handlers) that need
319
+ * Subscribers are typically API layer components (SSE, Webhook handlers) that need
276
320
  * to receive agent events. If the agent is already started, the subscriber is immediately subscribed.
277
321
  *
278
322
  * @param subscriber - Object implementing AgentEventSubscriber interface
@@ -314,12 +358,12 @@ class DextoAgent {
314
358
  */
315
359
  ensureStarted() {
316
360
  if (this._isStopped) {
317
- import_logger.logger.warn("Agent is stopped");
318
- throw import_errors.AgentError.stopped();
361
+ this.logger.warn("Agent is stopped");
362
+ throw import_errors2.AgentError.stopped();
319
363
  }
320
364
  if (!this._isStarted) {
321
- import_logger.logger.warn("Agent is not started");
322
- throw import_errors.AgentError.notStarted();
365
+ this.logger.warn("Agent is not started");
366
+ throw import_errors2.AgentError.notStarted();
323
367
  }
324
368
  }
325
369
  // ============= CORE AGENT FUNCTIONALITY =============
@@ -330,110 +374,347 @@ class DextoAgent {
330
374
  * @param textInput - The user's text message or query to process
331
375
  * @param imageDataInput - Optional image data and MIME type for multimodal input
332
376
  * @param fileDataInput - Optional file data and MIME type for file input
333
- * @param sessionId - Optional session ID for multi-session scenarios
377
+ * @param sessionId - Session ID for the conversation (required)
378
+ * @param stream - Whether to stream the response (default: false)
334
379
  * @returns Promise that resolves to the AI's response text, or null if no significant response
335
380
  * @throws Error if processing fails
336
381
  */
337
382
  async run(textInput, imageDataInput, fileDataInput, sessionId, stream = false) {
338
383
  this.ensureStarted();
339
- try {
340
- const targetSessionId = sessionId || this.currentDefaultSessionId;
341
- const llmConfig = this.stateManager.getLLMConfig(targetSessionId);
342
- const validation = (0, import_validation.validateInputForLLM)(
343
- {
344
- text: textInput,
345
- ...imageDataInput && { imageData: imageDataInput },
346
- ...fileDataInput && { fileData: fileDataInput }
347
- },
348
- {
349
- provider: llmConfig.provider,
350
- model: llmConfig.model
351
- }
352
- );
353
- (0, import_result_bridge.ensureOk)(validation);
354
- const existingSession = await this.sessionManager.getSession(targetSessionId);
355
- const session = existingSession || await this.sessionManager.createSession(targetSessionId);
356
- import_logger.logger.debug(
357
- `DextoAgent.run: sessionId=${targetSessionId}, textLength=${textInput?.length ?? 0}, hasImage=${Boolean(
358
- imageDataInput
359
- )}, hasFile=${Boolean(fileDataInput)}`
360
- );
361
- let finalText = textInput;
362
- let finalImageData = imageDataInput;
363
- if (textInput && textInput.includes("@")) {
364
- try {
365
- const resources = await this.resourceManager.list();
366
- const expansion = await (0, import_resources.expandMessageReferences)(
367
- textInput,
368
- resources,
369
- (uri) => this.resourceManager.read(uri)
370
- );
371
- if (expansion.unresolvedReferences.length > 0) {
372
- const unresolvedNames = expansion.unresolvedReferences.map((ref) => ref.originalRef).join(", ");
373
- import_logger.logger.warn(
374
- `Could not resolve ${expansion.unresolvedReferences.length} resource reference(s): ${unresolvedNames}`
375
- );
376
- }
377
- const MAX_EXPANDED_SIZE = 5 * 1024 * 1024;
378
- const expandedSize = Buffer.byteLength(expansion.expandedMessage, "utf-8");
379
- if (expandedSize > MAX_EXPANDED_SIZE) {
380
- import_logger.logger.warn(
381
- `Expanded message size (${(expandedSize / 1024 / 1024).toFixed(2)}MB) exceeds limit (${MAX_EXPANDED_SIZE / 1024 / 1024}MB). Content may be truncated.`
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 };
398
+ });
399
+ }
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)
382
442
  );
383
- }
384
- finalText = expansion.expandedMessage;
385
- if (expansion.extractedImages.length > 0 && !imageDataInput) {
386
- const firstImage = expansion.extractedImages[0];
387
- if (firstImage) {
388
- finalImageData = {
389
- image: firstImage.image,
390
- mimeType: firstImage.mimeType
391
- };
392
- import_logger.logger.debug(
393
- `Using extracted image: ${firstImage.name} (${firstImage.mimeType})`
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}`
394
447
  );
395
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
+ );
396
473
  }
397
- } catch (error) {
398
- import_logger.logger.error(
399
- `Failed to expand resource references: ${error instanceof Error ? error.message : String(error)}. Continuing with original message.`
474
+ }
475
+ if (!finalText.trim() && !finalImageData && !fileDataInput) {
476
+ this.logger.warn(
477
+ "Resource expansion resulted in empty content. Using original message."
400
478
  );
479
+ finalText = textInput;
401
480
  }
402
- }
403
- if (!finalText.trim() && !finalImageData && !fileDataInput) {
404
- import_logger.logger.warn(
405
- "Resource expansion resulted in empty content. Using original message."
481
+ const response = await session.run(
482
+ finalText,
483
+ finalImageData,
484
+ fileDataInput,
485
+ stream
406
486
  );
407
- finalText = textInput;
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
+ });
500
+ }
501
+ /**
502
+ * Generate a complete response (waits for full completion).
503
+ * This is the recommended method for non-streaming use cases.
504
+ *
505
+ * @param message The user's message
506
+ * @param options Configuration options (sessionId is required, imageData, fileData, signal are optional)
507
+ * @returns Promise that resolves to the complete response
508
+ *
509
+ * @example
510
+ * ```typescript
511
+ * const response = await agent.generate("What is 2+2?", { sessionId: "default" });
512
+ * console.log(response.content); // "4"
513
+ * console.log(response.usage.totalTokens); // 50
514
+ * ```
515
+ */
516
+ async generate(message, options) {
517
+ const events = [];
518
+ for await (const event of await this.stream(message, options)) {
519
+ events.push(event);
520
+ }
521
+ const errorEvent = events.find(
522
+ (e) => e.type === "llm:error"
523
+ );
524
+ if (errorEvent) {
525
+ if (errorEvent.error instanceof import_DextoRuntimeError.DextoRuntimeError) {
526
+ throw errorEvent.error;
408
527
  }
409
- void this.maybeGenerateTitle(targetSessionId, finalText, llmConfig);
410
- const response = await session.run(finalText, finalImageData, fileDataInput, stream);
411
- this.sessionManager.incrementMessageCount(session.id).catch(
412
- (error) => import_logger.logger.warn(
413
- `Failed to increment message count: ${error instanceof Error ? error.message : String(error)}`
414
- )
528
+ const llmConfig = this.stateManager.getLLMConfig(options.sessionId);
529
+ throw import_errors.LLMError.generationFailed(
530
+ errorEvent.error.message,
531
+ llmConfig.provider,
532
+ llmConfig.model
415
533
  );
416
- return response;
417
- } catch (error) {
418
- import_logger.logger.error(
419
- `Error during DextoAgent.run: ${error instanceof Error ? error.message : JSON.stringify(error)}`
534
+ }
535
+ const responseEvent = events.find((e) => e.type === "llm:response");
536
+ if (!responseEvent || responseEvent.type !== "llm:response") {
537
+ const llmConfig = this.stateManager.getLLMConfig(options.sessionId);
538
+ throw import_errors.LLMError.generationFailed(
539
+ "Stream did not complete successfully - no response received",
540
+ llmConfig.provider,
541
+ llmConfig.model
420
542
  );
421
- throw error;
422
543
  }
544
+ const toolCallEvents = events.filter(
545
+ (e) => e.type === "llm:tool-call"
546
+ );
547
+ const toolResultEvents = events.filter(
548
+ (e) => e.type === "llm:tool-result"
549
+ );
550
+ const toolCalls = toolCallEvents.map((tc) => {
551
+ const toolResult = toolResultEvents.find((tr) => tr.callId === tc.callId);
552
+ return {
553
+ toolName: tc.toolName,
554
+ args: tc.args,
555
+ callId: tc.callId || `tool_${Date.now()}`,
556
+ result: toolResult ? {
557
+ success: toolResult.success,
558
+ data: toolResult.sanitized
559
+ } : void 0
560
+ };
561
+ });
562
+ const messageId = `msg_${Date.now()}_${Math.random().toString(36).substring(7)}`;
563
+ const defaultUsage = {
564
+ inputTokens: 0,
565
+ outputTokens: 0,
566
+ totalTokens: 0
567
+ };
568
+ const usage = responseEvent.tokenUsage ?? defaultUsage;
569
+ return {
570
+ content: responseEvent.content,
571
+ reasoning: responseEvent.reasoning,
572
+ usage,
573
+ toolCalls,
574
+ sessionId: options.sessionId,
575
+ messageId
576
+ };
423
577
  }
424
578
  /**
425
- * Cancels the currently running turn for a session (or the default session).
579
+ * Stream a response (yields events as they arrive).
580
+ * This is the recommended method for real-time streaming UI updates.
581
+ *
582
+ * TODO: Refactor to move AsyncIterator down to LLM service level (Option 1).
583
+ * Streaming message API that returns core AgentEvents in real-time.
584
+ * Only emits STREAMING_EVENTS (tier 1 visibility) - events designed for real-time chat UIs.
585
+ *
586
+ * Events are forwarded directly from the AgentEventBus with no mapping layer,
587
+ * providing a unified event system across all API layers.
588
+ *
589
+ * @param message The user's message
590
+ * @param options Configuration options (sessionId is required, imageData, fileData, signal are optional)
591
+ * @returns AsyncIterator that yields StreamingEvent objects (core events with type property)
592
+ *
593
+ * @example
594
+ * ```typescript
595
+ * for await (const event of await agent.stream("Write a poem", { sessionId: "default" })) {
596
+ * if (event.type === 'llm:chunk') {
597
+ * process.stdout.write(event.content);
598
+ * }
599
+ * if (event.type === 'llm:tool-call') {
600
+ * console.log(`\n[Using ${event.toolName}]\n`);
601
+ * }
602
+ * }
603
+ * ```
604
+ */
605
+ async stream(message, options) {
606
+ this.ensureStarted();
607
+ if (!options.sessionId) {
608
+ throw new Error("sessionId is required in StreamOptions");
609
+ }
610
+ const sessionId = options.sessionId;
611
+ const imageData = options.imageData;
612
+ const fileData = options.fileData;
613
+ const signal = options.signal;
614
+ const eventQueue = [];
615
+ let completed = false;
616
+ let _streamError = null;
617
+ const controller = new AbortController();
618
+ const cleanupSignal = controller.signal;
619
+ const listeners = [];
620
+ const cleanupListeners = () => {
621
+ if (listeners.length === 0) {
622
+ return;
623
+ }
624
+ for (const { event, listener } of listeners) {
625
+ this.agentEventBus.off(event, listener);
626
+ }
627
+ listeners.length = 0;
628
+ };
629
+ if (signal) {
630
+ const abortHandler = () => {
631
+ cleanupListeners();
632
+ controller.abort();
633
+ };
634
+ signal.addEventListener("abort", abortHandler, { once: true });
635
+ }
636
+ for (const eventName of import_events.STREAMING_EVENTS) {
637
+ const listener = (data) => {
638
+ if (data.sessionId !== void 0 && data.sessionId !== sessionId) {
639
+ return;
640
+ }
641
+ eventQueue.push({ type: eventName, ...data });
642
+ if (eventName === "llm:response" || eventName === "llm:error" && !data.recoverable) {
643
+ completed = true;
644
+ }
645
+ };
646
+ this.agentEventBus.on(eventName, listener, {
647
+ signal: cleanupSignal
648
+ });
649
+ listeners.push({ event: eventName, listener });
650
+ }
651
+ const imageDataForRun = imageData ? {
652
+ image: typeof imageData.image === "string" ? imageData.image : imageData.image.toString(),
653
+ mimeType: imageData.mimeType || "image/png"
654
+ } : void 0;
655
+ const fileDataForRun = fileData ? {
656
+ data: typeof fileData.data === "string" ? fileData.data : fileData.data.toString(),
657
+ mimeType: fileData.mimeType,
658
+ ...fileData.filename && { filename: fileData.filename }
659
+ } : void 0;
660
+ this.run(message, imageDataForRun, fileDataForRun, sessionId, true).catch((error) => {
661
+ _streamError = error;
662
+ completed = true;
663
+ this.logger.error(
664
+ `Error in DextoAgent.stream: ${error instanceof Error ? error.message : String(error)}`
665
+ );
666
+ eventQueue.push({
667
+ type: "llm:error",
668
+ error,
669
+ recoverable: false,
670
+ context: "run_failed",
671
+ sessionId
672
+ });
673
+ });
674
+ const iterator = {
675
+ async next() {
676
+ while (!completed && eventQueue.length === 0) {
677
+ await new Promise((resolve) => setTimeout(resolve, 0));
678
+ if (signal?.aborted) {
679
+ cleanupListeners();
680
+ controller.abort();
681
+ return { done: true, value: void 0 };
682
+ }
683
+ }
684
+ if (eventQueue.length > 0) {
685
+ return { done: false, value: eventQueue.shift() };
686
+ }
687
+ if (completed) {
688
+ cleanupListeners();
689
+ controller.abort();
690
+ return { done: true, value: void 0 };
691
+ }
692
+ cleanupListeners();
693
+ return { done: true, value: void 0 };
694
+ },
695
+ async return() {
696
+ cleanupListeners();
697
+ controller.abort();
698
+ return { done: true, value: void 0 };
699
+ },
700
+ [Symbol.asyncIterator]() {
701
+ return iterator;
702
+ }
703
+ };
704
+ return iterator;
705
+ }
706
+ /**
707
+ * Cancels the currently running turn for a session.
426
708
  * Safe to call even if no run is in progress.
427
- * @param sessionId Optional session id; defaults to current default session
709
+ * @param sessionId Session id (required)
428
710
  * @returns true if a run was in progress and was signaled to abort; false otherwise
429
711
  */
430
712
  async cancel(sessionId) {
431
713
  this.ensureStarted();
432
- const targetSessionId = sessionId || this.currentDefaultSessionId;
433
- if (!sessionId && this.defaultSession && this.defaultSession.id === targetSessionId) {
434
- return this.defaultSession.cancel();
714
+ if (!sessionId || typeof sessionId !== "string") {
715
+ throw new Error("sessionId is required and must be a non-empty string");
435
716
  }
436
- const existing = await this.sessionManager.getSession(targetSessionId, false);
717
+ const existing = await this.sessionManager.getSession(sessionId, false);
437
718
  if (existing) {
438
719
  return existing.cancel();
439
720
  }
@@ -473,9 +754,6 @@ class DextoAgent {
473
754
  */
474
755
  async endSession(sessionId) {
475
756
  this.ensureStarted();
476
- if (sessionId === this.currentDefaultSessionId) {
477
- this.defaultSession = null;
478
- }
479
757
  return this.sessionManager.endSession(sessionId);
480
758
  }
481
759
  /**
@@ -485,9 +763,6 @@ class DextoAgent {
485
763
  */
486
764
  async deleteSession(sessionId) {
487
765
  this.ensureStarted();
488
- if (sessionId === this.currentDefaultSessionId) {
489
- this.defaultSession = null;
490
- }
491
766
  return this.sessionManager.deleteSession(sessionId);
492
767
  }
493
768
  /**
@@ -514,66 +789,63 @@ class DextoAgent {
514
789
  return await this.sessionManager.getSessionTitle(sessionId);
515
790
  }
516
791
  /**
517
- * Background task: generate and persist a session title using the same LLM.
518
- * Runs only for the first user message (messageCount === 0 and no existing title).
519
- * Never throws; timeboxed in the generator.
792
+ * Generate a title for a session on-demand.
793
+ * Uses the first user message content to generate a descriptive title.
794
+ *
795
+ * @param sessionId Session ID to generate title for
796
+ * @returns Promise that resolves to the generated title, or null if generation failed
520
797
  */
521
- async maybeGenerateTitle(sessionId, userText, llmConfig) {
522
- try {
523
- const metadata = await this.sessionManager.getSessionMetadata(sessionId);
524
- if (!metadata) {
525
- import_logger.logger.debug(
526
- `[SessionTitle] No session metadata available for ${sessionId}, skipping title generation`
527
- );
528
- return;
529
- }
530
- if (metadata.title) {
531
- import_logger.logger.debug(
532
- `[SessionTitle] Session ${sessionId} already has title '${metadata.title}', skipping`
533
- );
534
- return;
535
- }
536
- if (!userText || !userText.trim()) {
537
- import_logger.logger.debug(
538
- `[SessionTitle] User text empty for session ${sessionId}, skipping title generation`
539
- );
540
- return;
541
- }
542
- import_logger.logger.debug(
543
- `[SessionTitle] Checking title generation preconditions for session ${sessionId}`
544
- );
545
- const result = await (0, import_title_generator.generateSessionTitle)(
546
- llmConfig,
547
- llmConfig.router,
548
- this.toolManager,
549
- this.systemPromptManager,
550
- this.resourceManager,
551
- userText
798
+ async generateSessionTitle(sessionId) {
799
+ this.ensureStarted();
800
+ const metadata = await this.sessionManager.getSessionMetadata(sessionId);
801
+ if (!metadata) {
802
+ throw import_session.SessionError.notFound(sessionId);
803
+ }
804
+ if (metadata.title) {
805
+ this.logger.debug(
806
+ `[SessionTitle] Session ${sessionId} already has title '${metadata.title}'`
552
807
  );
553
- if (result.error) {
554
- import_logger.logger.debug(
555
- `[SessionTitle] LLM title generation failed for ${sessionId}: ${result.error}${result.timedOut ? " (timeout)" : ""}`
556
- );
557
- }
558
- let title = result.title;
559
- if (!title) {
560
- title = (0, import_title_generator.deriveHeuristicTitle)(userText);
561
- if (title) {
562
- import_logger.logger.info(`[SessionTitle] Using heuristic title for ${sessionId}: ${title}`);
563
- } else {
564
- import_logger.logger.debug(
565
- `[SessionTitle] No suitable title derived for session ${sessionId}`
566
- );
567
- return;
568
- }
808
+ return metadata.title;
809
+ }
810
+ const session = await this.sessionManager.getSession(sessionId);
811
+ if (!session) {
812
+ throw import_session.SessionError.notFound(sessionId);
813
+ }
814
+ const history = await session.getHistory();
815
+ const firstUserMsg = history.find((m) => m.role === "user");
816
+ if (!firstUserMsg) {
817
+ this.logger.debug(`[SessionTitle] No user message found for session ${sessionId}`);
818
+ return null;
819
+ }
820
+ const userText = typeof firstUserMsg.content === "string" ? firstUserMsg.content : firstUserMsg.content?.filter((p) => p.type === "text").map((p) => p.text).join(" ");
821
+ if (!userText || !userText.trim()) {
822
+ this.logger.debug(`[SessionTitle] Empty user text for session ${sessionId}`);
823
+ return null;
824
+ }
825
+ const llmConfig = this.getEffectiveConfig(sessionId).llm;
826
+ const result = await (0, import_title_generator.generateSessionTitle)(
827
+ llmConfig,
828
+ llmConfig.router,
829
+ this.toolManager,
830
+ this.systemPromptManager,
831
+ this.resourceManager,
832
+ userText,
833
+ this.logger
834
+ );
835
+ let title = result.title;
836
+ if (!title) {
837
+ title = (0, import_title_generator.deriveHeuristicTitle)(userText);
838
+ if (title) {
839
+ this.logger.info(`[SessionTitle] Using heuristic title for ${sessionId}: ${title}`);
569
840
  } else {
570
- import_logger.logger.info(`[SessionTitle] Generated LLM title for ${sessionId}: ${title}`);
841
+ this.logger.debug(`[SessionTitle] No suitable title derived for ${sessionId}`);
842
+ return null;
571
843
  }
572
- await this.sessionManager.setSessionTitle(sessionId, title, { ifUnsetOnly: true });
573
- this.agentEventBus.emit("dexto:sessionTitleUpdated", { sessionId, title });
574
- } catch (err) {
575
- import_logger.logger.silly(`Title generation skipped/failed for ${sessionId}: ${String(err)}`);
844
+ } else {
845
+ this.logger.info(`[SessionTitle] Generated LLM title for ${sessionId}: ${title}`);
576
846
  }
847
+ await this.sessionManager.setSessionTitle(sessionId, title, { ifUnsetOnly: true });
848
+ return title;
577
849
  }
578
850
  /**
579
851
  * Gets the conversation history for a specific session.
@@ -594,14 +866,16 @@ class DextoAgent {
594
866
  return await Promise.all(
595
867
  history.map(async (message) => ({
596
868
  ...message,
597
- content: await (0, import_utils.expandBlobReferences)(message.content, this.resourceManager).catch(
598
- (error) => {
599
- import_logger.logger.warn(
600
- `Failed to expand blob references in message: ${error instanceof Error ? error.message : String(error)}`
601
- );
602
- return message.content;
603
- }
604
- )
869
+ content: await (0, import_utils.expandBlobReferences)(
870
+ message.content,
871
+ this.resourceManager,
872
+ this.logger
873
+ ).catch((error) => {
874
+ this.logger.warn(
875
+ `Failed to expand blob references in message: ${error instanceof Error ? error.message : String(error)}`
876
+ );
877
+ return message.content;
878
+ })
605
879
  }))
606
880
  );
607
881
  }
@@ -627,88 +901,23 @@ class DextoAgent {
627
901
  return await this.searchService.searchSessions(query);
628
902
  }
629
903
  /**
630
- * Loads a session as the new "default" session for this agent.
631
- * All subsequent operations that don't specify a session ID will use this session.
632
- * This provides a clean "current working session" pattern for API users.
633
- *
634
- * @param sessionId The session ID to load as default, or null to reset to original default
635
- * @throws Error if session doesn't exist
636
- *
637
- * @example
638
- * ```typescript
639
- * // Load a specific session as default
640
- * await agent.loadSessionAsDefault('project-alpha');
641
- * await agent.run("What's the status?"); // Uses project-alpha session
642
- *
643
- * // Reset to original default
644
- * await agent.loadSessionAsDefault(null);
645
- * await agent.run("Hello"); // Uses 'default' session
646
- * ```
647
- */
648
- async loadSessionAsDefault(sessionId = null) {
649
- this.ensureStarted();
650
- if (sessionId === null) {
651
- this.currentDefaultSessionId = "default";
652
- this.defaultSession = null;
653
- import_logger.logger.debug("Agent default session reset to original default");
654
- return;
655
- }
656
- const session = await this.sessionManager.getSession(sessionId);
657
- if (!session) {
658
- throw import_session.SessionError.notFound(sessionId);
659
- }
660
- this.currentDefaultSessionId = sessionId;
661
- this.defaultSession = null;
662
- import_logger.logger.info(`Agent default session changed to: ${sessionId}`);
663
- }
664
- /**
665
- * Gets the currently loaded default session ID.
666
- * This reflects the session loaded via loadSession().
667
- *
668
- * @returns The current default session ID
669
- */
670
- getCurrentSessionId() {
671
- this.ensureStarted();
672
- return this.currentDefaultSessionId;
673
- }
674
- /**
675
- * Gets the currently loaded default session.
676
- * This respects the session loaded via loadSession().
677
- *
678
- * @returns The current default ChatSession
679
- */
680
- async getDefaultSession() {
681
- this.ensureStarted();
682
- if (!this.defaultSession || this.defaultSession.id !== this.currentDefaultSessionId) {
683
- this.defaultSession = await this.sessionManager.createSession(
684
- this.currentDefaultSessionId
685
- );
686
- }
687
- return this.defaultSession;
688
- }
689
- /**
690
- * Resets the conversation history for a specific session or the default session.
904
+ * Resets the conversation history for a specific session.
691
905
  * Keeps the session alive but the conversation history is cleared.
692
- * @param sessionId Optional session ID. If not provided, resets the currently loaded default session.
906
+ * @param sessionId Session ID (required)
693
907
  */
694
908
  async resetConversation(sessionId) {
695
909
  this.ensureStarted();
910
+ if (!sessionId || typeof sessionId !== "string") {
911
+ throw new Error("sessionId is required and must be a non-empty string");
912
+ }
696
913
  try {
697
- const targetSessionId = sessionId || this.currentDefaultSessionId;
698
- if (!sessionId) {
699
- if (!this.defaultSession || this.defaultSession.id !== this.currentDefaultSessionId) {
700
- this.defaultSession = await this.sessionManager.createSession(
701
- this.currentDefaultSessionId
702
- );
703
- }
704
- }
705
- await this.sessionManager.resetSession(targetSessionId);
706
- import_logger.logger.info(`DextoAgent conversation reset for session: ${targetSessionId}`);
707
- this.agentEventBus.emit("dexto:conversationReset", {
708
- sessionId: targetSessionId
914
+ await this.sessionManager.resetSession(sessionId);
915
+ this.logger.info(`DextoAgent conversation reset for session: ${sessionId}`);
916
+ this.agentEventBus.emit("session:reset", {
917
+ sessionId
709
918
  });
710
919
  } catch (error) {
711
- import_logger.logger.error(
920
+ this.logger.error(
712
921
  `Error during DextoAgent.resetConversation: ${error instanceof Error ? error.message : String(error)}`
713
922
  );
714
923
  throw error;
@@ -762,22 +971,24 @@ class DextoAgent {
762
971
  */
763
972
  async switchLLM(llmUpdates, sessionId) {
764
973
  this.ensureStarted();
765
- import_logger.logger.debug(`DextoAgent.switchLLM: llmUpdates: ${(0, import_safe_stringify.safeStringify)(llmUpdates)}`);
974
+ this.logger.debug(`DextoAgent.switchLLM: llmUpdates: ${(0, import_safe_stringify.safeStringify)(llmUpdates)}`);
766
975
  const parseResult = import_schemas.LLMUpdatesSchema.safeParse(llmUpdates);
767
976
  if (!parseResult.success) {
768
977
  const validation = (0, import_result.fail)((0, import_result.zodToIssues)(parseResult.error, "error"));
769
- (0, import_result_bridge.ensureOk)(validation);
978
+ (0, import_result_bridge.ensureOk)(validation, this.logger);
770
979
  throw new Error("Unreachable");
771
980
  }
772
981
  const validatedUpdates = parseResult.data;
773
982
  const currentLLMConfig = sessionId ? this.stateManager.getRuntimeConfig(sessionId).llm : this.stateManager.getRuntimeConfig().llm;
774
- const result = (0, import_resolver.resolveAndValidateLLMConfig)(currentLLMConfig, validatedUpdates);
775
- const validatedConfig = (0, import_result_bridge.ensureOk)(result);
983
+ const result = (0, import_resolver.resolveAndValidateLLMConfig)(currentLLMConfig, validatedUpdates, this.logger);
984
+ const validatedConfig = (0, import_result_bridge.ensureOk)(result, this.logger);
776
985
  await this.performLLMSwitch(validatedConfig, sessionId);
777
- import_logger.logger.info(`DextoAgent.switchLLM: LLM switched to: ${(0, import_safe_stringify.safeStringify)(validatedConfig)}`);
986
+ this.logger.info(
987
+ `DextoAgent.switchLLM: LLM switched to: ${(0, import_safe_stringify.safeStringify)(validatedConfig)}`
988
+ );
778
989
  const warnings = result.issues.filter((issue) => issue.severity === "warning");
779
990
  if (warnings.length > 0) {
780
- import_logger.logger.warn(
991
+ this.logger.warn(
781
992
  `LLM switch completed with warnings: ${warnings.map((w) => w.message).join(", ")}`
782
993
  );
783
994
  }
@@ -801,7 +1012,7 @@ class DextoAgent {
801
1012
  }
802
1013
  await this.sessionManager.switchLLMForSpecificSession(validatedConfig, sessionScope);
803
1014
  } else {
804
- await this.sessionManager.switchLLMForDefaultSession(validatedConfig);
1015
+ this.logger.debug("LLM config updated at agent level (no active session switches)");
805
1016
  }
806
1017
  }
807
1018
  /**
@@ -915,36 +1126,40 @@ class DextoAgent {
915
1126
  this.ensureStarted();
916
1127
  const existingServerNames = Object.keys(this.stateManager.getRuntimeConfig().mcpServers);
917
1128
  const validation = (0, import_resolver2.resolveAndValidateMcpServerConfig)(name, config, existingServerNames);
918
- const validatedConfig = (0, import_result_bridge.ensureOk)(validation);
1129
+ const validatedConfig = (0, import_result_bridge.ensureOk)(validation, this.logger);
919
1130
  this.stateManager.addMcpServer(name, validatedConfig);
920
1131
  try {
921
1132
  await this.mcpManager.connectServer(name, validatedConfig);
922
1133
  await this.toolManager.refresh();
923
- this.agentEventBus.emit("dexto:mcpServerConnected", {
1134
+ this.agentEventBus.emit("mcp:server-connected", {
924
1135
  name,
925
1136
  success: true
926
1137
  });
927
- this.agentEventBus.emit("dexto:availableToolsUpdated", {
1138
+ this.agentEventBus.emit("tools:available-updated", {
928
1139
  tools: Object.keys(await this.toolManager.getAllTools()),
929
1140
  source: "mcp"
930
1141
  });
931
- import_logger.logger.info(`DextoAgent: Successfully added and connected to MCP server '${name}'.`);
1142
+ this.logger.info(
1143
+ `DextoAgent: Successfully added and connected to MCP server '${name}'.`
1144
+ );
932
1145
  const warnings = validation.issues.filter((i) => i.severity === "warning");
933
1146
  if (warnings.length > 0) {
934
- import_logger.logger.warn(
1147
+ this.logger.warn(
935
1148
  `MCP server connected with warnings: ${warnings.map((w) => w.message).join(", ")}`
936
1149
  );
937
1150
  }
938
1151
  } catch (error) {
939
1152
  const errorMessage = error instanceof Error ? error.message : String(error);
940
- import_logger.logger.error(`DextoAgent: Failed to connect to MCP server '${name}': ${errorMessage}`);
1153
+ this.logger.error(
1154
+ `DextoAgent: Failed to connect to MCP server '${name}': ${errorMessage}`
1155
+ );
941
1156
  this.stateManager.removeMcpServer(name);
942
- this.agentEventBus.emit("dexto:mcpServerConnected", {
1157
+ this.agentEventBus.emit("mcp:server-connected", {
943
1158
  name,
944
1159
  success: false,
945
1160
  error: errorMessage
946
1161
  });
947
- throw import_errors2.MCPError.connectionFailed(name, errorMessage);
1162
+ throw import_errors3.MCPError.connectionFailed(name, errorMessage);
948
1163
  }
949
1164
  }
950
1165
  /**
@@ -966,20 +1181,22 @@ class DextoAgent {
966
1181
  async restartMcpServer(name) {
967
1182
  this.ensureStarted();
968
1183
  try {
969
- import_logger.logger.info(`DextoAgent: Restarting MCP server '${name}'...`);
1184
+ this.logger.info(`DextoAgent: Restarting MCP server '${name}'...`);
970
1185
  await this.mcpManager.restartServer(name);
971
1186
  await this.toolManager.refresh();
972
- this.agentEventBus.emit("dexto:mcpServerRestarted", {
1187
+ this.agentEventBus.emit("mcp:server-restarted", {
973
1188
  serverName: name
974
1189
  });
975
- this.agentEventBus.emit("dexto:availableToolsUpdated", {
1190
+ this.agentEventBus.emit("tools:available-updated", {
976
1191
  tools: Object.keys(await this.toolManager.getAllTools()),
977
1192
  source: "mcp"
978
1193
  });
979
- import_logger.logger.info(`DextoAgent: Successfully restarted MCP server '${name}'.`);
1194
+ this.logger.info(`DextoAgent: Successfully restarted MCP server '${name}'.`);
980
1195
  } catch (error) {
981
1196
  const errorMessage = error instanceof Error ? error.message : String(error);
982
- import_logger.logger.error(`DextoAgent: Failed to restart MCP server '${name}': ${errorMessage}`);
1197
+ this.logger.error(
1198
+ `DextoAgent: Failed to restart MCP server '${name}': ${errorMessage}`
1199
+ );
983
1200
  throw error;
984
1201
  }
985
1202
  }
@@ -1094,10 +1311,10 @@ class DextoAgent {
1094
1311
  */
1095
1312
  async getSystemPrompt() {
1096
1313
  this.ensureStarted();
1097
- const context = {
1314
+ const context2 = {
1098
1315
  mcpManager: this.mcpManager
1099
1316
  };
1100
- return await this.systemPromptManager.build(context);
1317
+ return await this.systemPromptManager.build(context2);
1101
1318
  }
1102
1319
  /**
1103
1320
  * Lists all available prompts from all providers (MCP, internal, starter, custom).
@@ -1171,7 +1388,8 @@ class DextoAgent {
1171
1388
  /**
1172
1389
  * Gets the effective configuration for a session or the default configuration.
1173
1390
  * @param sessionId Optional session ID. If not provided, returns default config.
1174
- * @returns The effective configuration object
1391
+ * @returns The effective configuration object (validated with defaults applied)
1392
+ * @remarks Requires agent to be started. Use `agent.config` for pre-start access.
1175
1393
  */
1176
1394
  getEffectiveConfig(sessionId) {
1177
1395
  this.ensureStarted();
@@ -1185,89 +1403,53 @@ class DextoAgent {
1185
1403
  */
1186
1404
  getAgentFilePath() {
1187
1405
  if (!this.configPath) {
1188
- throw import_errors.AgentError.noConfigPath();
1406
+ throw import_errors2.AgentError.noConfigPath();
1189
1407
  }
1190
1408
  return this.configPath;
1191
1409
  }
1192
1410
  /**
1193
- * Reloads the agent configuration from disk.
1194
- * This will re-read the config file, validate it, and detect what changed.
1195
- * Most configuration changes require a full agent restart to take effect.
1196
- *
1197
- * To apply changes: stop the agent and start it again with the new config.
1411
+ * Reloads the agent configuration with a new config object.
1412
+ * Validates the new config, detects what changed, and automatically
1413
+ * restarts the agent if necessary to apply the changes.
1198
1414
  *
1199
- * @returns Object containing list of changes that require restart
1200
- * @throws Error if config file cannot be read or is invalid
1415
+ * @param newConfig The new agent configuration to apply
1416
+ * @returns Object containing whether agent was restarted and list of changes applied
1417
+ * @throws Error if config is invalid or restart fails
1201
1418
  *
1202
1419
  * TODO: improve hot reload capabilites so that we don't always require a restart
1203
1420
  */
1204
- async reloadConfig() {
1205
- if (!this.configPath) {
1206
- throw import_errors.AgentError.noConfigPath();
1207
- }
1208
- import_logger.logger.info(`Reloading agent configuration from: ${this.configPath}`);
1421
+ async reload(newConfig) {
1422
+ this.logger.info("Reloading agent configuration");
1209
1423
  const oldConfig = this.config;
1210
- const newConfig = await (0, import_loader.loadAgentConfig)(this.configPath);
1211
1424
  const validated = import_schemas2.AgentConfigSchema.parse(newConfig);
1212
- const restartRequired = this.detectRestartRequiredChanges(oldConfig, validated);
1425
+ const changesApplied = this.detectConfigChanges(oldConfig, validated);
1213
1426
  this.config = validated;
1214
- if (restartRequired.length > 0) {
1215
- import_logger.logger.warn(
1216
- `Configuration updated. Restart required to apply: ${restartRequired.join(", ")}`
1427
+ let restarted = false;
1428
+ if (changesApplied.length > 0) {
1429
+ this.logger.info(
1430
+ `Configuration changed. Restarting agent to apply: ${changesApplied.join(", ")}`
1217
1431
  );
1432
+ await this.restart();
1433
+ restarted = true;
1434
+ this.logger.info("Agent restarted successfully with new configuration");
1218
1435
  } else {
1219
- import_logger.logger.info("Agent configuration reloaded successfully (no changes detected)");
1436
+ this.logger.info("Agent configuration reloaded successfully (no changes detected)");
1220
1437
  }
1221
1438
  return {
1222
- restartRequired
1439
+ restarted,
1440
+ changesApplied
1223
1441
  };
1224
1442
  }
1225
- /**
1226
- * Updates and saves the agent configuration to disk.
1227
- * This merges the updates with the raw config from disk, validates, and writes to file.
1228
- * IMPORTANT: This preserves environment variable placeholders (e.g., $OPENAI_API_KEY)
1229
- * to avoid leaking secrets into the config file.
1230
- * @param updates Partial configuration updates to apply
1231
- * @param targetPath Optional path to save to (defaults to current config path)
1232
- * @returns Object containing list of changes that require restart
1233
- * @throws Error if validation fails or file cannot be written
1234
- */
1235
- async updateAndSaveConfig(updates, targetPath) {
1236
- const path = targetPath || this.configPath;
1237
- if (!path) {
1238
- throw import_errors.AgentError.noConfigPath();
1239
- }
1240
- import_logger.logger.info(`Updating and saving agent configuration to: ${path}`);
1241
- const rawYaml = await import_fs.promises.readFile(path, "utf-8");
1242
- const doc = (0, import_yaml.parseDocument)(rawYaml);
1243
- const rawConfig = doc.toJSON();
1244
- const updatedRawConfig = { ...rawConfig, ...updates };
1245
- const parsed = import_schemas2.AgentConfigSchema.safeParse(updatedRawConfig);
1246
- if (!parsed.success) {
1247
- const result = (0, import_result.fail)((0, import_result.zodToIssues)(parsed.error, "error"));
1248
- throw new import_DextoValidationError.DextoValidationError(result.issues);
1249
- }
1250
- for (const [key, value] of Object.entries(updates)) {
1251
- doc.set(key, value);
1252
- }
1253
- const yamlContent = String(doc);
1254
- const tmpPath = `${path}.tmp`;
1255
- await import_fs.promises.writeFile(tmpPath, yamlContent, "utf-8");
1256
- await import_fs.promises.rename(tmpPath, path);
1257
- const reloadResult = await this.reloadConfig();
1258
- import_logger.logger.info(`Agent configuration saved to: ${path}`);
1259
- return reloadResult;
1260
- }
1261
1443
  /**
1262
1444
  * Detects configuration changes that require a full agent restart.
1445
+ * Pure comparison logic - no file I/O.
1263
1446
  * Returns an array of change descriptions.
1264
1447
  *
1265
1448
  * @param oldConfig Previous validated configuration
1266
1449
  * @param newConfig New validated configuration
1267
1450
  * @returns Array of restart-required change descriptions
1268
- * @private
1269
1451
  */
1270
- detectRestartRequiredChanges(oldConfig, newConfig) {
1452
+ detectConfigChanges(oldConfig, newConfig) {
1271
1453
  const changes = [];
1272
1454
  if (JSON.stringify(oldConfig.storage) !== JSON.stringify(newConfig.storage)) {
1273
1455
  changes.push("Storage backend");
@@ -1292,6 +1474,58 @@ class DextoAgent {
1292
1474
  }
1293
1475
  return changes;
1294
1476
  }
1477
+ // ============= APPROVAL HANDLER API =============
1478
+ /**
1479
+ * Set a custom approval handler for manual approval mode.
1480
+ *
1481
+ * When `toolConfirmation.mode` is set to 'manual', an approval handler must be
1482
+ * provided to process tool confirmation requests. The handler will be called
1483
+ * whenever a tool execution requires user approval.
1484
+ *
1485
+ * The handler receives an approval request and must return a promise that resolves
1486
+ * to an approval response with the user's decision (approved/denied/cancelled).
1487
+ *
1488
+ * @param handler The approval handler function
1489
+ *
1490
+ * @example
1491
+ * ```typescript
1492
+ * import { ApprovalStatus } from '@dexto/core';
1493
+ *
1494
+ * agent.setApprovalHandler(async (request) => {
1495
+ * // Present approval request to user (CLI, UI, webhook, etc.)
1496
+ * console.log(`Approve tool: ${request.metadata.toolName}?`);
1497
+ * console.log(`Args: ${JSON.stringify(request.metadata.args)}`);
1498
+ *
1499
+ * // Collect user's decision (this is just an example)
1500
+ * const approved = await getUserInput();
1501
+ *
1502
+ * return {
1503
+ * approvalId: request.approvalId,
1504
+ * status: approved ? ApprovalStatus.APPROVED : ApprovalStatus.DENIED,
1505
+ * sessionId: request.sessionId,
1506
+ * };
1507
+ * });
1508
+ * ```
1509
+ */
1510
+ setApprovalHandler(handler) {
1511
+ this.approvalHandler = handler;
1512
+ if (this._isStarted && this.services) {
1513
+ this.services.approvalManager.setHandler(handler);
1514
+ }
1515
+ this.logger.debug("Approval handler registered");
1516
+ }
1517
+ /**
1518
+ * Clear the current approval handler.
1519
+ *
1520
+ * After calling this, manual approval mode will fail if a tool requires approval.
1521
+ */
1522
+ clearApprovalHandler() {
1523
+ this.approvalHandler = void 0;
1524
+ if (this._isStarted && this.services) {
1525
+ this.services.approvalManager.clearHandler();
1526
+ }
1527
+ this.logger.debug("Approval handler cleared");
1528
+ }
1295
1529
  // ============= AGENT MANAGEMENT =============
1296
1530
  // Note: Agent management methods have been moved to the Dexto orchestrator class.
1297
1531
  // See: /packages/core/src/Dexto.ts