@dexto/core 1.2.6 → 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 (515) hide show
  1. package/README.md +55 -13
  2. package/dist/agent/DextoAgent.cjs +627 -228
  3. package/dist/agent/DextoAgent.d.ts +157 -34
  4. package/dist/agent/DextoAgent.d.ts.map +1 -1
  5. package/dist/agent/DextoAgent.js +625 -227
  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 +4 -1
  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 +7 -3
  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 -11
  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 +20 -5
  36. package/dist/approval/schemas.d.ts +127 -52
  37. package/dist/approval/schemas.d.ts.map +1 -1
  38. package/dist/approval/schemas.js +21 -6
  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/factory.cjs → context/compression/overflow.cjs} +20 -21
  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 +287 -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 +287 -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 +185 -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.cjs +1 -0
  81. package/dist/errors/types.d.ts +4 -2
  82. package/dist/errors/types.d.ts.map +1 -1
  83. package/dist/errors/types.js +2 -1
  84. package/dist/events/index.cjs +22 -2
  85. package/dist/events/index.d.ts +170 -62
  86. package/dist/events/index.d.ts.map +1 -1
  87. package/dist/events/index.js +23 -3
  88. package/dist/filesystem/error-codes.js +1 -1
  89. package/dist/filesystem/errors.js +1 -1
  90. package/dist/filesystem/filesystem-service.js +1 -1
  91. package/dist/filesystem/index.js +1 -1
  92. package/dist/filesystem/path-validator.js +1 -1
  93. package/dist/index.browser.cjs +23 -8
  94. package/dist/index.browser.d.ts +4 -3
  95. package/dist/index.browser.d.ts.map +1 -1
  96. package/dist/index.browser.js +20 -3
  97. package/dist/index.js +1 -1
  98. package/dist/llm/error-codes.cjs +0 -1
  99. package/dist/llm/error-codes.d.ts +0 -1
  100. package/dist/llm/error-codes.d.ts.map +1 -1
  101. package/dist/llm/error-codes.js +1 -2
  102. package/dist/llm/errors.cjs +10 -10
  103. package/dist/llm/errors.d.ts +5 -6
  104. package/dist/llm/errors.d.ts.map +1 -1
  105. package/dist/llm/errors.js +12 -12
  106. package/dist/llm/executor/stream-processor.cjs +367 -0
  107. package/dist/llm/executor/stream-processor.d.ts +55 -0
  108. package/dist/llm/executor/stream-processor.d.ts.map +1 -0
  109. package/dist/llm/executor/stream-processor.js +344 -0
  110. package/dist/llm/executor/tool-output-truncator.cjs +75 -0
  111. package/dist/llm/executor/tool-output-truncator.d.ts +27 -0
  112. package/dist/llm/executor/tool-output-truncator.d.ts.map +1 -0
  113. package/dist/llm/executor/tool-output-truncator.js +48 -0
  114. package/dist/llm/executor/turn-executor.cjs +753 -0
  115. package/dist/llm/executor/turn-executor.d.ts +166 -0
  116. package/dist/llm/executor/turn-executor.d.ts.map +1 -0
  117. package/dist/llm/executor/turn-executor.js +684 -0
  118. package/dist/llm/executor/types.d.ts +27 -0
  119. package/dist/llm/executor/types.d.ts.map +1 -0
  120. package/dist/llm/formatters/vercel.cjs +20 -186
  121. package/dist/llm/formatters/vercel.d.ts +2 -14
  122. package/dist/llm/formatters/vercel.d.ts.map +1 -1
  123. package/dist/llm/formatters/vercel.js +19 -185
  124. package/dist/llm/registry.cjs +36 -45
  125. package/dist/llm/registry.d.ts +53 -39
  126. package/dist/llm/registry.d.ts.map +1 -1
  127. package/dist/llm/registry.js +34 -42
  128. package/dist/llm/resolver.cjs +1 -31
  129. package/dist/llm/resolver.d.ts.map +1 -1
  130. package/dist/llm/resolver.js +2 -34
  131. package/dist/llm/schemas.cjs +2 -17
  132. package/dist/llm/schemas.d.ts +10 -23
  133. package/dist/llm/schemas.d.ts.map +1 -1
  134. package/dist/llm/schemas.js +5 -22
  135. package/dist/llm/services/factory.cjs +3 -92
  136. package/dist/llm/services/factory.d.ts +14 -4
  137. package/dist/llm/services/factory.d.ts.map +1 -1
  138. package/dist/llm/services/factory.js +4 -83
  139. package/dist/llm/services/test-utils.integration.cjs +6 -8
  140. package/dist/llm/services/test-utils.integration.d.ts.map +1 -1
  141. package/dist/llm/services/test-utils.integration.js +7 -9
  142. package/dist/llm/services/types.d.ts +1 -28
  143. package/dist/llm/services/types.d.ts.map +1 -1
  144. package/dist/llm/services/vercel.cjs +54 -468
  145. package/dist/llm/services/vercel.d.ts +38 -21
  146. package/dist/llm/services/vercel.d.ts.map +1 -1
  147. package/dist/llm/services/vercel.js +56 -475
  148. package/dist/llm/types.cjs +0 -3
  149. package/dist/llm/types.d.ts +8 -8
  150. package/dist/llm/types.d.ts.map +1 -1
  151. package/dist/llm/types.js +1 -3
  152. package/dist/llm/validation.js +1 -1
  153. package/dist/logger/browser.js +1 -1
  154. package/dist/logger/factory.js +1 -1
  155. package/dist/logger/index.js +1 -1
  156. package/dist/logger/logger.js +1 -1
  157. package/dist/logger/v2/dexto-logger.cjs +34 -6
  158. package/dist/logger/v2/dexto-logger.d.ts +20 -2
  159. package/dist/logger/v2/dexto-logger.d.ts.map +1 -1
  160. package/dist/logger/v2/dexto-logger.js +35 -7
  161. package/dist/logger/v2/error-codes.js +1 -1
  162. package/dist/logger/v2/errors.js +1 -1
  163. package/dist/logger/v2/schemas.cjs +1 -1
  164. package/dist/logger/v2/schemas.js +2 -2
  165. package/dist/logger/v2/test-utils.cjs +70 -0
  166. package/dist/logger/v2/test-utils.d.ts +17 -0
  167. package/dist/logger/v2/test-utils.d.ts.map +1 -0
  168. package/dist/logger/v2/test-utils.js +46 -0
  169. package/dist/logger/v2/transport-factory.js +1 -1
  170. package/dist/logger/v2/transports/console-transport.js +1 -1
  171. package/dist/logger/v2/transports/file-transport.cjs +6 -0
  172. package/dist/logger/v2/transports/file-transport.d.ts +4 -0
  173. package/dist/logger/v2/transports/file-transport.d.ts.map +1 -1
  174. package/dist/logger/v2/transports/file-transport.js +7 -1
  175. package/dist/logger/v2/types.cjs +1 -0
  176. package/dist/logger/v2/types.d.ts +18 -2
  177. package/dist/logger/v2/types.d.ts.map +1 -1
  178. package/dist/logger/v2/types.js +2 -1
  179. package/dist/mcp/error-codes.cjs +1 -0
  180. package/dist/mcp/error-codes.d.ts +1 -0
  181. package/dist/mcp/error-codes.d.ts.map +1 -1
  182. package/dist/mcp/error-codes.js +2 -1
  183. package/dist/mcp/errors.cjs +13 -0
  184. package/dist/mcp/errors.d.ts +7 -0
  185. package/dist/mcp/errors.d.ts.map +1 -1
  186. package/dist/mcp/errors.js +14 -1
  187. package/dist/mcp/manager.cjs +4 -0
  188. package/dist/mcp/manager.d.ts.map +1 -1
  189. package/dist/mcp/manager.js +5 -1
  190. package/dist/mcp/mcp-client.js +1 -1
  191. package/dist/mcp/resolver.js +1 -1
  192. package/dist/mcp/schemas.cjs +6 -0
  193. package/dist/mcp/schemas.d.ts +52 -0
  194. package/dist/mcp/schemas.d.ts.map +1 -1
  195. package/dist/mcp/schemas.js +6 -1
  196. package/dist/memory/error-codes.js +1 -1
  197. package/dist/memory/errors.js +1 -1
  198. package/dist/memory/index.js +1 -1
  199. package/dist/memory/manager.js +1 -1
  200. package/dist/memory/schemas.d.ts +2 -2
  201. package/dist/memory/schemas.js +1 -1
  202. package/dist/plugins/builtins/content-policy.js +1 -1
  203. package/dist/plugins/builtins/response-sanitizer.js +1 -1
  204. package/dist/plugins/error-codes.cjs +1 -0
  205. package/dist/plugins/error-codes.d.ts +3 -1
  206. package/dist/plugins/error-codes.d.ts.map +1 -1
  207. package/dist/plugins/error-codes.js +2 -1
  208. package/dist/plugins/index.js +1 -1
  209. package/dist/plugins/loader.cjs +25 -5
  210. package/dist/plugins/loader.d.ts.map +1 -1
  211. package/dist/plugins/loader.js +26 -6
  212. package/dist/plugins/manager.js +1 -1
  213. package/dist/plugins/registrations/builtins.js +1 -1
  214. package/dist/plugins/schemas.d.ts +3 -3
  215. package/dist/plugins/schemas.js +1 -1
  216. package/dist/plugins/types.d.ts +0 -1
  217. package/dist/plugins/types.d.ts.map +1 -1
  218. package/dist/process/command-validator.js +1 -1
  219. package/dist/process/error-codes.js +1 -1
  220. package/dist/process/errors.js +1 -1
  221. package/dist/process/index.js +1 -1
  222. package/dist/process/process-service.cjs +78 -26
  223. package/dist/process/process-service.d.ts +6 -1
  224. package/dist/process/process-service.d.ts.map +1 -1
  225. package/dist/process/process-service.js +79 -27
  226. package/dist/process/types.d.ts +2 -2
  227. package/dist/process/types.d.ts.map +1 -1
  228. package/dist/prompts/error-codes.cjs +1 -0
  229. package/dist/prompts/error-codes.d.ts +2 -1
  230. package/dist/prompts/error-codes.d.ts.map +1 -1
  231. package/dist/prompts/error-codes.js +2 -1
  232. package/dist/prompts/errors.cjs +15 -0
  233. package/dist/prompts/errors.d.ts +4 -0
  234. package/dist/prompts/errors.d.ts.map +1 -1
  235. package/dist/prompts/errors.js +16 -1
  236. package/dist/prompts/index.js +1 -1
  237. package/dist/prompts/name-validation.js +1 -1
  238. package/dist/prompts/prompt-manager.cjs +13 -2
  239. package/dist/prompts/prompt-manager.d.ts +7 -0
  240. package/dist/prompts/prompt-manager.d.ts.map +1 -1
  241. package/dist/prompts/prompt-manager.js +14 -3
  242. package/dist/prompts/providers/config-prompt-provider.cjs +12 -3
  243. package/dist/prompts/providers/config-prompt-provider.d.ts +2 -1
  244. package/dist/prompts/providers/config-prompt-provider.d.ts.map +1 -1
  245. package/dist/prompts/providers/config-prompt-provider.js +13 -4
  246. package/dist/prompts/providers/custom-prompt-provider.cjs +2 -2
  247. package/dist/prompts/providers/custom-prompt-provider.d.ts +1 -1
  248. package/dist/prompts/providers/custom-prompt-provider.d.ts.map +1 -1
  249. package/dist/prompts/providers/custom-prompt-provider.js +3 -3
  250. package/dist/prompts/providers/mcp-prompt-provider.js +1 -1
  251. package/dist/prompts/schemas.d.ts +12 -0
  252. package/dist/prompts/schemas.d.ts.map +1 -1
  253. package/dist/prompts/schemas.js +1 -1
  254. package/dist/prompts/types.d.ts +2 -0
  255. package/dist/prompts/types.d.ts.map +1 -1
  256. package/dist/prompts/utils.js +1 -1
  257. package/dist/resources/error-codes.js +1 -1
  258. package/dist/resources/errors.js +1 -1
  259. package/dist/resources/handlers/blob-handler.js +1 -1
  260. package/dist/resources/handlers/factory.js +1 -1
  261. package/dist/resources/handlers/filesystem-handler.js +1 -1
  262. package/dist/resources/index.js +1 -1
  263. package/dist/resources/internal-provider.js +1 -1
  264. package/dist/resources/manager.js +1 -1
  265. package/dist/resources/reference-parser.js +1 -1
  266. package/dist/resources/schemas.js +1 -1
  267. package/dist/search/index.js +1 -1
  268. package/dist/search/search-service.js +1 -1
  269. package/dist/session/chat-session.cjs +149 -51
  270. package/dist/session/chat-session.d.ts +69 -29
  271. package/dist/session/chat-session.d.ts.map +1 -1
  272. package/dist/session/chat-session.js +150 -52
  273. package/dist/session/error-codes.js +1 -1
  274. package/dist/session/errors.js +1 -1
  275. package/dist/session/history/database.cjs +134 -21
  276. package/dist/session/history/database.d.ts +37 -8
  277. package/dist/session/history/database.d.ts.map +1 -1
  278. package/dist/session/history/database.js +135 -22
  279. package/dist/session/history/factory.js +1 -1
  280. package/dist/session/history/memory.cjs +18 -0
  281. package/dist/session/history/memory.d.ts +8 -0
  282. package/dist/session/history/memory.d.ts.map +1 -1
  283. package/dist/session/history/memory.js +19 -1
  284. package/dist/session/history/types.d.ts +13 -1
  285. package/dist/session/history/types.d.ts.map +1 -1
  286. package/dist/session/index.cjs +3 -0
  287. package/dist/session/index.d.ts +3 -0
  288. package/dist/session/index.d.ts.map +1 -1
  289. package/dist/session/index.js +3 -1
  290. package/dist/session/message-queue.cjs +201 -0
  291. package/dist/session/message-queue.d.ts +114 -0
  292. package/dist/session/message-queue.d.ts.map +1 -0
  293. package/dist/session/message-queue.js +178 -0
  294. package/dist/session/schemas.js +1 -1
  295. package/dist/session/session-manager.cjs +57 -7
  296. package/dist/session/session-manager.d.ts +18 -0
  297. package/dist/session/session-manager.d.ts.map +1 -1
  298. package/dist/session/session-manager.js +58 -8
  299. package/dist/session/title-generator.cjs +4 -8
  300. package/dist/session/title-generator.d.ts +1 -2
  301. package/dist/session/title-generator.d.ts.map +1 -1
  302. package/dist/session/title-generator.js +5 -9
  303. package/dist/session/types.cjs +16 -0
  304. package/dist/session/types.d.ts +14 -0
  305. package/dist/session/types.d.ts.map +1 -0
  306. package/dist/session/types.js +0 -0
  307. package/dist/storage/blob/factory.js +1 -1
  308. package/dist/storage/blob/local-blob-store.js +1 -1
  309. package/dist/storage/blob/memory-blob-store.js +1 -1
  310. package/dist/storage/blob/schemas.js +1 -1
  311. package/dist/storage/cache/factory.cjs +6 -2
  312. package/dist/storage/cache/factory.d.ts +2 -1
  313. package/dist/storage/cache/factory.d.ts.map +1 -1
  314. package/dist/storage/cache/factory.js +7 -3
  315. package/dist/storage/cache/memory-cache-store.js +1 -1
  316. package/dist/storage/cache/redis-store.js +1 -1
  317. package/dist/storage/cache/schemas.js +1 -1
  318. package/dist/storage/database/factory.cjs +11 -17
  319. package/dist/storage/database/factory.d.ts +2 -1
  320. package/dist/storage/database/factory.d.ts.map +1 -1
  321. package/dist/storage/database/factory.js +12 -18
  322. package/dist/storage/database/memory-database-store.js +1 -1
  323. package/dist/storage/database/postgres-store.cjs +12 -0
  324. package/dist/storage/database/postgres-store.d.ts.map +1 -1
  325. package/dist/storage/database/postgres-store.js +13 -1
  326. package/dist/storage/database/schemas.js +1 -1
  327. package/dist/storage/database/sqlite-store.cjs +8 -0
  328. package/dist/storage/database/sqlite-store.d.ts.map +1 -1
  329. package/dist/storage/database/sqlite-store.js +9 -1
  330. package/dist/storage/error-codes.cjs +1 -0
  331. package/dist/storage/error-codes.d.ts +1 -0
  332. package/dist/storage/error-codes.d.ts.map +1 -1
  333. package/dist/storage/error-codes.js +2 -1
  334. package/dist/storage/errors.cjs +17 -0
  335. package/dist/storage/errors.d.ts +9 -0
  336. package/dist/storage/errors.d.ts.map +1 -1
  337. package/dist/storage/errors.js +18 -1
  338. package/dist/storage/index.js +1 -1
  339. package/dist/storage/schemas.js +1 -1
  340. package/dist/storage/storage-manager.js +1 -1
  341. package/dist/systemPrompt/contributors.js +1 -1
  342. package/dist/systemPrompt/error-codes.js +1 -1
  343. package/dist/systemPrompt/errors.js +1 -1
  344. package/dist/systemPrompt/in-built-prompts.js +1 -1
  345. package/dist/systemPrompt/index.js +1 -1
  346. package/dist/systemPrompt/manager.js +1 -1
  347. package/dist/systemPrompt/registry.js +1 -1
  348. package/dist/systemPrompt/schemas.d.ts +5 -5
  349. package/dist/systemPrompt/schemas.js +1 -1
  350. package/dist/telemetry/decorators.js +1 -1
  351. package/dist/{llm/tokenizer/default.cjs → telemetry/error-codes.cjs} +14 -19
  352. package/dist/telemetry/error-codes.d.ts +13 -0
  353. package/dist/telemetry/error-codes.d.ts.map +1 -0
  354. package/dist/telemetry/error-codes.js +13 -0
  355. package/dist/telemetry/errors.cjs +105 -0
  356. package/dist/telemetry/errors.d.ts +28 -0
  357. package/dist/telemetry/errors.d.ts.map +1 -0
  358. package/dist/telemetry/errors.js +82 -0
  359. package/dist/telemetry/exporters.js +1 -1
  360. package/dist/telemetry/index.js +1 -1
  361. package/dist/telemetry/schemas.js +1 -1
  362. package/dist/telemetry/telemetry.cjs +92 -26
  363. package/dist/telemetry/telemetry.d.ts +1 -1
  364. package/dist/telemetry/telemetry.d.ts.map +1 -1
  365. package/dist/telemetry/telemetry.js +75 -19
  366. package/dist/telemetry/utils.js +1 -1
  367. package/dist/tools/bash-pattern-utils.cjs +91 -0
  368. package/dist/tools/bash-pattern-utils.d.ts +58 -0
  369. package/dist/tools/bash-pattern-utils.d.ts.map +1 -0
  370. package/dist/tools/bash-pattern-utils.js +64 -0
  371. package/dist/tools/confirmation/allowed-tools-provider/factory.js +1 -1
  372. package/dist/tools/confirmation/allowed-tools-provider/in-memory.js +1 -1
  373. package/dist/tools/confirmation/allowed-tools-provider/storage.js +1 -1
  374. package/dist/tools/display-types.cjs +60 -0
  375. package/dist/tools/display-types.d.ts +133 -0
  376. package/dist/tools/display-types.d.ts.map +1 -0
  377. package/dist/tools/display-types.js +32 -0
  378. package/dist/tools/error-codes.cjs +2 -0
  379. package/dist/tools/error-codes.d.ts +3 -1
  380. package/dist/tools/error-codes.d.ts.map +1 -1
  381. package/dist/tools/error-codes.js +3 -1
  382. package/dist/tools/errors.cjs +30 -0
  383. package/dist/tools/errors.d.ts +16 -0
  384. package/dist/tools/errors.d.ts.map +1 -1
  385. package/dist/tools/errors.js +31 -1
  386. package/dist/tools/index.cjs +2 -0
  387. package/dist/tools/index.d.ts +1 -0
  388. package/dist/tools/index.d.ts.map +1 -1
  389. package/dist/tools/index.js +2 -1
  390. package/dist/tools/internal-tools/constants.js +1 -1
  391. package/dist/tools/internal-tools/implementations/ask-user-tool.cjs +1 -1
  392. package/dist/tools/internal-tools/implementations/ask-user-tool.js +2 -2
  393. package/dist/tools/internal-tools/implementations/bash-exec-tool.cjs +42 -18
  394. package/dist/tools/internal-tools/implementations/bash-exec-tool.d.ts +3 -3
  395. package/dist/tools/internal-tools/implementations/bash-exec-tool.d.ts.map +1 -1
  396. package/dist/tools/internal-tools/implementations/bash-exec-tool.js +43 -19
  397. package/dist/tools/internal-tools/implementations/bash-output-tool.js +1 -1
  398. package/dist/tools/internal-tools/implementations/delegate-to-url-tool.js +1 -1
  399. package/dist/tools/internal-tools/implementations/edit-file-tool.cjs +66 -1
  400. package/dist/tools/internal-tools/implementations/edit-file-tool.d.ts.map +1 -1
  401. package/dist/tools/internal-tools/implementations/edit-file-tool.js +67 -2
  402. package/dist/tools/internal-tools/implementations/glob-files-tool.cjs +14 -1
  403. package/dist/tools/internal-tools/implementations/glob-files-tool.d.ts.map +1 -1
  404. package/dist/tools/internal-tools/implementations/glob-files-tool.js +15 -2
  405. package/dist/tools/internal-tools/implementations/grep-content-tool.cjs +16 -1
  406. package/dist/tools/internal-tools/implementations/grep-content-tool.d.ts.map +1 -1
  407. package/dist/tools/internal-tools/implementations/grep-content-tool.js +17 -2
  408. package/dist/tools/internal-tools/implementations/kill-process-tool.js +1 -1
  409. package/dist/tools/internal-tools/implementations/read-file-tool.cjs +9 -1
  410. package/dist/tools/internal-tools/implementations/read-file-tool.d.ts.map +1 -1
  411. package/dist/tools/internal-tools/implementations/read-file-tool.js +10 -2
  412. package/dist/tools/internal-tools/implementations/search-history-tool.js +1 -1
  413. package/dist/tools/internal-tools/implementations/write-file-tool.cjs +69 -1
  414. package/dist/tools/internal-tools/implementations/write-file-tool.d.ts.map +1 -1
  415. package/dist/tools/internal-tools/implementations/write-file-tool.js +72 -2
  416. package/dist/tools/internal-tools/provider.cjs +27 -10
  417. package/dist/tools/internal-tools/provider.d.ts +8 -5
  418. package/dist/tools/internal-tools/provider.d.ts.map +1 -1
  419. package/dist/tools/internal-tools/provider.js +28 -11
  420. package/dist/tools/internal-tools/registry.cjs +4 -3
  421. package/dist/tools/internal-tools/registry.d.ts +28 -7
  422. package/dist/tools/internal-tools/registry.d.ts.map +1 -1
  423. package/dist/tools/internal-tools/registry.js +5 -4
  424. package/dist/tools/schemas.cjs +17 -7
  425. package/dist/tools/schemas.d.ts +31 -4
  426. package/dist/tools/schemas.d.ts.map +1 -1
  427. package/dist/tools/schemas.js +15 -7
  428. package/dist/tools/tool-manager.cjs +140 -18
  429. package/dist/tools/tool-manager.d.ts +23 -1
  430. package/dist/tools/tool-manager.d.ts.map +1 -1
  431. package/dist/tools/tool-manager.js +145 -19
  432. package/dist/tools/types.d.ts +20 -11
  433. package/dist/tools/types.d.ts.map +1 -1
  434. package/dist/utils/api-key-resolver.js +1 -1
  435. package/dist/utils/async-context.js +1 -1
  436. package/dist/utils/debug.js +1 -1
  437. package/dist/{llm/tokenizer/types.cjs → utils/defer.cjs} +19 -10
  438. package/dist/utils/defer.d.ts +63 -0
  439. package/dist/utils/defer.d.ts.map +1 -0
  440. package/dist/utils/defer.js +19 -0
  441. package/dist/utils/env-file.js +1 -1
  442. package/dist/utils/error-conversion.js +1 -1
  443. package/dist/utils/execution-context.js +1 -1
  444. package/dist/utils/fs-walk.js +1 -1
  445. package/dist/utils/index.cjs +3 -1
  446. package/dist/utils/index.d.ts +1 -0
  447. package/dist/utils/index.d.ts.map +1 -1
  448. package/dist/utils/index.js +1 -0
  449. package/dist/utils/path.js +1 -1
  450. package/dist/utils/redactor.js +1 -1
  451. package/dist/utils/result.js +1 -1
  452. package/dist/utils/safe-stringify.js +1 -1
  453. package/dist/utils/schema-metadata.js +1 -1
  454. package/dist/utils/schema.d.ts +6 -0
  455. package/dist/utils/schema.d.ts.map +1 -1
  456. package/dist/utils/schema.js +1 -1
  457. package/dist/utils/service-initializer.cjs +6 -2
  458. package/dist/utils/service-initializer.d.ts.map +1 -1
  459. package/dist/utils/service-initializer.js +7 -3
  460. package/dist/utils/user-info.js +1 -1
  461. package/dist/utils/zod-schema-converter.js +1 -1
  462. package/package.json +54 -17
  463. package/dist/context/compression/middle-removal.cjs +0 -95
  464. package/dist/context/compression/middle-removal.d.ts +0 -47
  465. package/dist/context/compression/middle-removal.d.ts.map +0 -1
  466. package/dist/context/compression/middle-removal.js +0 -72
  467. package/dist/context/compression/oldest-removal.cjs +0 -83
  468. package/dist/context/compression/oldest-removal.d.ts +0 -42
  469. package/dist/context/compression/oldest-removal.d.ts.map +0 -1
  470. package/dist/context/compression/oldest-removal.js +0 -60
  471. package/dist/llm/formatters/anthropic.cjs +0 -257
  472. package/dist/llm/formatters/anthropic.d.ts +0 -46
  473. package/dist/llm/formatters/anthropic.d.ts.map +0 -1
  474. package/dist/llm/formatters/anthropic.js +0 -239
  475. package/dist/llm/formatters/factory.cjs +0 -50
  476. package/dist/llm/formatters/factory.d.ts +0 -10
  477. package/dist/llm/formatters/factory.d.ts.map +0 -1
  478. package/dist/llm/formatters/factory.js +0 -27
  479. package/dist/llm/formatters/openai.cjs +0 -196
  480. package/dist/llm/formatters/openai.d.ts +0 -39
  481. package/dist/llm/formatters/openai.d.ts.map +0 -1
  482. package/dist/llm/formatters/openai.js +0 -177
  483. package/dist/llm/formatters/types.d.ts +0 -41
  484. package/dist/llm/formatters/types.d.ts.map +0 -1
  485. package/dist/llm/services/anthropic.cjs +0 -511
  486. package/dist/llm/services/anthropic.d.ts +0 -48
  487. package/dist/llm/services/anthropic.d.ts.map +0 -1
  488. package/dist/llm/services/anthropic.js +0 -447
  489. package/dist/llm/services/openai.cjs +0 -611
  490. package/dist/llm/services/openai.d.ts +0 -48
  491. package/dist/llm/services/openai.d.ts.map +0 -1
  492. package/dist/llm/services/openai.js +0 -547
  493. package/dist/llm/tokenizer/anthropic.cjs +0 -43
  494. package/dist/llm/tokenizer/anthropic.d.ts +0 -19
  495. package/dist/llm/tokenizer/anthropic.d.ts.map +0 -1
  496. package/dist/llm/tokenizer/anthropic.js +0 -20
  497. package/dist/llm/tokenizer/default.d.ts +0 -14
  498. package/dist/llm/tokenizer/default.d.ts.map +0 -1
  499. package/dist/llm/tokenizer/default.js +0 -18
  500. package/dist/llm/tokenizer/factory.d.ts +0 -12
  501. package/dist/llm/tokenizer/factory.d.ts.map +0 -1
  502. package/dist/llm/tokenizer/factory.js +0 -21
  503. package/dist/llm/tokenizer/google.cjs +0 -52
  504. package/dist/llm/tokenizer/google.d.ts +0 -29
  505. package/dist/llm/tokenizer/google.d.ts.map +0 -1
  506. package/dist/llm/tokenizer/google.js +0 -29
  507. package/dist/llm/tokenizer/openai.cjs +0 -115
  508. package/dist/llm/tokenizer/openai.d.ts +0 -33
  509. package/dist/llm/tokenizer/openai.d.ts.map +0 -1
  510. package/dist/llm/tokenizer/openai.js +0 -91
  511. package/dist/llm/tokenizer/types.d.ts +0 -18
  512. package/dist/llm/tokenizer/types.d.ts.map +0 -1
  513. package/dist/llm/tokenizer/types.js +0 -10
  514. /package/dist/llm/{formatters → executor}/types.cjs +0 -0
  515. /package/dist/llm/{formatters → executor}/types.js +0 -0
@@ -1,4 +1,4 @@
1
- import "../chunk-C6A6W6XS.js";
1
+ import "../chunk-PTJYTZNU.js";
2
2
  import { createDatabaseHistoryProvider } from "./history/factory.js";
3
3
  import { createLLMService } from "../llm/services/factory.js";
4
4
  import {
@@ -8,6 +8,7 @@ import {
8
8
  import { DextoLogComponent } from "../logger/v2/types.js";
9
9
  import { DextoRuntimeError, ErrorScope, ErrorType } from "../errors/index.js";
10
10
  import { PluginErrorCode } from "../plugins/error-codes.js";
11
+ import { getModelPricing, calculateCost } from "../llm/registry.js";
11
12
  class ChatSession {
12
13
  /**
13
14
  * Creates a new ChatSession instance.
@@ -58,6 +59,10 @@ class ChatSession {
58
59
  * Stores the bound functions so they can be removed from the event bus.
59
60
  */
60
61
  forwarders = /* @__PURE__ */ new Map();
62
+ /**
63
+ * Token accumulator listener for cleanup.
64
+ */
65
+ tokenAccumulatorListener = null;
61
66
  /**
62
67
  * AbortController for the currently running turn, if any.
63
68
  * Calling cancel() aborts the in-flight LLM request and tool execution checks.
@@ -88,10 +93,33 @@ class ChatSession {
88
93
  this.forwarders.set(eventName, forwarder);
89
94
  this.eventBus.on(eventName, forwarder);
90
95
  });
96
+ this.setupTokenAccumulation();
91
97
  this.logger.debug(
92
98
  `[setupEventForwarding] Event forwarding setup complete for session=${this.id}`
93
99
  );
94
100
  }
101
+ /**
102
+ * Sets up token usage accumulation by listening to llm:response events.
103
+ * Accumulates token usage and cost to session metadata for /stats tracking.
104
+ */
105
+ setupTokenAccumulation() {
106
+ this.tokenAccumulatorListener = (payload) => {
107
+ if (payload.tokenUsage) {
108
+ let cost;
109
+ const llmConfig = this.services.stateManager.getLLMConfig(this.id);
110
+ const pricing = getModelPricing(llmConfig.provider, llmConfig.model);
111
+ if (pricing) {
112
+ cost = calculateCost(payload.tokenUsage, pricing);
113
+ }
114
+ this.services.sessionManager.accumulateTokenUsage(this.id, payload.tokenUsage, cost).catch((err) => {
115
+ this.logger.warn(
116
+ `Failed to accumulate token usage: ${err instanceof Error ? err.message : String(err)}`
117
+ );
118
+ });
119
+ }
120
+ };
121
+ this.eventBus.on("llm:response", this.tokenAccumulatorListener);
122
+ }
95
123
  /**
96
124
  * Initializes session-specific services.
97
125
  */
@@ -104,7 +132,6 @@ class ChatSession {
104
132
  );
105
133
  this.llmService = createLLMService(
106
134
  llmConfig,
107
- llmConfig.router,
108
135
  this.services.toolManager,
109
136
  this.services.systemPromptManager,
110
137
  this.historyProvider,
@@ -133,12 +160,12 @@ class ChatSession {
133
160
  async saveBlockedInteraction(userInput, errorMessage, _imageData, _fileData) {
134
161
  const userMessage = {
135
162
  role: "user",
136
- content: "[Blocked by content policy: input redacted]"
163
+ content: [{ type: "text", text: "[Blocked by content policy: input redacted]" }]
137
164
  };
138
165
  const errorContent = `Error: ${errorMessage}`;
139
166
  const assistantMessage = {
140
167
  role: "assistant",
141
- content: errorContent
168
+ content: [{ type: "text", text: errorContent }]
142
169
  };
143
170
  await this.historyProvider.saveMessage(userMessage);
144
171
  await this.historyProvider.saveMessage(assistantMessage);
@@ -146,44 +173,61 @@ class ChatSession {
146
173
  this.eventBus.emit("llm:response", {
147
174
  content: errorContent,
148
175
  provider: llmConfig.provider,
149
- model: llmConfig.model,
150
- router: llmConfig.router
176
+ model: llmConfig.model
151
177
  });
152
178
  }
153
179
  /**
154
- * Processes user input through the session's LLM service and returns the response.
180
+ * Stream a response for the given content.
181
+ * Primary method for running conversations with multi-image support.
155
182
  *
156
- * This method:
157
- * 1. Takes user input (text, optionally with image or file data)
158
- * 2. Passes it to the LLM service for processing
159
- * 3. Returns the AI's response text
160
- *
161
- * The method handles both text-only and multimodal input (text + images/files).
162
- * Tool calls and conversation management are handled internally by the LLM service.
163
- *
164
- * @param input - The user's text input
165
- * @param imageDataInput - Optional image data for multimodal input
166
- * @param fileDataInput - Optional file data for file input
167
- * @param stream - Optional flag to enable streaming responses
183
+ * @param content - String or ContentPart[] (text, images, files)
184
+ * @param options - { signal?: AbortSignal }
168
185
  * @returns Promise that resolves to the AI's response text
169
186
  *
170
187
  * @example
171
188
  * ```typescript
172
- * const response = await session.run('What is the weather like today?');
173
- * console.log(response); // "I'll check the weather for you..."
189
+ * // Text only
190
+ * const response = await session.stream('What is the weather?');
191
+ *
192
+ * // Multiple images
193
+ * const response = await session.stream([
194
+ * { type: 'text', text: 'Compare these images' },
195
+ * { type: 'image', image: base64Data1, mimeType: 'image/png' },
196
+ * { type: 'image', image: base64Data2, mimeType: 'image/png' }
197
+ * ]);
174
198
  * ```
175
199
  */
176
- async run(input, imageDataInput, fileDataInput, stream) {
200
+ async stream(content, options) {
201
+ const parts = typeof content === "string" ? [{ type: "text", text: content }] : content;
202
+ const textParts = parts.filter(
203
+ (p) => p.type === "text"
204
+ );
205
+ const imageParts = parts.filter((p) => p.type === "image");
206
+ const fileParts = parts.filter((p) => p.type === "file");
177
207
  this.logger.debug(
178
- `Running session ${this.id} | input.len=${input?.length ?? 0} | image=${imageDataInput ? imageDataInput.mimeType : "none"} | file=${fileDataInput ? `${fileDataInput.mimeType}:${fileDataInput.filename ?? "unknown"}` : "none"}`
208
+ `Streaming session ${this.id} | textParts=${textParts.length} | images=${imageParts.length} | files=${fileParts.length}`
179
209
  );
180
210
  this.currentRunController = new AbortController();
181
- const signal = this.currentRunController.signal;
211
+ const signal = options?.signal ? this.combineSignals(options.signal, this.currentRunController.signal) : this.currentRunController.signal;
182
212
  try {
213
+ const textContent = textParts.map((p) => p.text).join("\n");
214
+ const firstImage = imageParts[0];
215
+ const firstFile = fileParts[0];
183
216
  const beforeLLMPayload = {
184
- text: input,
185
- ...imageDataInput !== void 0 && { imageData: imageDataInput },
186
- ...fileDataInput !== void 0 && { fileData: fileDataInput },
217
+ text: textContent,
218
+ ...firstImage && {
219
+ imageData: {
220
+ image: typeof firstImage.image === "string" ? firstImage.image : "[binary]",
221
+ mimeType: firstImage.mimeType || "image/jpeg"
222
+ }
223
+ },
224
+ ...firstFile && {
225
+ fileData: {
226
+ data: typeof firstFile.data === "string" ? firstFile.data : "[binary]",
227
+ mimeType: firstFile.mimeType,
228
+ ...firstFile.filename && { filename: firstFile.filename }
229
+ }
230
+ },
187
231
  sessionId: this.id
188
232
  };
189
233
  const modifiedBeforePayload = await this.services.pluginManager.executePlugins(
@@ -198,22 +242,17 @@ class ChatSession {
198
242
  abortSignal: signal
199
243
  }
200
244
  );
201
- const finalInput = modifiedBeforePayload.text;
202
- const finalImageData = modifiedBeforePayload.imageData;
203
- const finalFileData = modifiedBeforePayload.fileData;
204
- const response = await this.llmService.completeTask(
205
- finalInput,
206
- { signal },
207
- finalImageData,
208
- finalFileData,
209
- stream
210
- );
245
+ let modifiedParts = [...parts];
246
+ if (modifiedBeforePayload.text !== textContent && textParts.length > 0) {
247
+ modifiedParts = modifiedParts.filter((p) => p.type !== "text");
248
+ modifiedParts.unshift({ type: "text", text: modifiedBeforePayload.text });
249
+ }
250
+ const response = await this.llmService.stream(modifiedParts, { signal });
211
251
  const llmConfig = this.services.stateManager.getLLMConfig(this.id);
212
252
  const beforeResponsePayload = {
213
253
  content: response,
214
254
  provider: llmConfig.provider,
215
255
  model: llmConfig.model,
216
- router: llmConfig.router,
217
256
  sessionId: this.id
218
257
  };
219
258
  const modifiedResponsePayload = await this.services.pluginManager.executePlugins(
@@ -237,16 +276,21 @@ class ChatSession {
237
276
  context: "user_cancelled",
238
277
  recoverable: true
239
278
  });
279
+ try {
280
+ const history = await this.getHistory();
281
+ const lastAssistant = history.filter((m) => m.role === "assistant").pop();
282
+ if (lastAssistant && typeof lastAssistant.content === "string") {
283
+ return lastAssistant.content;
284
+ }
285
+ } catch {
286
+ this.logger.debug("Failed to retrieve partial response from history on cancel");
287
+ }
240
288
  return "";
241
289
  }
242
290
  if (error instanceof DextoRuntimeError && error.code === PluginErrorCode.PLUGIN_BLOCKED_EXECUTION && error.scope === ErrorScope.PLUGIN && error.type === ErrorType.FORBIDDEN) {
291
+ const textContent = parts.filter((p) => p.type === "text").map((p) => p.text).join("\n");
243
292
  try {
244
- await this.saveBlockedInteraction(
245
- input,
246
- error.message,
247
- imageDataInput,
248
- fileDataInput
249
- );
293
+ await this.saveBlockedInteraction(textContent, error.message);
250
294
  this.logger.debug(
251
295
  `ChatSession ${this.id}: Saved blocked interaction to history`
252
296
  );
@@ -257,15 +301,27 @@ class ChatSession {
257
301
  }
258
302
  return error.message;
259
303
  }
260
- const errortype = error instanceof Error ? "object" : "string";
261
304
  this.logger.error(
262
- `Error in ChatSession.run: errortype=${errortype}: ${error instanceof Error ? error.message : String(error)}`
305
+ `Error in ChatSession.stream: ${error instanceof Error ? error.message : String(error)}`
263
306
  );
264
307
  throw error;
265
308
  } finally {
266
309
  this.currentRunController = null;
267
310
  }
268
311
  }
312
+ /**
313
+ * Combine multiple abort signals into one.
314
+ */
315
+ combineSignals(signal1, signal2) {
316
+ const controller = new AbortController();
317
+ const onAbort = () => controller.abort();
318
+ signal1.addEventListener("abort", onAbort);
319
+ signal2.addEventListener("abort", onAbort);
320
+ if (signal1.aborted || signal2.aborted) {
321
+ controller.abort();
322
+ }
323
+ return controller.signal;
324
+ }
269
325
  /**
270
326
  * Retrieves the complete conversation history for this session.
271
327
  *
@@ -336,11 +392,11 @@ class ChatSession {
336
392
  /**
337
393
  * Switches the LLM service for this session while preserving conversation history.
338
394
  *
339
- * This method creates a new LLM service with the specified configuration and router,
395
+ * This method creates a new LLM service with the specified configuration,
340
396
  * while maintaining the existing ContextManager and conversation history. This allows
341
397
  * users to change AI models mid-conversation without losing context.
342
398
  *
343
- * @param newLLMConfig The new LLM configuration to use (includes router)
399
+ * @param newLLMConfig The new LLM configuration to use
344
400
  *
345
401
  * @example
346
402
  * ```typescript
@@ -349,16 +405,13 @@ class ChatSession {
349
405
  * provider: 'openai',
350
406
  * model: 'gpt-5',
351
407
  * apiKey: process.env.OPENAI_API_KEY,
352
- * router: 'in-built'
353
408
  * });
354
409
  * ```
355
410
  */
356
411
  async switchLLM(newLLMConfig) {
357
412
  try {
358
- const router = newLLMConfig.router;
359
413
  const newLLMService = createLLMService(
360
414
  newLLMConfig,
361
- router,
362
415
  this.services.toolManager,
363
416
  this.services.systemPromptManager,
364
417
  this.historyProvider,
@@ -375,7 +428,6 @@ class ChatSession {
375
428
  );
376
429
  this.eventBus.emit("llm:switched", {
377
430
  newConfig: newLLMConfig,
378
- router,
379
431
  historyRetained: true
380
432
  });
381
433
  } catch (error) {
@@ -416,8 +468,54 @@ class ChatSession {
416
468
  this.eventBus.off(eventName, forwarder);
417
469
  });
418
470
  this.forwarders.clear();
471
+ if (this.tokenAccumulatorListener) {
472
+ this.eventBus.off("llm:response", this.tokenAccumulatorListener);
473
+ this.tokenAccumulatorListener = null;
474
+ }
419
475
  this.logger.debug(`Session ${this.id} disposed successfully`);
420
476
  }
477
+ /**
478
+ * Check if this session is currently processing a message.
479
+ * Returns true if a run is in progress and has not been aborted.
480
+ */
481
+ isBusy() {
482
+ return this.currentRunController !== null && !this.currentRunController.signal.aborted;
483
+ }
484
+ /**
485
+ * Queue a message for processing when the session is busy.
486
+ * The message will be injected into the conversation when the current turn completes.
487
+ *
488
+ * @param message The user message to queue
489
+ * @returns Queue position and message ID
490
+ */
491
+ queueMessage(message) {
492
+ return this.llmService.getMessageQueue().enqueue(message);
493
+ }
494
+ /**
495
+ * Get all messages currently in the queue.
496
+ * @returns Array of queued messages
497
+ */
498
+ getQueuedMessages() {
499
+ return this.llmService.getMessageQueue().getAll();
500
+ }
501
+ /**
502
+ * Remove a queued message.
503
+ * @param id Message ID to remove
504
+ * @returns true if message was found and removed; false otherwise
505
+ */
506
+ removeQueuedMessage(id) {
507
+ return this.llmService.getMessageQueue().remove(id);
508
+ }
509
+ /**
510
+ * Clear all queued messages.
511
+ * @returns Number of messages that were cleared
512
+ */
513
+ clearMessageQueue() {
514
+ const queue = this.llmService.getMessageQueue();
515
+ const count = queue.pendingCount();
516
+ queue.clear();
517
+ return count;
518
+ }
421
519
  /**
422
520
  * Cancel the currently running turn for this session, if any.
423
521
  * Returns true if a run was in progress and was signaled to abort.
@@ -1,4 +1,4 @@
1
- import "../chunk-C6A6W6XS.js";
1
+ import "../chunk-PTJYTZNU.js";
2
2
  var SessionErrorCode = /* @__PURE__ */ ((SessionErrorCode2) => {
3
3
  SessionErrorCode2["SESSION_NOT_FOUND"] = "session_not_found";
4
4
  SessionErrorCode2["SESSION_INITIALIZATION_FAILED"] = "session_initialization_failed";
@@ -1,4 +1,4 @@
1
- import "../chunk-C6A6W6XS.js";
1
+ import "../chunk-PTJYTZNU.js";
2
2
  import { DextoRuntimeError } from "../errors/DextoRuntimeError.js";
3
3
  import { ErrorScope, ErrorType } from "../errors/types.js";
4
4
  import { SessionErrorCode } from "./error-codes.js";
@@ -24,47 +24,58 @@ module.exports = __toCommonJS(database_exports);
24
24
  var import_types = require("../../logger/v2/types.cjs");
25
25
  var import_errors = require("../errors.js");
26
26
  class DatabaseHistoryProvider {
27
+ // Debounce window for batching updates
27
28
  constructor(sessionId, database, logger) {
28
29
  this.sessionId = sessionId;
29
30
  this.database = database;
30
31
  this.logger = logger.createChild(import_types.DextoLogComponent.SESSION);
31
32
  }
32
33
  logger;
34
+ // Cache state
35
+ cache = null;
36
+ dirty = false;
37
+ flushTimer = null;
38
+ flushPromise = null;
39
+ // Flush configuration
40
+ static FLUSH_DELAY_MS = 100;
33
41
  async getHistory() {
34
- const key = this.getMessagesKey();
35
- try {
36
- const messages = await this.database.getRange(key, 0, 1e3);
37
- this.logger.debug(
38
- `DatabaseHistoryProvider: Retrieved ${messages.length} messages for session ${this.sessionId}`
39
- );
40
- return messages;
41
- } catch (error) {
42
- this.logger.error(
43
- `DatabaseHistoryProvider: Error retrieving messages for session ${this.sessionId}: ${error instanceof Error ? error.message : String(error)}`
44
- );
45
- return [];
42
+ if (this.cache === null) {
43
+ const key = this.getMessagesKey();
44
+ try {
45
+ this.cache = await this.database.getRange(key, 0, 1e4);
46
+ this.logger.debug(
47
+ `DatabaseHistoryProvider: Loaded ${this.cache.length} messages from DB for session ${this.sessionId}`
48
+ );
49
+ } catch (error) {
50
+ this.logger.error(
51
+ `DatabaseHistoryProvider: Error loading messages for session ${this.sessionId}: ${error instanceof Error ? error.message : String(error)}`
52
+ );
53
+ throw import_errors.SessionError.storageFailed(
54
+ this.sessionId,
55
+ "load history",
56
+ error instanceof Error ? error.message : String(error)
57
+ );
58
+ }
46
59
  }
60
+ return [...this.cache];
47
61
  }
48
62
  async saveMessage(message) {
49
63
  const key = this.getMessagesKey();
64
+ if (this.cache === null) {
65
+ await this.getHistory();
66
+ }
67
+ this.cache.push(message);
50
68
  try {
51
69
  await this.database.append(key, message);
52
- let contentPreview = "[no content]";
53
- if (message.content) {
54
- if (typeof message.content === "string") {
55
- contentPreview = message.content.length > 100 ? `${message.content.substring(0, 100)}...` : message.content;
56
- } else if (Array.isArray(message.content)) {
57
- contentPreview = `[${message.content.length} parts]`;
58
- }
59
- }
60
70
  this.logger.debug(
61
71
  `DatabaseHistoryProvider: Saved message for session ${this.sessionId}`,
62
72
  {
63
73
  role: message.role,
64
- content: contentPreview
74
+ id: message.id
65
75
  }
66
76
  );
67
77
  } catch (error) {
78
+ this.cache.pop();
68
79
  this.logger.error(
69
80
  `DatabaseHistoryProvider: Error saving message for session ${this.sessionId}: ${error instanceof Error ? error.message : String(error)}`
70
81
  );
@@ -75,7 +86,34 @@ class DatabaseHistoryProvider {
75
86
  );
76
87
  }
77
88
  }
89
+ async updateMessage(message) {
90
+ if (!message.id) {
91
+ this.logger.warn(
92
+ `DatabaseHistoryProvider: Ignoring update for message without id in session ${this.sessionId}`
93
+ );
94
+ return;
95
+ }
96
+ if (this.cache === null) {
97
+ await this.getHistory();
98
+ }
99
+ const index = this.cache.findIndex((m) => m.id === message.id);
100
+ if (index !== -1) {
101
+ this.cache[index] = message;
102
+ this.dirty = true;
103
+ this.scheduleFlush();
104
+ this.logger.debug(
105
+ `DatabaseHistoryProvider: Updated message ${message.id} in cache for session ${this.sessionId}`
106
+ );
107
+ } else {
108
+ this.logger.warn(
109
+ `DatabaseHistoryProvider: Message ${message.id} not found for update in session ${this.sessionId}`
110
+ );
111
+ }
112
+ }
78
113
  async clearHistory() {
114
+ this.cancelPendingFlush();
115
+ this.cache = [];
116
+ this.dirty = false;
79
117
  const key = this.getMessagesKey();
80
118
  try {
81
119
  await this.database.delete(key);
@@ -92,6 +130,81 @@ class DatabaseHistoryProvider {
92
130
  );
93
131
  }
94
132
  }
133
+ /**
134
+ * Flush any pending updates to the database.
135
+ * Should be called at turn boundaries to ensure durability.
136
+ */
137
+ async flush() {
138
+ if (this.flushPromise) {
139
+ await this.flushPromise;
140
+ return;
141
+ }
142
+ this.cancelPendingFlush();
143
+ if (!this.dirty || !this.cache) {
144
+ return;
145
+ }
146
+ this.flushPromise = this.doFlush();
147
+ try {
148
+ await this.flushPromise;
149
+ } finally {
150
+ this.flushPromise = null;
151
+ }
152
+ }
153
+ /**
154
+ * Internal flush implementation.
155
+ * Writes entire cache to DB (delete + re-append all).
156
+ */
157
+ async doFlush() {
158
+ if (!this.dirty || !this.cache) {
159
+ return;
160
+ }
161
+ const key = this.getMessagesKey();
162
+ const messageCount = this.cache.length;
163
+ try {
164
+ await this.database.delete(key);
165
+ for (const msg of this.cache) {
166
+ await this.database.append(key, msg);
167
+ }
168
+ if (!this.flushTimer) {
169
+ this.dirty = false;
170
+ }
171
+ this.logger.debug(
172
+ `DatabaseHistoryProvider: Flushed ${messageCount} messages to DB for session ${this.sessionId}`
173
+ );
174
+ } catch (error) {
175
+ this.logger.error(
176
+ `DatabaseHistoryProvider: Error flushing messages for session ${this.sessionId}: ${error instanceof Error ? error.message : String(error)}`
177
+ );
178
+ throw import_errors.SessionError.storageFailed(
179
+ this.sessionId,
180
+ "flush messages",
181
+ error instanceof Error ? error.message : String(error)
182
+ );
183
+ }
184
+ }
185
+ /**
186
+ * Schedule a debounced flush.
187
+ * Batches rapid updateMessage() calls into a single DB write.
188
+ */
189
+ scheduleFlush() {
190
+ if (this.flushTimer) {
191
+ return;
192
+ }
193
+ this.flushTimer = setTimeout(() => {
194
+ this.flushTimer = null;
195
+ this.doFlush().catch(() => {
196
+ });
197
+ }, DatabaseHistoryProvider.FLUSH_DELAY_MS);
198
+ }
199
+ /**
200
+ * Cancel any pending scheduled flush.
201
+ */
202
+ cancelPendingFlush() {
203
+ if (this.flushTimer) {
204
+ clearTimeout(this.flushTimer);
205
+ this.flushTimer = null;
206
+ }
207
+ }
95
208
  getMessagesKey() {
96
209
  return `messages:${this.sessionId}`;
97
210
  }
@@ -4,24 +4,53 @@ import type { InternalMessage } from '../../context/types.js';
4
4
  import type { IConversationHistoryProvider } from './types.js';
5
5
  /**
6
6
  * History provider that works directly with DatabaseBackend.
7
- * Handles message-specific operations and key formatting internally.
7
+ * Uses write-through caching for read performance while maintaining durability.
8
8
  *
9
- * TODO: Add in-memory caching to reduce database queries.
10
- * Cache should be invalidated on writes and persist across LLM switches.
11
- * Consider caching strategy:
12
- * - Load cache on first getHistory() call
13
- * - Update cache optimistically on saveMessage()
14
- * - Clear cache on clearHistory()
15
- * This will significantly improve performance for sessions with many messages.
9
+ * Caching strategy:
10
+ * - getHistory(): Returns cached messages after first load (eliminates repeated DB reads)
11
+ * - saveMessage(): Updates cache AND writes to DB immediately (new messages are critical)
12
+ * - updateMessage(): Updates cache immediately, debounces DB writes (batches rapid updates)
13
+ * - flush(): Forces all pending updates to DB (called at turn boundaries)
14
+ * - clearHistory(): Clears cache and DB immediately
15
+ *
16
+ * Durability guarantees:
17
+ * - New messages (saveMessage) are always immediately durable
18
+ * - Updates (updateMessage) are durable within flush interval or on explicit flush()
19
+ * - Worst case on crash: lose updates from last flush interval (typically <100ms)
16
20
  */
17
21
  export declare class DatabaseHistoryProvider implements IConversationHistoryProvider {
18
22
  private sessionId;
19
23
  private database;
20
24
  private logger;
25
+ private cache;
26
+ private dirty;
27
+ private flushTimer;
28
+ private flushPromise;
29
+ private static readonly FLUSH_DELAY_MS;
21
30
  constructor(sessionId: string, database: Database, logger: IDextoLogger);
22
31
  getHistory(): Promise<InternalMessage[]>;
23
32
  saveMessage(message: InternalMessage): Promise<void>;
33
+ updateMessage(message: InternalMessage): Promise<void>;
24
34
  clearHistory(): Promise<void>;
35
+ /**
36
+ * Flush any pending updates to the database.
37
+ * Should be called at turn boundaries to ensure durability.
38
+ */
39
+ flush(): Promise<void>;
40
+ /**
41
+ * Internal flush implementation.
42
+ * Writes entire cache to DB (delete + re-append all).
43
+ */
44
+ private doFlush;
45
+ /**
46
+ * Schedule a debounced flush.
47
+ * Batches rapid updateMessage() calls into a single DB write.
48
+ */
49
+ private scheduleFlush;
50
+ /**
51
+ * Cancel any pending scheduled flush.
52
+ */
53
+ private cancelPendingFlush;
25
54
  private getMessagesKey;
26
55
  }
27
56
  //# sourceMappingURL=database.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/session/history/database.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAEvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAE/D;;;;;;;;;;;GAWG;AACH,qBAAa,uBAAwB,YAAW,4BAA4B;IAIpE,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,QAAQ;IAJpB,OAAO,CAAC,MAAM,CAAe;gBAGjB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,QAAQ,EAC1B,MAAM,EAAE,YAAY;IAKlB,UAAU,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAmBxC,WAAW,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAqCpD,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAkBnC,OAAO,CAAC,cAAc;CAGzB"}
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/session/history/database.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAEvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAE/D;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,uBAAwB,YAAW,4BAA4B;IAapE,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,QAAQ;IAbpB,OAAO,CAAC,MAAM,CAAe;IAG7B,OAAO,CAAC,KAAK,CAAkC;IAC/C,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,UAAU,CAA8C;IAChE,OAAO,CAAC,YAAY,CAA8B;IAGlD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAO;gBAGjC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,QAAQ,EAC1B,MAAM,EAAE,YAAY;IAKlB,UAAU,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAyBxC,WAAW,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAoCpD,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAiCtD,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IA0BnC;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAwB5B;;;OAGG;YACW,OAAO;IAoCrB;;;OAGG;IACH,OAAO,CAAC,aAAa;IAerB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,cAAc;CAGzB"}