@dexto/core 1.7.2 → 1.8.1

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 (616) hide show
  1. package/dist/agent/DextoAgent.cjs +163 -77
  2. package/dist/agent/DextoAgent.d.ts +73 -19
  3. package/dist/agent/DextoAgent.d.ts.map +1 -1
  4. package/dist/agent/DextoAgent.js +165 -67
  5. package/dist/agent/agent-options.d.ts +6 -10
  6. package/dist/agent/agent-options.d.ts.map +1 -1
  7. package/dist/agent/agentCard.js +1 -1
  8. package/dist/agent/error-codes.js +1 -1
  9. package/dist/agent/errors.js +1 -1
  10. package/dist/agent/index.d.ts +1 -0
  11. package/dist/agent/index.d.ts.map +1 -1
  12. package/dist/agent/index.js +1 -1
  13. package/dist/agent/schemas.d.ts +2 -2
  14. package/dist/agent/schemas.js +1 -1
  15. package/dist/agent/state-manager.js +1 -1
  16. package/dist/agent/types.d.ts +1 -1
  17. package/dist/agent/types.d.ts.map +1 -1
  18. package/dist/approval/error-codes.cjs +1 -1
  19. package/dist/approval/error-codes.d.ts +1 -1
  20. package/dist/approval/error-codes.d.ts.map +1 -1
  21. package/dist/approval/error-codes.js +2 -2
  22. package/dist/approval/errors.cjs +2 -5
  23. package/dist/approval/errors.d.ts.map +1 -1
  24. package/dist/approval/errors.js +3 -6
  25. package/dist/approval/factory.cjs +19 -4
  26. package/dist/approval/factory.d.ts +4 -1
  27. package/dist/approval/factory.d.ts.map +1 -1
  28. package/dist/approval/factory.js +19 -5
  29. package/dist/approval/index.d.ts +1 -1
  30. package/dist/approval/index.d.ts.map +1 -1
  31. package/dist/approval/index.js +1 -1
  32. package/dist/approval/manager.cjs +168 -26
  33. package/dist/approval/manager.d.ts +46 -12
  34. package/dist/approval/manager.d.ts.map +1 -1
  35. package/dist/approval/manager.js +177 -29
  36. package/dist/approval/schemas.cjs +26 -26
  37. package/dist/approval/schemas.d.ts +29 -29
  38. package/dist/approval/schemas.d.ts.map +1 -1
  39. package/dist/approval/schemas.js +23 -23
  40. package/dist/approval/types.cjs +5 -5
  41. package/dist/approval/types.d.ts +18 -18
  42. package/dist/approval/types.d.ts.map +1 -1
  43. package/dist/approval/types.js +6 -6
  44. package/dist/{chunk-PTJYTZNU.js → chunk-C6A6W6XS.js} +1 -44
  45. package/dist/config/index.cjs +75 -0
  46. package/dist/config/index.d.ts +15 -0
  47. package/dist/config/index.d.ts.map +1 -0
  48. package/dist/config/index.js +50 -0
  49. package/dist/context/compaction/overflow.d.ts +1 -1
  50. package/dist/context/compaction/overflow.d.ts.map +1 -1
  51. package/dist/context/compaction/overflow.js +1 -1
  52. package/dist/context/compaction/strategies/noop.js +1 -1
  53. package/dist/context/compaction/strategies/reactive-overflow-compaction.js +1 -1
  54. package/dist/context/content-clone.cjs +131 -0
  55. package/dist/context/content-clone.d.ts +7 -0
  56. package/dist/context/content-clone.d.ts.map +1 -0
  57. package/dist/context/content-clone.js +104 -0
  58. package/dist/context/error-codes.js +1 -1
  59. package/dist/context/errors.js +1 -1
  60. package/dist/context/index.cjs +2 -0
  61. package/dist/context/index.d.ts +1 -0
  62. package/dist/context/index.d.ts.map +1 -1
  63. package/dist/context/index.js +2 -1
  64. package/dist/context/manager.cjs +52 -41
  65. package/dist/context/manager.d.ts +8 -8
  66. package/dist/context/manager.d.ts.map +1 -1
  67. package/dist/context/manager.js +46 -35
  68. package/dist/context/media-helpers.js +1 -1
  69. package/dist/context/schemas.cjs +77 -0
  70. package/dist/context/schemas.d.ts +5 -0
  71. package/dist/context/schemas.d.ts.map +1 -0
  72. package/dist/context/schemas.js +53 -0
  73. package/dist/context/types.d.ts +1 -1
  74. package/dist/context/types.d.ts.map +1 -1
  75. package/dist/context/types.js +1 -1
  76. package/dist/context/utils.cjs +73 -72
  77. package/dist/context/utils.d.ts +4 -4
  78. package/dist/context/utils.d.ts.map +1 -1
  79. package/dist/context/utils.js +72 -71
  80. package/dist/errors/DextoBaseError.js +1 -1
  81. package/dist/errors/DextoRuntimeError.js +1 -1
  82. package/dist/errors/DextoValidationError.js +1 -1
  83. package/dist/errors/index.js +1 -1
  84. package/dist/errors/result-bridge.js +1 -1
  85. package/dist/errors/types.js +1 -1
  86. package/dist/events/index.cjs +9 -1
  87. package/dist/events/index.d.ts +22 -10
  88. package/dist/events/index.d.ts.map +1 -1
  89. package/dist/events/index.js +10 -2
  90. package/dist/hooks/builtins/content-policy.js +1 -1
  91. package/dist/hooks/builtins/response-sanitizer.js +1 -1
  92. package/dist/hooks/error-codes.js +1 -1
  93. package/dist/hooks/index.js +1 -1
  94. package/dist/hooks/manager.cjs +1 -1
  95. package/dist/hooks/manager.d.ts +2 -2
  96. package/dist/hooks/manager.d.ts.map +1 -1
  97. package/dist/hooks/manager.js +2 -2
  98. package/dist/hooks/types.d.ts +2 -2
  99. package/dist/hooks/types.d.ts.map +1 -1
  100. package/dist/index.browser.cjs +9 -9
  101. package/dist/index.browser.d.ts +4 -4
  102. package/dist/index.browser.d.ts.map +1 -1
  103. package/dist/index.browser.js +2 -2
  104. package/dist/index.cjs +2 -0
  105. package/dist/index.d.ts +1 -0
  106. package/dist/index.d.ts.map +1 -1
  107. package/dist/index.js +2 -1
  108. package/dist/llm/curation-config.cjs +3 -3
  109. package/dist/llm/curation-config.d.ts +1 -1
  110. package/dist/llm/curation-config.js +4 -4
  111. package/dist/llm/curation.cjs +2 -2
  112. package/dist/llm/curation.d.ts +2 -2
  113. package/dist/llm/curation.d.ts.map +1 -1
  114. package/dist/llm/curation.js +2 -2
  115. package/dist/llm/error-codes.js +1 -1
  116. package/dist/llm/errors.cjs +3 -3
  117. package/dist/llm/errors.d.ts +1 -1
  118. package/dist/llm/errors.d.ts.map +1 -1
  119. package/dist/llm/errors.js +2 -2
  120. package/dist/llm/{reasoning/anthropic-betas.cjs → executor/index.cjs} +10 -9
  121. package/dist/llm/executor/index.d.ts +2 -0
  122. package/dist/llm/executor/index.d.ts.map +1 -0
  123. package/dist/llm/executor/index.js +11 -0
  124. package/dist/llm/executor/provider-options.cjs +22 -25
  125. package/dist/llm/executor/provider-options.d.ts +1 -1
  126. package/dist/llm/executor/provider-options.d.ts.map +1 -1
  127. package/dist/llm/executor/provider-options.js +18 -17
  128. package/dist/llm/executor/stream-processor.cjs +28 -139
  129. package/dist/llm/executor/stream-processor.d.ts +3 -14
  130. package/dist/llm/executor/stream-processor.d.ts.map +1 -1
  131. package/dist/llm/executor/stream-processor.js +29 -140
  132. package/dist/llm/{reasoning/profiles/openai.cjs → executor/tool-definitions.cjs} +22 -18
  133. package/dist/llm/executor/tool-definitions.d.ts +4 -0
  134. package/dist/llm/executor/tool-definitions.d.ts.map +1 -0
  135. package/dist/llm/executor/tool-definitions.js +22 -0
  136. package/dist/llm/executor/tool-output-truncator.js +1 -1
  137. package/dist/llm/executor/turn-executor.cjs +1093 -458
  138. package/dist/llm/executor/turn-executor.d.ts +269 -43
  139. package/dist/llm/executor/turn-executor.d.ts.map +1 -1
  140. package/dist/llm/executor/turn-executor.js +1079 -405
  141. package/dist/llm/executor/types.d.ts +7 -1
  142. package/dist/llm/executor/types.d.ts.map +1 -1
  143. package/dist/llm/formatters/vercel.cjs +2 -2
  144. package/dist/llm/formatters/vercel.d.ts +1 -1
  145. package/dist/llm/formatters/vercel.d.ts.map +1 -1
  146. package/dist/llm/formatters/vercel.js +1 -1
  147. package/dist/llm/index.cjs +2 -4
  148. package/dist/llm/index.d.ts +1 -2
  149. package/dist/llm/index.d.ts.map +1 -1
  150. package/dist/llm/index.js +2 -3
  151. package/dist/llm/providers/codex-app-server.cjs +22 -2
  152. package/dist/llm/providers/codex-app-server.d.ts.map +1 -1
  153. package/dist/llm/providers/codex-app-server.js +23 -3
  154. package/dist/llm/providers/codex-base-url.js +1 -1
  155. package/dist/llm/providers/local/ai-sdk-adapter.js +1 -1
  156. package/dist/llm/providers/local/downloader.js +1 -1
  157. package/dist/llm/providers/local/error-codes.js +1 -1
  158. package/dist/llm/providers/local/errors.js +1 -1
  159. package/dist/llm/providers/local/gpu-detector.js +1 -1
  160. package/dist/llm/providers/local/index.js +1 -1
  161. package/dist/llm/providers/local/node-llama-provider.js +1 -1
  162. package/dist/llm/providers/local/ollama-provider.js +1 -1
  163. package/dist/llm/providers/local/registry.js +1 -1
  164. package/dist/llm/providers/local/schemas.js +1 -1
  165. package/dist/llm/providers/openrouter-model-registry.js +1 -1
  166. package/dist/llm/registry/auto-update.cjs +5 -5
  167. package/dist/llm/registry/auto-update.d.ts.map +1 -1
  168. package/dist/llm/registry/auto-update.js +3 -3
  169. package/dist/llm/registry/index.cjs +96 -789
  170. package/dist/llm/registry/index.d.ts +4 -323
  171. package/dist/llm/registry/index.d.ts.map +1 -1
  172. package/dist/llm/registry/index.js +100 -763
  173. package/dist/llm/registry/sync.d.ts +2 -2
  174. package/dist/llm/registry/sync.d.ts.map +1 -1
  175. package/dist/llm/registry/sync.js +1 -1
  176. package/dist/llm/resolver.cjs +7 -6
  177. package/dist/llm/resolver.d.ts +1 -1
  178. package/dist/llm/resolver.js +5 -5
  179. package/dist/llm/schemas.cjs +14 -14
  180. package/dist/llm/schemas.d.ts +1 -1
  181. package/dist/llm/schemas.d.ts.map +1 -1
  182. package/dist/llm/schemas.js +6 -5
  183. package/dist/llm/services/factory.cjs +13 -15
  184. package/dist/llm/services/factory.d.ts +3 -3
  185. package/dist/llm/services/factory.d.ts.map +1 -1
  186. package/dist/llm/services/factory.js +16 -16
  187. package/dist/llm/services/types.d.ts +11 -2
  188. package/dist/llm/services/types.d.ts.map +1 -1
  189. package/dist/llm/services/vercel.cjs +23 -8
  190. package/dist/llm/services/vercel.d.ts +11 -7
  191. package/dist/llm/services/vercel.d.ts.map +1 -1
  192. package/dist/llm/services/vercel.js +24 -9
  193. package/dist/llm/usage-metadata.cjs +23 -6
  194. package/dist/llm/usage-metadata.d.ts +3 -2
  195. package/dist/llm/usage-metadata.d.ts.map +1 -1
  196. package/dist/llm/usage-metadata.js +20 -7
  197. package/dist/llm/usage-scope.js +1 -1
  198. package/dist/llm/usage-summary.d.ts +1 -1
  199. package/dist/llm/usage-summary.js +1 -1
  200. package/dist/llm/validation.cjs +4 -4
  201. package/dist/llm/validation.d.ts +1 -1
  202. package/dist/llm/validation.js +2 -2
  203. package/dist/logger/browser.js +1 -1
  204. package/dist/logger/default-logger-factory.js +1 -1
  205. package/dist/logger/factory.js +1 -1
  206. package/dist/logger/index.js +1 -1
  207. package/dist/logger/logger.js +1 -1
  208. package/dist/logger/v2/dexto-logger.js +1 -1
  209. package/dist/logger/v2/error-codes.js +1 -1
  210. package/dist/logger/v2/errors.js +1 -1
  211. package/dist/logger/v2/schemas.js +1 -1
  212. package/dist/logger/v2/test-utils.js +1 -1
  213. package/dist/logger/v2/transport-factory.js +1 -1
  214. package/dist/logger/v2/transports/console-transport.js +1 -1
  215. package/dist/logger/v2/transports/file-transport.js +1 -1
  216. package/dist/logger/v2/transports/silent-transport.js +1 -1
  217. package/dist/logger/v2/types.js +1 -1
  218. package/dist/mcp/bundled-config.js +1 -1
  219. package/dist/mcp/error-codes.js +1 -1
  220. package/dist/mcp/errors.js +1 -1
  221. package/dist/mcp/index.js +1 -1
  222. package/dist/mcp/manager.js +1 -1
  223. package/dist/mcp/mcp-client.js +1 -1
  224. package/dist/mcp/resolver.js +1 -1
  225. package/dist/mcp/schemas.js +1 -1
  226. package/dist/memory/error-codes.js +1 -1
  227. package/dist/memory/errors.js +1 -1
  228. package/dist/memory/index.js +1 -1
  229. package/dist/memory/manager.cjs +7 -27
  230. package/dist/memory/manager.d.ts +4 -12
  231. package/dist/memory/manager.d.ts.map +1 -1
  232. package/dist/memory/manager.js +8 -28
  233. package/dist/memory/schemas.js +1 -1
  234. package/dist/prompts/error-codes.js +1 -1
  235. package/dist/prompts/errors.js +1 -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 +9 -38
  239. package/dist/prompts/prompt-manager.d.ts +2 -10
  240. package/dist/prompts/prompt-manager.d.ts.map +1 -1
  241. package/dist/prompts/prompt-manager.js +10 -39
  242. package/dist/prompts/providers/config-prompt-provider.cjs +8 -87
  243. package/dist/prompts/providers/config-prompt-provider.d.ts.map +1 -1
  244. package/dist/prompts/providers/config-prompt-provider.js +9 -88
  245. package/dist/prompts/providers/custom-prompt-provider.cjs +21 -22
  246. package/dist/prompts/providers/custom-prompt-provider.d.ts +19 -4
  247. package/dist/prompts/providers/custom-prompt-provider.d.ts.map +1 -1
  248. package/dist/prompts/providers/custom-prompt-provider.js +22 -23
  249. package/dist/prompts/providers/mcp-prompt-provider.js +1 -1
  250. package/dist/prompts/schemas.cjs +2 -24
  251. package/dist/prompts/schemas.d.ts +0 -52
  252. package/dist/prompts/schemas.d.ts.map +1 -1
  253. package/dist/prompts/schemas.js +3 -25
  254. package/dist/prompts/types.d.ts +5 -32
  255. package/dist/prompts/types.d.ts.map +1 -1
  256. package/dist/prompts/utils.js +1 -1
  257. package/dist/resources/agent-resources-provider.js +1 -1
  258. package/dist/resources/error-codes.js +1 -1
  259. package/dist/resources/errors.js +1 -1
  260. package/dist/resources/handlers/blob-handler.cjs +14 -11
  261. package/dist/resources/handlers/blob-handler.d.ts +4 -4
  262. package/dist/resources/handlers/blob-handler.d.ts.map +1 -1
  263. package/dist/resources/handlers/blob-handler.js +15 -12
  264. package/dist/resources/handlers/factory.cjs +3 -3
  265. package/dist/resources/handlers/factory.js +4 -4
  266. package/dist/resources/handlers/filesystem-handler.js +1 -1
  267. package/dist/resources/handlers/types.d.ts +2 -2
  268. package/dist/resources/handlers/types.d.ts.map +1 -1
  269. package/dist/resources/index.js +1 -1
  270. package/dist/resources/manager.cjs +10 -7
  271. package/dist/resources/manager.d.ts +4 -4
  272. package/dist/resources/manager.d.ts.map +1 -1
  273. package/dist/resources/manager.js +11 -8
  274. package/dist/resources/reference-parser.js +1 -1
  275. package/dist/resources/schemas.cjs +1 -1
  276. package/dist/resources/schemas.d.ts +2 -2
  277. package/dist/resources/schemas.js +2 -2
  278. package/dist/runtime/host-runtime.js +1 -1
  279. package/dist/runtime/index.cjs +3 -0
  280. package/dist/runtime/index.d.ts +2 -0
  281. package/dist/runtime/index.d.ts.map +1 -1
  282. package/dist/runtime/index.js +3 -1
  283. package/dist/runtime/run-context.js +1 -1
  284. package/dist/search/index.js +1 -1
  285. package/dist/search/search-service.cjs +6 -13
  286. package/dist/search/search-service.d.ts +5 -3
  287. package/dist/search/search-service.d.ts.map +1 -1
  288. package/dist/search/search-service.js +7 -14
  289. package/dist/session/chat-session.cjs +264 -108
  290. package/dist/session/chat-session.d.ts +75 -21
  291. package/dist/session/chat-session.d.ts.map +1 -1
  292. package/dist/session/chat-session.js +268 -108
  293. package/dist/session/error-codes.js +1 -1
  294. package/dist/session/errors.js +1 -1
  295. package/dist/session/index.cjs +19 -2
  296. package/dist/session/index.d.ts +4 -3
  297. package/dist/session/index.d.ts.map +1 -1
  298. package/dist/session/index.js +19 -3
  299. package/dist/session/message-queue.cjs +82 -51
  300. package/dist/session/message-queue.d.ts +13 -8
  301. package/dist/session/message-queue.d.ts.map +1 -1
  302. package/dist/session/message-queue.js +83 -52
  303. package/dist/session/queue-clone.cjs +50 -0
  304. package/dist/session/queue-clone.d.ts +5 -0
  305. package/dist/session/queue-clone.d.ts.map +1 -0
  306. package/dist/session/queue-clone.js +25 -0
  307. package/dist/session/schemas.cjs +74 -2
  308. package/dist/session/schemas.d.ts +94 -0
  309. package/dist/session/schemas.d.ts.map +1 -1
  310. package/dist/session/schemas.js +69 -2
  311. package/dist/session/session-manager.cjs +107 -123
  312. package/dist/session/session-manager.d.ts +8 -7
  313. package/dist/session/session-manager.d.ts.map +1 -1
  314. package/dist/session/session-manager.js +108 -124
  315. package/dist/session/title-generator.cjs +14 -26
  316. package/dist/session/title-generator.d.ts +4 -6
  317. package/dist/session/title-generator.d.ts.map +1 -1
  318. package/dist/session/title-generator.js +16 -28
  319. package/dist/session/types.cjs +28 -0
  320. package/dist/session/types.d.ts +5 -1
  321. package/dist/session/types.d.ts.map +1 -1
  322. package/dist/session/types.js +19 -0
  323. package/dist/{session/history/factory.cjs → skills/index.cjs} +9 -9
  324. package/dist/skills/index.d.ts +4 -0
  325. package/dist/skills/index.d.ts.map +1 -0
  326. package/dist/skills/index.js +7 -0
  327. package/dist/skills/skill-manager.cjs +76 -0
  328. package/dist/skills/skill-manager.d.ts +13 -0
  329. package/dist/skills/skill-manager.d.ts.map +1 -0
  330. package/dist/skills/skill-manager.js +53 -0
  331. package/dist/skills/types.d.ts +24 -0
  332. package/dist/skills/types.d.ts.map +1 -0
  333. package/dist/skills/workspace-skill-source.cjs +120 -0
  334. package/dist/skills/workspace-skill-source.d.ts +16 -0
  335. package/dist/skills/workspace-skill-source.d.ts.map +1 -0
  336. package/dist/skills/workspace-skill-source.js +97 -0
  337. package/dist/{llm → storage/approvals}/types.cjs +13 -30
  338. package/dist/storage/approvals/types.d.ts +54 -0
  339. package/dist/storage/approvals/types.d.ts.map +1 -0
  340. package/dist/storage/approvals/types.js +14 -0
  341. package/dist/storage/artifacts/types.d.ts +73 -0
  342. package/dist/storage/artifacts/types.d.ts.map +1 -0
  343. package/dist/storage/conversation/database.cjs +233 -0
  344. package/dist/storage/conversation/database.d.ts +38 -0
  345. package/dist/storage/conversation/database.d.ts.map +1 -0
  346. package/dist/storage/conversation/database.js +210 -0
  347. package/dist/storage/conversation/types.cjs +16 -0
  348. package/dist/storage/conversation/types.d.ts +21 -0
  349. package/dist/storage/conversation/types.d.ts.map +1 -0
  350. package/dist/storage/conversation/types.js +0 -0
  351. package/dist/storage/database/types.d.ts +4 -0
  352. package/dist/storage/database/types.d.ts.map +1 -1
  353. package/dist/storage/error-codes.js +1 -1
  354. package/dist/storage/errors.cjs +6 -6
  355. package/dist/storage/errors.d.ts +2 -2
  356. package/dist/storage/errors.js +7 -7
  357. package/dist/storage/index.cjs +42 -5
  358. package/dist/storage/index.d.ts +19 -8
  359. package/dist/storage/index.d.ts.map +1 -1
  360. package/dist/storage/index.js +39 -4
  361. package/dist/storage/memories/types.cjs +16 -0
  362. package/dist/storage/memories/types.d.ts +17 -0
  363. package/dist/storage/memories/types.d.ts.map +1 -0
  364. package/dist/storage/memories/types.js +0 -0
  365. package/dist/storage/message-queue/types.cjs +16 -0
  366. package/dist/storage/message-queue/types.d.ts +15 -0
  367. package/dist/storage/message-queue/types.d.ts.map +1 -0
  368. package/dist/storage/message-queue/types.js +0 -0
  369. package/dist/storage/prompts/types.cjs +16 -0
  370. package/dist/storage/prompts/types.d.ts +14 -0
  371. package/dist/storage/prompts/types.d.ts.map +1 -0
  372. package/dist/storage/prompts/types.js +0 -0
  373. package/dist/storage/runtime-events/types.cjs +16 -0
  374. package/dist/storage/runtime-events/types.d.ts +19 -0
  375. package/dist/storage/runtime-events/types.d.ts.map +1 -0
  376. package/dist/storage/runtime-events/types.js +0 -0
  377. package/dist/storage/sessions/types.cjs +16 -0
  378. package/dist/storage/sessions/types.d.ts +19 -0
  379. package/dist/storage/sessions/types.d.ts.map +1 -0
  380. package/dist/storage/sessions/types.js +0 -0
  381. package/dist/storage/stores/backend.cjs +702 -0
  382. package/dist/storage/stores/backend.d.ts +303 -0
  383. package/dist/storage/stores/backend.d.ts.map +1 -0
  384. package/dist/storage/stores/backend.js +677 -0
  385. package/dist/storage/stores/in-memory.cjs +510 -0
  386. package/dist/storage/stores/in-memory.d.ts +11 -0
  387. package/dist/storage/stores/in-memory.d.ts.map +1 -0
  388. package/dist/storage/stores/in-memory.js +487 -0
  389. package/dist/storage/stores/types.cjs +16 -0
  390. package/dist/storage/stores/types.d.ts +36 -0
  391. package/dist/storage/stores/types.d.ts.map +1 -0
  392. package/dist/storage/stores/types.js +0 -0
  393. package/dist/storage/tool-executions/types.cjs +127 -0
  394. package/dist/storage/tool-executions/types.d.ts +193 -0
  395. package/dist/storage/tool-executions/types.d.ts.map +1 -0
  396. package/dist/storage/tool-executions/types.js +96 -0
  397. package/dist/storage/tool-preferences/types.cjs +16 -0
  398. package/dist/storage/tool-preferences/types.d.ts +29 -0
  399. package/dist/storage/tool-preferences/types.d.ts.map +1 -0
  400. package/dist/storage/tool-preferences/types.js +0 -0
  401. package/dist/storage/tool-state/types.cjs +16 -0
  402. package/dist/storage/tool-state/types.d.ts +20 -0
  403. package/dist/storage/tool-state/types.d.ts.map +1 -0
  404. package/dist/storage/tool-state/types.js +0 -0
  405. package/dist/storage/workspaces/types.cjs +16 -0
  406. package/dist/storage/workspaces/types.d.ts +19 -0
  407. package/dist/storage/workspaces/types.d.ts.map +1 -0
  408. package/dist/storage/workspaces/types.js +0 -0
  409. package/dist/systemPrompt/contributors.cjs +10 -14
  410. package/dist/systemPrompt/contributors.d.ts +3 -3
  411. package/dist/systemPrompt/contributors.d.ts.map +1 -1
  412. package/dist/systemPrompt/contributors.js +11 -15
  413. package/dist/systemPrompt/error-codes.js +1 -1
  414. package/dist/systemPrompt/errors.js +1 -1
  415. package/dist/systemPrompt/in-built-prompts.js +1 -1
  416. package/dist/systemPrompt/index.js +1 -1
  417. package/dist/systemPrompt/manager.js +1 -1
  418. package/dist/systemPrompt/registry.js +1 -1
  419. package/dist/systemPrompt/schemas.js +1 -1
  420. package/dist/telemetry/decorators.js +1 -1
  421. package/dist/telemetry/error-codes.js +1 -1
  422. package/dist/telemetry/errors.js +1 -1
  423. package/dist/telemetry/exporters.js +1 -1
  424. package/dist/telemetry/index.js +1 -1
  425. package/dist/telemetry/schemas.js +1 -1
  426. package/dist/telemetry/telemetry.js +1 -1
  427. package/dist/telemetry/utils.js +1 -1
  428. package/dist/test-utils/in-memory-storage.cjs +9 -17
  429. package/dist/test-utils/in-memory-storage.js +9 -16
  430. package/dist/test-utils/session-state-stores.cjs +21 -24
  431. package/dist/test-utils/session-state-stores.js +22 -24
  432. package/dist/tools/{confirmation → approval}/allowed-tools-provider/factory.cjs +1 -1
  433. package/dist/tools/{confirmation → approval}/allowed-tools-provider/factory.d.ts +2 -2
  434. package/dist/tools/approval/allowed-tools-provider/factory.d.ts.map +1 -0
  435. package/dist/tools/{confirmation → approval}/allowed-tools-provider/factory.js +2 -2
  436. package/dist/tools/approval/allowed-tools-provider/in-memory.d.ts.map +1 -0
  437. package/dist/tools/{confirmation → approval}/allowed-tools-provider/in-memory.js +1 -1
  438. package/dist/tools/approval/allowed-tools-provider/storage.cjs +66 -0
  439. package/dist/tools/{confirmation → approval}/allowed-tools-provider/storage.d.ts +4 -10
  440. package/dist/tools/approval/allowed-tools-provider/storage.d.ts.map +1 -0
  441. package/dist/tools/approval/allowed-tools-provider/storage.js +43 -0
  442. package/dist/tools/approval/allowed-tools-provider/types.cjs +16 -0
  443. package/dist/tools/approval/allowed-tools-provider/types.d.ts.map +1 -0
  444. package/dist/tools/approval/allowed-tools-provider/types.js +0 -0
  445. package/dist/tools/approval/session-tool-policy.cjs +269 -0
  446. package/dist/tools/approval/session-tool-policy.d.ts +43 -0
  447. package/dist/tools/approval/session-tool-policy.d.ts.map +1 -0
  448. package/dist/tools/approval/session-tool-policy.js +245 -0
  449. package/dist/tools/define-tool.js +1 -1
  450. package/dist/tools/display-types.js +1 -1
  451. package/dist/tools/error-codes.cjs +3 -3
  452. package/dist/tools/error-codes.d.ts +4 -4
  453. package/dist/tools/error-codes.d.ts.map +1 -1
  454. package/dist/tools/error-codes.js +4 -4
  455. package/dist/tools/errors.cjs +12 -12
  456. package/dist/tools/errors.d.ts +6 -6
  457. package/dist/tools/errors.d.ts.map +1 -1
  458. package/dist/tools/errors.js +13 -13
  459. package/dist/tools/index.cjs +3 -0
  460. package/dist/tools/index.d.ts +3 -0
  461. package/dist/tools/index.d.ts.map +1 -1
  462. package/dist/tools/index.js +3 -1
  463. package/dist/tools/pattern-utils.js +1 -1
  464. package/dist/tools/presentation/tool-presentation.cjs +182 -0
  465. package/dist/tools/presentation/tool-presentation.d.ts +51 -0
  466. package/dist/tools/presentation/tool-presentation.d.ts.map +1 -0
  467. package/dist/tools/presentation/tool-presentation.js +159 -0
  468. package/dist/tools/presentation.js +1 -1
  469. package/dist/tools/schemas.cjs +5 -10
  470. package/dist/tools/schemas.d.ts +1 -4
  471. package/dist/tools/schemas.d.ts.map +1 -1
  472. package/dist/tools/schemas.js +6 -11
  473. package/dist/tools/session-tool-preferences-store.cjs +12 -28
  474. package/dist/tools/session-tool-preferences-store.d.ts +4 -7
  475. package/dist/tools/session-tool-preferences-store.d.ts.map +1 -1
  476. package/dist/tools/session-tool-preferences-store.js +12 -29
  477. package/dist/tools/tool-call-metadata.js +1 -1
  478. package/dist/tools/tool-manager.cjs +871 -834
  479. package/dist/tools/tool-manager.d.ts +94 -96
  480. package/dist/tools/tool-manager.d.ts.map +1 -1
  481. package/dist/tools/tool-manager.js +876 -833
  482. package/dist/tools/types.d.ts +10 -14
  483. package/dist/tools/types.d.ts.map +1 -1
  484. package/dist/utils/api-key-resolver.d.ts +1 -1
  485. package/dist/utils/api-key-resolver.d.ts.map +1 -1
  486. package/dist/utils/api-key-resolver.js +1 -1
  487. package/dist/utils/async-context.js +1 -1
  488. package/dist/utils/debug.js +1 -1
  489. package/dist/utils/defer.js +1 -1
  490. package/dist/utils/env.js +1 -1
  491. package/dist/utils/error-conversion.js +1 -1
  492. package/dist/utils/execution-context.js +1 -1
  493. package/dist/utils/fs-walk.js +1 -1
  494. package/dist/utils/path.js +1 -1
  495. package/dist/utils/redactor.js +1 -1
  496. package/dist/utils/result.js +1 -1
  497. package/dist/utils/safe-stringify.js +1 -1
  498. package/dist/utils/schema.js +1 -1
  499. package/dist/utils/service-initializer.cjs +37 -33
  500. package/dist/utils/service-initializer.d.ts +9 -5
  501. package/dist/utils/service-initializer.d.ts.map +1 -1
  502. package/dist/utils/service-initializer.js +38 -34
  503. package/dist/utils/zod-schema-converter.js +1 -1
  504. package/dist/workspace/error-codes.cjs +5 -1
  505. package/dist/workspace/error-codes.d.ts +4 -0
  506. package/dist/workspace/error-codes.d.ts.map +1 -1
  507. package/dist/workspace/error-codes.js +6 -2
  508. package/dist/workspace/errors.cjs +43 -0
  509. package/dist/workspace/errors.d.ts +9 -0
  510. package/dist/workspace/errors.d.ts.map +1 -1
  511. package/dist/workspace/errors.js +44 -1
  512. package/dist/workspace/index.d.ts +1 -1
  513. package/dist/workspace/index.d.ts.map +1 -1
  514. package/dist/workspace/index.js +1 -1
  515. package/dist/workspace/manager.cjs +21 -29
  516. package/dist/workspace/manager.d.ts +6 -6
  517. package/dist/workspace/manager.d.ts.map +1 -1
  518. package/dist/workspace/manager.js +22 -30
  519. package/dist/workspace/types.d.ts +47 -0
  520. package/dist/workspace/types.d.ts.map +1 -1
  521. package/package.json +116 -3
  522. package/dist/approval/session-approval-store.cjs +0 -91
  523. package/dist/approval/session-approval-store.d.ts +0 -37
  524. package/dist/approval/session-approval-store.d.ts.map +0 -1
  525. package/dist/approval/session-approval-store.js +0 -68
  526. package/dist/llm/reasoning/anthropic-betas.d.ts +0 -3
  527. package/dist/llm/reasoning/anthropic-betas.d.ts.map +0 -1
  528. package/dist/llm/reasoning/anthropic-betas.js +0 -7
  529. package/dist/llm/reasoning/anthropic-thinking.cjs +0 -79
  530. package/dist/llm/reasoning/anthropic-thinking.d.ts +0 -15
  531. package/dist/llm/reasoning/anthropic-thinking.d.ts.map +0 -1
  532. package/dist/llm/reasoning/anthropic-thinking.js +0 -52
  533. package/dist/llm/reasoning/openai-reasoning-effort.cjs +0 -86
  534. package/dist/llm/reasoning/openai-reasoning-effort.d.ts +0 -5
  535. package/dist/llm/reasoning/openai-reasoning-effort.d.ts.map +0 -1
  536. package/dist/llm/reasoning/openai-reasoning-effort.js +0 -61
  537. package/dist/llm/reasoning/profile.cjs +0 -113
  538. package/dist/llm/reasoning/profile.d.ts +0 -13
  539. package/dist/llm/reasoning/profile.d.ts.map +0 -1
  540. package/dist/llm/reasoning/profile.js +0 -92
  541. package/dist/llm/reasoning/profiles/anthropic.cjs +0 -61
  542. package/dist/llm/reasoning/profiles/anthropic.d.ts +0 -8
  543. package/dist/llm/reasoning/profiles/anthropic.d.ts.map +0 -1
  544. package/dist/llm/reasoning/profiles/anthropic.js +0 -45
  545. package/dist/llm/reasoning/profiles/bedrock.cjs +0 -54
  546. package/dist/llm/reasoning/profiles/bedrock.d.ts +0 -3
  547. package/dist/llm/reasoning/profiles/bedrock.d.ts.map +0 -1
  548. package/dist/llm/reasoning/profiles/bedrock.js +0 -36
  549. package/dist/llm/reasoning/profiles/google.cjs +0 -45
  550. package/dist/llm/reasoning/profiles/google.d.ts +0 -9
  551. package/dist/llm/reasoning/profiles/google.d.ts.map +0 -1
  552. package/dist/llm/reasoning/profiles/google.js +0 -21
  553. package/dist/llm/reasoning/profiles/openai-compatible.cjs +0 -39
  554. package/dist/llm/reasoning/profiles/openai-compatible.d.ts +0 -3
  555. package/dist/llm/reasoning/profiles/openai-compatible.d.ts.map +0 -1
  556. package/dist/llm/reasoning/profiles/openai-compatible.js +0 -16
  557. package/dist/llm/reasoning/profiles/openai.d.ts +0 -3
  558. package/dist/llm/reasoning/profiles/openai.d.ts.map +0 -1
  559. package/dist/llm/reasoning/profiles/openai.js +0 -18
  560. package/dist/llm/reasoning/profiles/openrouter.cjs +0 -83
  561. package/dist/llm/reasoning/profiles/openrouter.d.ts +0 -10
  562. package/dist/llm/reasoning/profiles/openrouter.d.ts.map +0 -1
  563. package/dist/llm/reasoning/profiles/openrouter.js +0 -59
  564. package/dist/llm/reasoning/profiles/shared.cjs +0 -80
  565. package/dist/llm/reasoning/profiles/shared.d.ts +0 -25
  566. package/dist/llm/reasoning/profiles/shared.d.ts.map +0 -1
  567. package/dist/llm/reasoning/profiles/shared.js +0 -53
  568. package/dist/llm/reasoning/profiles/vertex.cjs +0 -46
  569. package/dist/llm/reasoning/profiles/vertex.d.ts +0 -3
  570. package/dist/llm/reasoning/profiles/vertex.d.ts.map +0 -1
  571. package/dist/llm/reasoning/profiles/vertex.js +0 -23
  572. package/dist/llm/registry/models.generated.cjs +0 -10741
  573. package/dist/llm/registry/models.generated.d.ts +0 -2945
  574. package/dist/llm/registry/models.generated.d.ts.map +0 -1
  575. package/dist/llm/registry/models.generated.js +0 -10717
  576. package/dist/llm/registry/models.manual.cjs +0 -44
  577. package/dist/llm/registry/models.manual.d.ts +0 -22
  578. package/dist/llm/registry/models.manual.d.ts.map +0 -1
  579. package/dist/llm/registry/models.manual.js +0 -21
  580. package/dist/llm/types.d.ts +0 -39
  581. package/dist/llm/types.d.ts.map +0 -1
  582. package/dist/llm/types.js +0 -30
  583. package/dist/session/history/database.cjs +0 -232
  584. package/dist/session/history/database.d.ts +0 -41
  585. package/dist/session/history/database.d.ts.map +0 -1
  586. package/dist/session/history/database.js +0 -209
  587. package/dist/session/history/factory.d.ts +0 -11
  588. package/dist/session/history/factory.d.ts.map +0 -1
  589. package/dist/session/history/factory.js +0 -8
  590. package/dist/session/history/memory.cjs +0 -57
  591. package/dist/session/history/memory.d.ts +0 -22
  592. package/dist/session/history/memory.d.ts.map +0 -1
  593. package/dist/session/history/memory.js +0 -34
  594. package/dist/session/history/types.d.ts +0 -26
  595. package/dist/session/history/types.d.ts.map +0 -1
  596. package/dist/session/message-queue-store.cjs +0 -75
  597. package/dist/session/message-queue-store.d.ts +0 -16
  598. package/dist/session/message-queue-store.d.ts.map +0 -1
  599. package/dist/session/message-queue-store.js +0 -52
  600. package/dist/storage/storage-manager.cjs +0 -209
  601. package/dist/storage/storage-manager.d.ts +0 -77
  602. package/dist/storage/storage-manager.d.ts.map +0 -1
  603. package/dist/storage/storage-manager.js +0 -186
  604. package/dist/tools/confirmation/allowed-tools-provider/factory.d.ts.map +0 -1
  605. package/dist/tools/confirmation/allowed-tools-provider/in-memory.d.ts.map +0 -1
  606. package/dist/tools/confirmation/allowed-tools-provider/storage.cjs +0 -69
  607. package/dist/tools/confirmation/allowed-tools-provider/storage.d.ts.map +0 -1
  608. package/dist/tools/confirmation/allowed-tools-provider/storage.js +0 -46
  609. package/dist/tools/confirmation/allowed-tools-provider/types.d.ts.map +0 -1
  610. /package/dist/{session/history → skills}/types.cjs +0 -0
  611. /package/dist/{session/history → skills}/types.js +0 -0
  612. /package/dist/{tools/confirmation/allowed-tools-provider → storage/artifacts}/types.cjs +0 -0
  613. /package/dist/{tools/confirmation/allowed-tools-provider → storage/artifacts}/types.js +0 -0
  614. /package/dist/tools/{confirmation → approval}/allowed-tools-provider/in-memory.cjs +0 -0
  615. /package/dist/tools/{confirmation → approval}/allowed-tools-provider/in-memory.d.ts +0 -0
  616. /package/dist/tools/{confirmation → approval}/allowed-tools-provider/types.d.ts +0 -0
@@ -5,10 +5,6 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
9
- var __typeError = (msg) => {
10
- throw TypeError(msg);
11
- };
12
8
  var __export = (target, all) => {
13
9
  for (var name in all)
14
10
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -30,67 +26,164 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
26
  mod
31
27
  ));
32
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
33
- var __using = (stack, value, async) => {
34
- if (value != null) {
35
- if (typeof value !== "object" && typeof value !== "function") __typeError("Object expected");
36
- var dispose, inner;
37
- if (async) dispose = value[__knownSymbol("asyncDispose")];
38
- if (dispose === void 0) {
39
- dispose = value[__knownSymbol("dispose")];
40
- if (async) inner = dispose;
41
- }
42
- if (typeof dispose !== "function") __typeError("Object not disposable");
43
- if (inner) dispose = function() {
44
- try {
45
- inner.call(this);
46
- } catch (e) {
47
- return Promise.reject(e);
48
- }
49
- };
50
- stack.push([async, dispose, value]);
51
- } else if (async) {
52
- stack.push([async]);
53
- }
54
- return value;
55
- };
56
- var __callDispose = (stack, error, hasError) => {
57
- var E = typeof SuppressedError === "function" ? SuppressedError : function(e, s, m, _) {
58
- return _ = Error(m), _.name = "SuppressedError", _.error = e, _.suppressed = s, _;
59
- };
60
- var fail = (e) => error = hasError ? new E(e, error, "An error was suppressed during disposal") : (hasError = true, e);
61
- var next = (it) => {
62
- while (it = stack.pop()) {
63
- try {
64
- var result = it[1] && it[1].call(it[2]);
65
- if (it[0]) return Promise.resolve(result).then(next, (e) => (fail(e), next()));
66
- } catch (e) {
67
- fail(e);
68
- }
69
- }
70
- if (hasError) throw error;
71
- };
72
- return next();
73
- };
74
29
  var turn_executor_exports = {};
75
30
  __export(turn_executor_exports, {
76
- TurnExecutor: () => TurnExecutor
31
+ ModelStepResultStateSchema: () => ModelStepResultStateSchema,
32
+ TurnDriverStateSchema: () => TurnDriverStateSchema,
33
+ TurnExecutor: () => TurnExecutor,
34
+ parseTurnDriverState: () => parseTurnDriverState
77
35
  });
78
36
  module.exports = __toCommonJS(turn_executor_exports);
79
37
  var import_ai = require("ai");
38
+ var import_zod = require("zod");
80
39
  var import_api = require("@opentelemetry/api");
40
+ var import_utils = require("../../context/utils.js");
81
41
  var import_stream_processor = require("./stream-processor.js");
42
+ var import_tool_output_truncator = require("./tool-output-truncator.js");
82
43
  var import_provider_options = require("./provider-options.js");
83
- var import_types3 = require("../../logger/v2/types.js");
84
- var import_defer = require("../../utils/defer.js");
44
+ var import_types = require("../../logger/v2/types.js");
85
45
  var import_DextoRuntimeError = require("../../errors/DextoRuntimeError.js");
86
- var import_types5 = require("../../errors/types.js");
46
+ var import_types3 = require("../../errors/types.js");
87
47
  var import_error_codes = require("../error-codes.js");
88
48
  var import_error_conversion = require("../../utils/error-conversion.js");
89
49
  var import_codex_base_url = require("../providers/codex-base-url.js");
50
+ var import_tool_definitions = require("./tool-definitions.js");
51
+ var import_types4 = require("../../approval/types.js");
52
+ const MCP_TOOL_PREFIX = "mcp--";
53
+ const MODEL_REQUEST_MAX_RETRIES = 2;
54
+ const LLMFinishReasonStateSchema = import_zod.z.enum([
55
+ "stop",
56
+ "tool-calls",
57
+ "length",
58
+ "content-filter",
59
+ "error",
60
+ "other",
61
+ "unknown",
62
+ "cancelled",
63
+ "max-steps"
64
+ ]);
65
+ const TokenUsageStateSchema = import_zod.z.object({
66
+ inputTokens: import_zod.z.number().optional(),
67
+ outputTokens: import_zod.z.number().optional(),
68
+ reasoningTokens: import_zod.z.number().optional(),
69
+ totalTokens: import_zod.z.number().optional(),
70
+ cacheReadTokens: import_zod.z.number().optional(),
71
+ cacheWriteTokens: import_zod.z.number().optional()
72
+ }).strict().transform((parsed) => {
73
+ const usage = {};
74
+ if (parsed.inputTokens !== void 0) usage.inputTokens = parsed.inputTokens;
75
+ if (parsed.outputTokens !== void 0) usage.outputTokens = parsed.outputTokens;
76
+ if (parsed.reasoningTokens !== void 0) usage.reasoningTokens = parsed.reasoningTokens;
77
+ if (parsed.totalTokens !== void 0) usage.totalTokens = parsed.totalTokens;
78
+ if (parsed.cacheReadTokens !== void 0) usage.cacheReadTokens = parsed.cacheReadTokens;
79
+ if (parsed.cacheWriteTokens !== void 0) usage.cacheWriteTokens = parsed.cacheWriteTokens;
80
+ return usage;
81
+ });
82
+ const ModelToolCallStateSchema = import_zod.z.object({
83
+ toolCallId: import_zod.z.string(),
84
+ toolName: import_zod.z.string(),
85
+ input: import_zod.z.unknown()
86
+ }).strict();
87
+ const ModelStepResultStateSchema = import_zod.z.object({
88
+ text: import_zod.z.string(),
89
+ finishReason: LLMFinishReasonStateSchema,
90
+ usage: TokenUsageStateSchema,
91
+ toolCalls: import_zod.z.array(ModelToolCallStateSchema)
92
+ }).strict();
93
+ const JsonValueSchema = import_zod.z.json();
94
+ const ProviderOptionsStateSchema = import_zod.z.record(
95
+ import_zod.z.string(),
96
+ import_zod.z.record(import_zod.z.string(), JsonValueSchema)
97
+ );
98
+ const JsonSchemaStateSchema = import_zod.z.custom(
99
+ (value) => typeof value === "object" && value !== null && !Array.isArray(value)
100
+ );
101
+ const ToolSetEntryStateSchema = import_zod.z.object({
102
+ name: import_zod.z.string().optional(),
103
+ description: import_zod.z.string().optional(),
104
+ parameters: JsonSchemaStateSchema,
105
+ _meta: import_zod.z.record(import_zod.z.string(), JsonValueSchema).optional()
106
+ }).strict().transform((parsed) => {
107
+ const tool = { parameters: parsed.parameters };
108
+ if (parsed.name !== void 0) tool.name = parsed.name;
109
+ if (parsed.description !== void 0) tool.description = parsed.description;
110
+ if (parsed._meta !== void 0) tool._meta = parsed._meta;
111
+ return tool;
112
+ });
113
+ const ToolSetStateSchema = import_zod.z.record(import_zod.z.string(), ToolSetEntryStateSchema);
114
+ const ModelStepRequestStateSchema = import_zod.z.object({
115
+ messages: import_zod.z.array(
116
+ import_zod.z.custom(
117
+ (value) => typeof value === "object" && value !== null && !Array.isArray(value)
118
+ )
119
+ ),
120
+ estimatedInputTokens: import_zod.z.number().int().nonnegative(),
121
+ toolDefinitions: ToolSetStateSchema,
122
+ reasoning: import_zod.z.object({
123
+ reasoningVariant: import_zod.z.string().optional(),
124
+ reasoningBudgetTokens: import_zod.z.number().int().positive().optional()
125
+ }).strict().optional(),
126
+ providerOptions: ProviderOptionsStateSchema.optional(),
127
+ streaming: import_zod.z.boolean()
128
+ }).strict();
129
+ const TurnDriverStateSchema = import_zod.z.discriminatedUnion("phase", [
130
+ import_zod.z.object({
131
+ phase: import_zod.z.literal("ready-for-model"),
132
+ stepCount: import_zod.z.number().int().nonnegative(),
133
+ startedAtMs: import_zod.z.number().int().nonnegative(),
134
+ supportsTools: import_zod.z.boolean(),
135
+ lastText: import_zod.z.string(),
136
+ lastUsage: TokenUsageStateSchema.nullable(),
137
+ lastFinishReason: LLMFinishReasonStateSchema
138
+ }).strict(),
139
+ import_zod.z.object({
140
+ phase: import_zod.z.literal("model-step-prepared"),
141
+ stepCount: import_zod.z.number().int().nonnegative(),
142
+ startedAtMs: import_zod.z.number().int().nonnegative(),
143
+ supportsTools: import_zod.z.boolean(),
144
+ modelStepId: import_zod.z.string(),
145
+ request: ModelStepRequestStateSchema,
146
+ lastText: import_zod.z.string(),
147
+ lastUsage: TokenUsageStateSchema.nullable(),
148
+ lastFinishReason: LLMFinishReasonStateSchema
149
+ }).strict(),
150
+ import_zod.z.object({
151
+ phase: import_zod.z.literal("model-step-complete"),
152
+ stepCount: import_zod.z.number().int().nonnegative(),
153
+ startedAtMs: import_zod.z.number().int().nonnegative(),
154
+ supportsTools: import_zod.z.boolean(),
155
+ modelStepId: import_zod.z.string(),
156
+ result: ModelStepResultStateSchema,
157
+ toolCallsExecuted: import_zod.z.boolean()
158
+ }).strict(),
159
+ import_zod.z.object({
160
+ phase: import_zod.z.literal("stopped"),
161
+ stepCount: import_zod.z.number().int().nonnegative(),
162
+ startedAtMs: import_zod.z.number().int().nonnegative(),
163
+ supportsTools: import_zod.z.boolean(),
164
+ lastText: import_zod.z.string(),
165
+ lastUsage: TokenUsageStateSchema.nullable(),
166
+ lastFinishReason: LLMFinishReasonStateSchema,
167
+ finished: import_zod.z.boolean()
168
+ }).strict()
169
+ ]);
170
+ function parseTurnDriverState(input) {
171
+ return TurnDriverStateSchema.parse(input);
172
+ }
173
+ function toModelStepRequestState(request) {
174
+ return {
175
+ messages: structuredClone(request.messages),
176
+ estimatedInputTokens: request.estimatedInputTokens,
177
+ toolDefinitions: structuredClone(request.toolDefinitions),
178
+ ...request.reasoning === void 0 ? {} : { reasoning: structuredClone(request.reasoning) },
179
+ ...request.providerOptions === void 0 ? {} : { providerOptions: structuredClone(request.providerOptions) },
180
+ streaming: request.streaming
181
+ };
182
+ }
90
183
  const toolSupportCache = /* @__PURE__ */ new Map();
91
184
  const LOCAL_PROVIDERS = ["ollama", "local"];
92
185
  class TurnExecutor {
93
- constructor(model, toolManager, contextManager, eventBus, resourceManager, sessionId, config, llmContext, logger, messageQueue, modelLimits, externalSignal, compactionStrategy = null, runContext) {
186
+ constructor(model, toolManager, contextManager, eventBus, resourceManager, sessionId, config, llmContext, logger, steerQueue, followUpQueue, modelLimits, externalSignal, compactionStrategy = null, runContext) {
94
187
  this.model = model;
95
188
  this.toolManager = toolManager;
96
189
  this.contextManager = contextManager;
@@ -99,11 +192,12 @@ class TurnExecutor {
99
192
  this.sessionId = sessionId;
100
193
  this.config = config;
101
194
  this.llmContext = llmContext;
102
- this.messageQueue = messageQueue;
195
+ this.steerQueue = steerQueue;
196
+ this.followUpQueue = followUpQueue;
103
197
  this.modelLimits = modelLimits;
104
198
  this.externalSignal = externalSignal;
105
199
  this.runContext = runContext;
106
- this.logger = logger.createChild(import_types3.DextoLogComponent.EXECUTOR);
200
+ this.logger = logger.createChild(import_types.DextoLogComponent.EXECUTOR);
107
201
  this.stepAbortController = new AbortController();
108
202
  this.compactionStrategy = compactionStrategy;
109
203
  }
@@ -114,11 +208,7 @@ class TurnExecutor {
114
208
  */
115
209
  stepAbortController;
116
210
  compactionStrategy = null;
117
- /**
118
- * Map to track tool-call metadata by toolCallId.
119
- * Used to pass execution-time info (approval + presentation snapshot) to result persistence.
120
- */
121
- toolCallMetadata = /* @__PURE__ */ new Map();
211
+ currentModelStepId = "in-memory-model-step-0";
122
212
  /**
123
213
  * Get StreamProcessor config from TurnExecutor state.
124
214
  * @param estimatedInputTokens Optional estimated input tokens for analytics
@@ -147,238 +237,300 @@ class TurnExecutor {
147
237
  * @param streaming If true, emits llm:chunk events during streaming. Default true.
148
238
  */
149
239
  async execute(contributorContext, streaming = true) {
150
- var _stack = [];
240
+ const driver = await this.createDriver(contributorContext, { streaming });
151
241
  try {
152
- const _ = __using(_stack, (0, import_defer.defer)(() => this.cleanup()));
153
- const startTime = Date.now();
154
- let stepCount = 0;
155
- let lastStepTokens = null;
156
- let lastFinishReason = "unknown";
157
- let lastText = "";
158
- this.eventBus.emit("llm:thinking", {});
159
- const supportsTools = await this.validateToolSupport();
160
- if (!supportsTools) {
161
- const modelKey = `${this.llmContext.provider}:${this.llmContext.model}`;
162
- this.eventBus.emit("llm:unsupported-input", {
163
- errors: [
164
- `Model '${modelKey}' does not support tool calling.`,
165
- "You can still chat, but the model will not be able to use tools or execute commands."
166
- ],
167
- provider: this.llmContext.provider,
168
- model: this.llmContext.model,
169
- details: {
170
- feature: "tool-calling",
171
- supported: false
172
- }
173
- });
174
- this.logger.warn(
175
- `Model ${modelKey} does not support tools - continuing without tool calling`
176
- );
177
- }
178
- let currentAbortHandler = null;
242
+ let stopped = false;
179
243
  try {
180
- while (true) {
181
- if (currentAbortHandler && this.externalSignal) {
182
- this.externalSignal.removeEventListener("abort", currentAbortHandler);
183
- }
184
- this.stepAbortController = new AbortController();
185
- currentAbortHandler = () => this.stepAbortController.abort();
186
- if (this.externalSignal && !this.externalSignal.aborted) {
187
- this.externalSignal.addEventListener("abort", currentAbortHandler, {
188
- once: true
189
- });
244
+ while (!stopped) {
245
+ const modelStep = await driver.runNextModelStep();
246
+ if (modelStep.result.finishReason === "tool-calls") {
247
+ await driver.executeToolCalls();
190
248
  }
191
- const coalesced = await this.messageQueue.dequeueAll();
192
- if (coalesced) {
193
- await this.injectQueuedMessages(coalesced);
249
+ const nextStep = await driver.decideNextStep();
250
+ if (nextStep.kind === "stop") {
251
+ stopped = true;
194
252
  }
195
- await this.pruneOldToolOutputs();
196
- let prepared = await this.contextManager.getFormattedMessagesForLLM(
253
+ }
254
+ } catch (error) {
255
+ return await driver.fail(error);
256
+ }
257
+ return await driver.finish();
258
+ } finally {
259
+ driver.dispose();
260
+ }
261
+ }
262
+ async createDriver(contributorContext, options = { streaming: true }) {
263
+ const now = Date.now();
264
+ const state = options.state ?? {
265
+ phase: "ready-for-model",
266
+ stepCount: 0,
267
+ startedAtMs: now,
268
+ supportsTools: await this.validateInitialToolSupport(),
269
+ lastText: "",
270
+ lastUsage: null,
271
+ lastFinishReason: "unknown"
272
+ };
273
+ const startTime = state.startedAtMs;
274
+ let stepCount = state.stepCount;
275
+ let lastStepTokens = state.phase === "model-step-complete" ? structuredClone(state.result.usage) : structuredClone(state.lastUsage);
276
+ let lastFinishReason = state.phase === "model-step-complete" ? state.result.finishReason : state.lastFinishReason;
277
+ let lastText = state.phase === "model-step-complete" ? state.result.text : state.lastText;
278
+ let currentStepScope = null;
279
+ let currentResult = state.phase === "model-step-complete" ? structuredClone(state.result) : null;
280
+ let preparedModelRequest = state.phase === "model-step-prepared" ? await this.restorePreparedModelRequest(state.request, state.supportsTools) : null;
281
+ let currentToolCallsExecuted = state.phase === "model-step-complete" ? state.toolCallsExecuted : false;
282
+ let modelStepPreparing = false;
283
+ let modelStepRunning = false;
284
+ let toolCallsRunning = false;
285
+ let stopped = state.phase === "stopped";
286
+ let finished = state.phase === "stopped" ? state.finished : false;
287
+ let disposed = false;
288
+ const turn = { supportsTools: state.supportsTools };
289
+ if (state.phase === "model-step-prepared" || state.phase === "model-step-complete") {
290
+ this.currentModelStepId = state.modelStepId;
291
+ currentStepScope = this.startModelStepScope();
292
+ }
293
+ const closeCurrentStepScope = () => {
294
+ currentStepScope?.[Symbol.dispose]();
295
+ currentStepScope = null;
296
+ };
297
+ const getState = () => {
298
+ if (modelStepPreparing) {
299
+ throw new Error("Turn driver cannot checkpoint during model preparation");
300
+ }
301
+ if (modelStepRunning) {
302
+ throw new Error("Turn driver cannot checkpoint during a model step");
303
+ }
304
+ if (toolCallsRunning) {
305
+ throw new Error("Turn driver cannot checkpoint during tool execution");
306
+ }
307
+ if (stopped) {
308
+ return {
309
+ phase: "stopped",
310
+ stepCount,
311
+ startedAtMs: startTime,
312
+ supportsTools: turn.supportsTools,
313
+ lastText,
314
+ lastUsage: structuredClone(lastStepTokens),
315
+ lastFinishReason,
316
+ finished
317
+ };
318
+ }
319
+ if (preparedModelRequest !== null) {
320
+ return {
321
+ phase: "model-step-prepared",
322
+ stepCount,
323
+ startedAtMs: startTime,
324
+ supportsTools: turn.supportsTools,
325
+ modelStepId: this.currentModelStepId,
326
+ request: toModelStepRequestState(preparedModelRequest),
327
+ lastText,
328
+ lastUsage: structuredClone(lastStepTokens),
329
+ lastFinishReason
330
+ };
331
+ }
332
+ if (currentResult !== null) {
333
+ return {
334
+ phase: "model-step-complete",
335
+ stepCount,
336
+ startedAtMs: startTime,
337
+ supportsTools: turn.supportsTools,
338
+ modelStepId: this.currentModelStepId,
339
+ result: {
340
+ text: currentResult.text,
341
+ finishReason: currentResult.finishReason,
342
+ usage: structuredClone(currentResult.usage),
343
+ toolCalls: structuredClone(currentResult.toolCalls)
344
+ },
345
+ toolCallsExecuted: currentToolCallsExecuted
346
+ };
347
+ }
348
+ return {
349
+ phase: "ready-for-model",
350
+ stepCount,
351
+ startedAtMs: startTime,
352
+ supportsTools: turn.supportsTools,
353
+ lastText,
354
+ lastUsage: structuredClone(lastStepTokens),
355
+ lastFinishReason
356
+ };
357
+ };
358
+ const assertCanUseDriver = () => {
359
+ if (disposed) {
360
+ throw new Error("Turn driver has already been disposed");
361
+ }
362
+ if (finished) {
363
+ throw new Error("Turn driver has already finished");
364
+ }
365
+ };
366
+ return {
367
+ prepareNextModelStep: async () => {
368
+ assertCanUseDriver();
369
+ if (stopped) {
370
+ throw new Error("Turn driver has already reached a stop decision");
371
+ }
372
+ if (preparedModelRequest !== null) {
373
+ return { stepCount };
374
+ }
375
+ if (currentStepScope !== null) {
376
+ throw new Error("Previous model step has not been decided yet");
377
+ }
378
+ currentStepScope = this.startModelStepScope();
379
+ this.currentModelStepId = `in-memory-model-step-${stepCount}`;
380
+ modelStepPreparing = true;
381
+ try {
382
+ preparedModelRequest = await this.prepareNextModelRequest({
197
383
  contributorContext,
198
- this.llmContext
199
- );
200
- const toolDefinitions = supportsTools ? this.toolManager.filterToolsForSession(
201
- await this.toolManager.getAllTools(),
202
- this.sessionId
203
- ) : {};
204
- let estimatedTokens = await this.contextManager.getEstimatedNextInputTokens(
205
- prepared.systemPrompt,
206
- prepared.preparedHistory,
207
- toolDefinitions
208
- );
209
- if (this.shouldCompact(estimatedTokens)) {
210
- this.logger.debug(
211
- `Pre-check: estimated ${estimatedTokens} tokens exceeds threshold, compacting`
212
- );
213
- const didCompact = await this.compactContext(
214
- estimatedTokens,
215
- contributorContext,
216
- toolDefinitions
217
- );
218
- if (didCompact) {
219
- prepared = await this.contextManager.getFormattedMessagesForLLM(
220
- contributorContext,
221
- this.llmContext
222
- );
223
- estimatedTokens = await this.contextManager.getEstimatedNextInputTokens(
224
- prepared.systemPrompt,
225
- prepared.preparedHistory,
226
- toolDefinitions
227
- );
228
- this.logger.debug(
229
- `Post-compaction: recomputed estimate is ${estimatedTokens} tokens`
230
- );
384
+ supportsTools: turn.supportsTools,
385
+ streaming: options.streaming
386
+ });
387
+ } catch (error) {
388
+ currentStepScope[Symbol.dispose]();
389
+ currentStepScope = null;
390
+ throw error;
391
+ } finally {
392
+ modelStepPreparing = false;
393
+ }
394
+ return { stepCount };
395
+ },
396
+ runNextModelStep: async () => {
397
+ assertCanUseDriver();
398
+ if (stopped) {
399
+ throw new Error("Turn driver has already reached a stop decision");
400
+ }
401
+ if (currentResult !== null) {
402
+ throw new Error("Previous model step has not been decided yet");
403
+ }
404
+ modelStepRunning = true;
405
+ try {
406
+ if (preparedModelRequest === null) {
407
+ if (currentStepScope !== null) {
408
+ throw new Error("Previous model step has not been decided yet");
231
409
  }
410
+ currentStepScope = this.startModelStepScope();
411
+ this.currentModelStepId = `in-memory-model-step-${stepCount}`;
412
+ preparedModelRequest = await this.prepareNextModelRequest({
413
+ contributorContext,
414
+ supportsTools: turn.supportsTools,
415
+ streaming: options.streaming
416
+ });
417
+ }
418
+ const modelStepRequest = preparedModelRequest;
419
+ if (currentStepScope === null || modelStepRequest === null) {
420
+ throw new Error("Model step request was not prepared");
232
421
  }
233
422
  this.logger.debug(`Step ${stepCount}: Starting`);
234
- const tools = supportsTools ? await this.createTools() : {};
235
- const providerOptions = (0, import_provider_options.buildProviderOptions)({
236
- provider: this.llmContext.provider,
237
- model: this.llmContext.model,
238
- reasoning: this.config.reasoning
239
- });
240
- this.logger.debug("LLM request options", {
241
- provider: this.llmContext.provider,
242
- model: this.llmContext.model,
243
- requestedReasoning: {
244
- variant: this.config.reasoning?.variant,
245
- budgetTokens: this.config.reasoning?.budgetTokens
246
- },
247
- providerOptions
248
- });
249
- const reasoningVariant = this.config.reasoning?.variant;
250
- const reasoningBudgetTokens = (0, import_provider_options.getEffectiveReasoningBudgetTokens)(providerOptions);
251
- const reasoningForStream = reasoningVariant !== void 0 || reasoningBudgetTokens !== void 0 ? {
252
- ...reasoningVariant !== void 0 && { reasoningVariant },
253
- ...reasoningBudgetTokens !== void 0 && { reasoningBudgetTokens }
254
- } : void 0;
255
- const streamProcessor = new import_stream_processor.StreamProcessor(
256
- this.contextManager,
257
- this.eventBus,
258
- this.resourceManager,
259
- this.stepAbortController.signal,
260
- this.getStreamProcessorConfig(estimatedTokens, reasoningForStream),
261
- this.logger,
262
- streaming,
263
- this.toolCallMetadata
264
- );
265
- const result = await streamProcessor.process(
266
- () => (0, import_ai.streamText)({
267
- model: this.model,
268
- stopWhen: (0, import_ai.stepCountIs)(1),
269
- tools,
270
- abortSignal: this.stepAbortController.signal,
271
- messages: prepared.formattedMessages,
272
- ...this.config.maxOutputTokens !== void 0 && {
273
- maxOutputTokens: this.config.maxOutputTokens
274
- },
275
- ...this.config.temperature !== void 0 && {
276
- temperature: this.config.temperature
277
- },
278
- // Provider-specific options (caching, reasoning, etc.)
279
- ...providerOptions !== void 0 && {
280
- providerOptions
281
- },
282
- // Log stream-level errors (tool errors, API errors during streaming)
283
- onError: (error) => {
284
- this.logger.error("Stream error", { error });
285
- }
286
- })
287
- );
423
+ const result = await this.runModelStepWithRetry(modelStepRequest);
424
+ currentResult = result;
425
+ currentToolCallsExecuted = result.finishReason !== "tool-calls";
426
+ preparedModelRequest = null;
288
427
  lastStepTokens = result.usage;
289
428
  lastFinishReason = result.finishReason;
290
429
  lastText = result.text;
291
430
  this.logger.debug(
292
431
  `Step ${stepCount}: Finished with reason="${result.finishReason}", tokens=${JSON.stringify(result.usage)}`
293
432
  );
294
- if (result.finishReason === "cancelled") {
295
- this.logger.info(
296
- `Context estimation (cancelled): keeping last known actuals, partial response (${result.text.length} chars) will be estimated`
297
- );
298
- } else if (result.usage?.inputTokens !== void 0) {
299
- const contextInputTokens2 = this.getContextInputTokens(result.usage);
300
- const actualInputTokens = contextInputTokens2 ?? result.usage.inputTokens;
301
- const diff = estimatedTokens - actualInputTokens;
302
- const diffPercent = actualInputTokens > 0 ? (diff / actualInputTokens * 100).toFixed(1) : "0.0";
303
- this.logger.info(
304
- `Context estimation accuracy: estimated=${estimatedTokens}, actual=${actualInputTokens}, error=${diff} (${diffPercent}%)`
305
- );
306
- this.contextManager.setLastActualInputTokens(actualInputTokens);
307
- if (result.usage?.outputTokens !== void 0) {
308
- this.contextManager.setLastActualOutputTokens(result.usage.outputTokens);
309
- }
310
- await this.contextManager.recordLastCallMessageCount();
311
- }
312
- const contextInputTokens = result.usage ? this.getContextInputTokens(result.usage) : null;
313
- if (contextInputTokens && this.shouldCompactFromActual(contextInputTokens)) {
314
- this.logger.debug(
315
- `Post-response: actual ${contextInputTokens} tokens exceeds threshold, compacting`
316
- );
317
- await this.compactContext(
318
- contextInputTokens,
319
- contributorContext,
320
- toolDefinitions
321
- );
322
- }
323
- if (result.finishReason !== "tool-calls") {
324
- const queuedOnTerminate = await this.messageQueue.dequeueAll();
325
- if (queuedOnTerminate) {
326
- this.logger.debug(
327
- `Continuing: ${queuedOnTerminate.messages.length} queued message(s) to process`
328
- );
329
- await this.injectQueuedMessages(queuedOnTerminate);
330
- continue;
331
- }
332
- this.logger.debug(`Terminating: finishReason is "${result.finishReason}"`);
333
- break;
334
- }
335
- if (this.externalSignal?.aborted && !this.messageQueue.hasPending()) {
336
- this.logger.debug("Terminating: hard cancel - external abort signal received");
337
- lastFinishReason = "cancelled";
338
- break;
339
- }
340
- stepCount++;
341
- if (this.config.maxSteps !== void 0 && stepCount >= this.config.maxSteps) {
342
- this.logger.debug(`Terminating: reached maxSteps (${this.config.maxSteps})`);
343
- lastFinishReason = "max-steps";
344
- break;
433
+ await this.applyModelStepResult({
434
+ result,
435
+ request: modelStepRequest,
436
+ contributorContext
437
+ });
438
+ return {
439
+ result,
440
+ stepCount
441
+ };
442
+ } finally {
443
+ modelStepRunning = false;
444
+ }
445
+ },
446
+ executeToolCalls: async () => {
447
+ assertCanUseDriver();
448
+ if (currentStepScope === null) {
449
+ throw new Error("No active model step is available for tool execution");
450
+ }
451
+ const result = currentResult;
452
+ if (result === null) {
453
+ throw new Error("No model step result is available for tool execution");
454
+ }
455
+ if (currentToolCallsExecuted) {
456
+ throw new Error("Tool calls for the current model step have already run");
457
+ }
458
+ if (result.finishReason === "tool-calls") {
459
+ toolCallsRunning = true;
460
+ currentToolCallsExecuted = true;
461
+ try {
462
+ await this.executeModelToolCalls(result.toolCalls);
463
+ } catch (error) {
464
+ currentToolCallsExecuted = false;
465
+ throw error;
466
+ } finally {
467
+ toolCallsRunning = false;
345
468
  }
346
469
  }
347
- } catch (error) {
348
- const mappedError = this.mapProviderError(error);
349
- this.logger.error("TurnExecutor failed", { error: mappedError });
350
- this.eventBus.emit("llm:error", {
351
- error: mappedError,
352
- context: "TurnExecutor",
353
- recoverable: false
354
- });
355
- await this.contextManager.flush();
356
- this.eventBus.emit("run:complete", {
357
- finishReason: "error",
470
+ },
471
+ decideNextStep: async () => {
472
+ assertCanUseDriver();
473
+ if (currentStepScope === null) {
474
+ throw new Error("No active model step is available to decide");
475
+ }
476
+ const result = currentResult;
477
+ if (result === null) {
478
+ throw new Error("No model step result is available to decide");
479
+ }
480
+ if (result.finishReason === "tool-calls" && !currentToolCallsExecuted) {
481
+ throw new Error("Tool calls must finish before deciding the next model step");
482
+ }
483
+ const nextStep = await this.decideNextStep(result, stepCount);
484
+ stepCount = nextStep.stepCount;
485
+ currentResult = null;
486
+ currentToolCallsExecuted = false;
487
+ closeCurrentStepScope();
488
+ if (nextStep.kind === "stop") {
489
+ lastFinishReason = nextStep.finishReason;
490
+ stopped = true;
491
+ return {
492
+ kind: "stop",
493
+ stepCount,
494
+ finishReason: lastFinishReason
495
+ };
496
+ }
497
+ return {
498
+ kind: "continue",
499
+ stepCount
500
+ };
501
+ },
502
+ finish: async () => {
503
+ assertCanUseDriver();
504
+ if (!stopped) {
505
+ throw new Error("Turn driver cannot finish before a stop decision");
506
+ }
507
+ const result = await this.finishTurn({
508
+ startTime,
358
509
  stepCount,
359
- durationMs: Date.now() - startTime,
360
- error: mappedError
510
+ text: lastText,
511
+ usage: lastStepTokens,
512
+ finishReason: lastFinishReason
361
513
  });
362
- throw mappedError;
514
+ finished = true;
515
+ return result;
516
+ },
517
+ fail: async (error) => {
518
+ closeCurrentStepScope();
519
+ return this.failTurn(error, stepCount, startTime);
520
+ },
521
+ getState,
522
+ checkpoint: () => {
523
+ const state2 = getState();
524
+ disposed = true;
525
+ closeCurrentStepScope();
526
+ return state2;
527
+ },
528
+ dispose: () => {
529
+ disposed = true;
530
+ closeCurrentStepScope();
531
+ this.cleanup();
363
532
  }
364
- await this.contextManager.flush();
365
- this.setTelemetryAttributes(lastStepTokens);
366
- this.eventBus.emit("run:complete", {
367
- finishReason: lastFinishReason,
368
- stepCount,
369
- durationMs: Date.now() - startTime
370
- });
371
- return {
372
- text: lastText,
373
- stepCount,
374
- usage: lastStepTokens,
375
- finishReason: lastFinishReason
376
- };
377
- } catch (_2) {
378
- var _error = _2, _hasError = true;
379
- } finally {
380
- __callDispose(_stack, _error, _hasError);
381
- }
533
+ };
382
534
  }
383
535
  /**
384
536
  * Abort the current step execution.
@@ -387,6 +539,170 @@ class TurnExecutor {
387
539
  abort() {
388
540
  this.stepAbortController.abort();
389
541
  }
542
+ async validateInitialToolSupport() {
543
+ try {
544
+ return (await this.startTurn()).supportsTools;
545
+ } catch (error) {
546
+ this.cleanup();
547
+ throw error;
548
+ }
549
+ }
550
+ async startTurn() {
551
+ this.eventBus.emit("llm:thinking", {});
552
+ const supportsTools = await this.validateToolSupport();
553
+ if (!supportsTools) {
554
+ const modelKey = `${this.llmContext.provider}:${this.llmContext.model}`;
555
+ this.eventBus.emit("llm:unsupported-input", {
556
+ errors: [
557
+ `Model '${modelKey}' does not support tool calling.`,
558
+ "You can still chat, but the model will not be able to use tools or execute commands."
559
+ ],
560
+ provider: this.llmContext.provider,
561
+ model: this.llmContext.model,
562
+ details: {
563
+ feature: "tool-calling",
564
+ supported: false
565
+ }
566
+ });
567
+ this.logger.warn(
568
+ `Model ${modelKey} does not support tools - continuing without tool calling`
569
+ );
570
+ }
571
+ return { supportsTools };
572
+ }
573
+ startModelStepScope() {
574
+ this.stepAbortController = new AbortController();
575
+ const abortHandler = () => this.stepAbortController.abort();
576
+ if (this.externalSignal?.aborted) {
577
+ this.stepAbortController.abort();
578
+ } else if (this.externalSignal) {
579
+ this.externalSignal.addEventListener("abort", abortHandler, { once: true });
580
+ }
581
+ return {
582
+ [Symbol.dispose]: () => {
583
+ this.externalSignal?.removeEventListener("abort", abortHandler);
584
+ }
585
+ };
586
+ }
587
+ async finishTurn(input) {
588
+ await this.contextManager.flush();
589
+ this.setTelemetryAttributes(input.usage);
590
+ this.eventBus.emit("run:complete", {
591
+ finishReason: input.finishReason,
592
+ stepCount: input.stepCount,
593
+ durationMs: Date.now() - input.startTime
594
+ });
595
+ return {
596
+ text: input.text,
597
+ stepCount: input.stepCount,
598
+ usage: input.usage,
599
+ finishReason: input.finishReason
600
+ };
601
+ }
602
+ async failTurn(error, stepCount, startTime) {
603
+ const mappedError = this.mapProviderError(error);
604
+ this.logger.error("TurnExecutor failed", { error: mappedError });
605
+ this.eventBus.emit("llm:error", {
606
+ error: mappedError,
607
+ context: "TurnExecutor",
608
+ recoverable: false
609
+ });
610
+ await this.contextManager.flush();
611
+ this.eventBus.emit("run:complete", {
612
+ finishReason: "error",
613
+ stepCount,
614
+ durationMs: Date.now() - startTime,
615
+ error: mappedError
616
+ });
617
+ throw mappedError;
618
+ }
619
+ advanceStep(stepCount) {
620
+ const nextStepCount = stepCount + 1;
621
+ if (this.config.maxSteps !== void 0 && nextStepCount >= this.config.maxSteps) {
622
+ return {
623
+ kind: "stop",
624
+ stepCount: nextStepCount,
625
+ finishReason: "max-steps"
626
+ };
627
+ }
628
+ return {
629
+ kind: "continue",
630
+ stepCount: nextStepCount
631
+ };
632
+ }
633
+ async continueWithQueuedInput(kind, queue, stepCount, finishReason) {
634
+ const label = kind === "late-steer" ? "late steer" : "follow-up";
635
+ if (this.externalSignal?.aborted || finishReason === "cancelled") {
636
+ this.logger.debug(`Terminating: cancel received before ${label}`);
637
+ return {
638
+ kind: "stop",
639
+ stepCount,
640
+ finishReason: "cancelled"
641
+ };
642
+ }
643
+ const stepAdvance = this.advanceStep(stepCount);
644
+ if (stepAdvance.kind === "stop") {
645
+ this.logger.debug(`Terminating: reached maxSteps (${this.config.maxSteps})`);
646
+ return stepAdvance;
647
+ }
648
+ const queued = await queue.dequeueAll();
649
+ if (!queued) {
650
+ this.logger.debug(`Terminating: finishReason is "${finishReason}"`);
651
+ return {
652
+ kind: "stop",
653
+ stepCount: stepAdvance.stepCount,
654
+ finishReason
655
+ };
656
+ }
657
+ const messageName = kind === "late-steer" ? "steer" : "follow-up";
658
+ const suffix = kind === "late-steer" ? " at end of turn" : "";
659
+ this.logger.debug(
660
+ `Continuing: ${queued.messages.length} ${messageName} message(s) to process${suffix}`
661
+ );
662
+ await this.injectQueuedMessages(queued);
663
+ return {
664
+ kind: "continue",
665
+ stepCount: stepAdvance.stepCount
666
+ };
667
+ }
668
+ async decideNextStep(result, stepCount) {
669
+ if (result.finishReason === "tool-calls") {
670
+ await this.steerQueue.refresh();
671
+ if (this.externalSignal?.aborted && !this.steerQueue.hasPending()) {
672
+ this.logger.debug("Terminating: hard cancel - external abort signal received");
673
+ return {
674
+ kind: "stop",
675
+ stepCount,
676
+ finishReason: "cancelled"
677
+ };
678
+ }
679
+ return this.advanceStep(stepCount);
680
+ }
681
+ await this.steerQueue.refresh();
682
+ if (this.steerQueue.hasPending()) {
683
+ return this.continueWithQueuedInput(
684
+ "late-steer",
685
+ this.steerQueue,
686
+ stepCount,
687
+ result.finishReason
688
+ );
689
+ }
690
+ await this.followUpQueue.refresh();
691
+ if (this.followUpQueue.hasPending()) {
692
+ return this.continueWithQueuedInput(
693
+ "follow-up",
694
+ this.followUpQueue,
695
+ stepCount,
696
+ result.finishReason
697
+ );
698
+ }
699
+ this.logger.debug(`Terminating: finishReason is "${result.finishReason}"`);
700
+ return {
701
+ kind: "stop",
702
+ stepCount,
703
+ finishReason: result.finishReason
704
+ };
705
+ }
390
706
  /**
391
707
  * Inject coalesced queued messages into the context as a single user message.
392
708
  * This enables mid-task user guidance.
@@ -480,210 +796,526 @@ class TurnExecutor {
480
796
  return true;
481
797
  }
482
798
  }
483
- /**
484
- * Creates tools with execute callbacks and toModelOutput.
485
- *
486
- * Key design decisions:
487
- * - execute() returns raw result with inline images (async)
488
- * - toModelOutput() formats for LLM consumption (sync)
489
- * - StreamProcessor handles persistence via tool-result events
490
- */
491
- async createTools() {
492
- const tools = this.toolManager.filterToolsForSession(
799
+ async prepareNextModelRequest(input) {
800
+ const coalesced = await this.steerQueue.dequeueAll();
801
+ if (coalesced) {
802
+ await this.injectQueuedMessages(coalesced);
803
+ }
804
+ await this.pruneOldToolOutputs();
805
+ let prepared = await this.contextManager.getFormattedMessagesForLLM(
806
+ input.contributorContext,
807
+ this.llmContext
808
+ );
809
+ const toolDefinitions = input.supportsTools ? this.toolManager.filterToolsForSession(
493
810
  await this.toolManager.getAllTools(),
494
811
  this.sessionId
812
+ ) : {};
813
+ let estimatedInputTokens = await this.contextManager.getEstimatedNextInputTokens(
814
+ prepared.systemPrompt,
815
+ prepared.preparedHistory,
816
+ toolDefinitions
495
817
  );
496
- return Object.fromEntries(
497
- Object.entries(tools).map(([name, tool]) => [
498
- name,
499
- {
500
- inputSchema: (0, import_ai.jsonSchema)(tool.parameters),
501
- ...tool.description && { description: tool.description },
502
- /**
503
- * Execute callback - runs the tool and returns raw result.
504
- * Does NOT persist - StreamProcessor handles that on tool-result event.
505
- *
506
- * Uses Promise.race to ensure we return quickly on abort, even if the
507
- * underlying tool (especially MCP tools we don't control) keeps running.
508
- */
509
- execute: async (args, options) => {
510
- this.logger.debug(
511
- `Executing tool: ${name} (toolCallId: ${options.toolCallId})`
512
- );
513
- const abortSignal = this.stepAbortController.signal;
514
- if (abortSignal.aborted) {
515
- this.logger.debug(`Tool ${name} cancelled before execution`);
516
- return { error: "Cancelled by user", cancelled: true };
517
- }
518
- let abortHandler = null;
519
- const abortPromise = new Promise(
520
- (resolve) => {
521
- abortHandler = () => {
522
- this.logger.debug(`Tool ${name} cancelled during execution`);
523
- resolve({ error: "Cancelled by user", cancelled: true });
524
- };
525
- abortSignal.addEventListener("abort", abortHandler, { once: true });
526
- }
527
- );
528
- try {
529
- const result = await Promise.race([
530
- (async () => {
531
- const executionResult = await this.toolManager.executeTool(
532
- name,
533
- args,
534
- options.toolCallId,
535
- {
536
- sessionId: this.sessionId,
537
- abortSignal,
538
- ...this.runContext !== void 0 ? { runContext: this.runContext } : {}
539
- }
540
- );
541
- const metadata = (() => {
542
- const meta = {};
543
- if (executionResult.presentationSnapshot !== void 0) {
544
- meta.presentationSnapshot = executionResult.presentationSnapshot;
545
- }
546
- if (executionResult.meta !== void 0) {
547
- meta.meta = executionResult.meta;
548
- }
549
- if (executionResult.requireApproval !== void 0) {
550
- meta.requireApproval = executionResult.requireApproval;
551
- if (executionResult.approvalStatus !== void 0) {
552
- meta.approvalStatus = executionResult.approvalStatus;
553
- }
554
- }
555
- return Object.keys(meta).length > 0 ? meta : void 0;
556
- })();
557
- if (metadata) {
558
- this.toolCallMetadata.set(options.toolCallId, metadata);
559
- }
560
- return executionResult.result;
561
- })(),
562
- abortPromise
563
- ]);
564
- return result;
565
- } finally {
566
- if (abortHandler) {
567
- abortSignal.removeEventListener("abort", abortHandler);
568
- }
569
- }
570
- },
571
- /**
572
- * toModelOutput - formats raw result for LLM consumption.
573
- * Called by Vercel SDK when preparing messages for next LLM call.
574
- * SYNC - images are already inline in the raw result.
575
- */
576
- toModelOutput: (result) => {
577
- return this.formatToolResultForLLM(result, name);
578
- }
818
+ if (this.shouldCompact(estimatedInputTokens)) {
819
+ this.logger.debug(
820
+ `Pre-check: estimated ${estimatedInputTokens} tokens exceeds threshold, compacting`
821
+ );
822
+ const didCompact = await this.compactContext(
823
+ estimatedInputTokens,
824
+ input.contributorContext,
825
+ toolDefinitions
826
+ );
827
+ if (didCompact) {
828
+ prepared = await this.contextManager.getFormattedMessagesForLLM(
829
+ input.contributorContext,
830
+ this.llmContext
831
+ );
832
+ estimatedInputTokens = await this.contextManager.getEstimatedNextInputTokens(
833
+ prepared.systemPrompt,
834
+ prepared.preparedHistory,
835
+ toolDefinitions
836
+ );
837
+ this.logger.debug(
838
+ `Post-compaction: recomputed estimate is ${estimatedInputTokens} tokens`
839
+ );
840
+ }
841
+ }
842
+ const providerOptions = (0, import_provider_options.buildProviderOptions)({
843
+ provider: this.llmContext.provider,
844
+ model: this.llmContext.model,
845
+ reasoning: this.config.reasoning
846
+ });
847
+ this.logger.debug("LLM request options", {
848
+ provider: this.llmContext.provider,
849
+ model: this.llmContext.model,
850
+ requestedReasoning: {
851
+ variant: this.config.reasoning?.variant,
852
+ budgetTokens: this.config.reasoning?.budgetTokens
853
+ },
854
+ providerOptions
855
+ });
856
+ const reasoningVariant = this.config.reasoning?.variant;
857
+ const reasoningBudgetTokens = (0, import_provider_options.getEffectiveReasoningBudgetTokens)(providerOptions);
858
+ const reasoning = reasoningVariant !== void 0 || reasoningBudgetTokens !== void 0 ? {
859
+ ...reasoningVariant !== void 0 && { reasoningVariant },
860
+ ...reasoningBudgetTokens !== void 0 && { reasoningBudgetTokens }
861
+ } : void 0;
862
+ return {
863
+ messages: prepared.formattedMessages,
864
+ tools: input.supportsTools ? (0, import_tool_definitions.createModelToolDefinitions)(toolDefinitions) : {},
865
+ toolDefinitions,
866
+ estimatedInputTokens,
867
+ reasoning,
868
+ providerOptions,
869
+ streaming: input.streaming
870
+ };
871
+ }
872
+ async restorePreparedModelRequest(state, supportsTools) {
873
+ const toolDefinitions = supportsTools ? structuredClone(state.toolDefinitions) : {};
874
+ return {
875
+ messages: structuredClone(state.messages),
876
+ tools: supportsTools ? (0, import_tool_definitions.createModelToolDefinitions)(toolDefinitions) : {},
877
+ toolDefinitions,
878
+ estimatedInputTokens: state.estimatedInputTokens,
879
+ reasoning: state.reasoning === void 0 ? void 0 : {
880
+ ...state.reasoning.reasoningVariant === void 0 ? {} : { reasoningVariant: state.reasoning.reasoningVariant },
881
+ ...state.reasoning.reasoningBudgetTokens === void 0 ? {} : { reasoningBudgetTokens: state.reasoning.reasoningBudgetTokens }
882
+ },
883
+ providerOptions: state.providerOptions,
884
+ streaming: state.streaming
885
+ };
886
+ }
887
+ async runModelStep(request) {
888
+ const streamProcessor = new import_stream_processor.StreamProcessor(
889
+ this.contextManager,
890
+ this.eventBus,
891
+ this.stepAbortController.signal,
892
+ this.getStreamProcessorConfig(request.estimatedInputTokens, request.reasoning),
893
+ this.logger,
894
+ request.streaming
895
+ );
896
+ return streamProcessor.process(
897
+ () => (0, import_ai.streamText)({
898
+ model: this.model,
899
+ stopWhen: (0, import_ai.stepCountIs)(1),
900
+ maxRetries: 0,
901
+ tools: request.tools,
902
+ abortSignal: this.stepAbortController.signal,
903
+ messages: request.messages,
904
+ ...this.config.maxOutputTokens !== void 0 && {
905
+ maxOutputTokens: this.config.maxOutputTokens
906
+ },
907
+ ...this.config.temperature !== void 0 && {
908
+ temperature: this.config.temperature
909
+ },
910
+ // Provider-specific options (caching, reasoning, etc.)
911
+ ...request.providerOptions !== void 0 && {
912
+ providerOptions: request.providerOptions
913
+ },
914
+ // Log stream-level errors (tool errors, API errors during streaming)
915
+ onError: (error) => {
916
+ this.logger.error("Stream error", { error });
579
917
  }
580
- ])
918
+ })
581
919
  );
582
920
  }
583
- /**
584
- * Format tool result for LLM consumption.
585
- * Handles multimodal content (text + images).
586
- *
587
- * This handles RAW tool results - the structure may vary.
588
- */
589
- formatToolResultForLLM(result, toolName) {
590
- if (result && typeof result === "object" && "error" in result) {
591
- const errorResult = result;
592
- let errorFlags = "";
593
- if (errorResult.denied) errorFlags += " (denied)";
594
- if (errorResult.timeout) errorFlags += " (timeout)";
921
+ async runModelStepWithRetry(request) {
922
+ for (let failedAttempts = 0; ; failedAttempts += 1) {
923
+ const historyLengthBefore = (await this.contextManager.getHistory()).length;
924
+ try {
925
+ return await this.runModelStep(request);
926
+ } catch (error) {
927
+ const historyLengthAfter = (await this.contextManager.getHistory()).length;
928
+ const historyLengthChanged = historyLengthAfter !== historyLengthBefore;
929
+ if (!this.canRetryModelRequest(error, historyLengthChanged) || failedAttempts >= MODEL_REQUEST_MAX_RETRIES) {
930
+ throw error;
931
+ }
932
+ const mappedError = this.mapProviderError(error);
933
+ this.eventBus.emit("llm:retrying", {
934
+ error: mappedError,
935
+ context: "TurnExecutor.runModelStep",
936
+ attempt: failedAttempts + 1,
937
+ maxRetries: MODEL_REQUEST_MAX_RETRIES,
938
+ provider: this.llmContext.provider,
939
+ model: this.llmContext.model
940
+ });
941
+ this.logger.warn("Retrying model request after transient failure", {
942
+ attempt: failedAttempts + 1,
943
+ maxRetries: MODEL_REQUEST_MAX_RETRIES,
944
+ error: mappedError
945
+ });
946
+ }
947
+ }
948
+ }
949
+ canRetryModelRequest(error, historyLengthChanged) {
950
+ if (historyLengthChanged) return false;
951
+ if (this.stepAbortController.signal.aborted) return false;
952
+ if (!import_ai.APICallError.isInstance?.(error)) return false;
953
+ return error.isRetryable;
954
+ }
955
+ async applyModelStepResult(input) {
956
+ const { result, request, contributorContext } = input;
957
+ if (result.finishReason === "cancelled") {
958
+ this.logger.info(
959
+ `Context estimation (cancelled): keeping last known actuals, partial response (${result.text.length} chars) will be estimated`
960
+ );
961
+ return;
962
+ }
963
+ const contextInputTokens = this.getContextInputTokens(result.usage);
964
+ if (result.usage.inputTokens !== void 0) {
965
+ const actualInputTokens = contextInputTokens ?? result.usage.inputTokens;
966
+ const diff = request.estimatedInputTokens - actualInputTokens;
967
+ const diffPercent = actualInputTokens > 0 ? (diff / actualInputTokens * 100).toFixed(1) : "0.0";
968
+ this.logger.info(
969
+ `Context estimation accuracy: estimated=${request.estimatedInputTokens}, actual=${actualInputTokens}, error=${diff} (${diffPercent}%)`
970
+ );
971
+ this.contextManager.setLastActualInputTokens(actualInputTokens);
972
+ if (result.usage.outputTokens !== void 0) {
973
+ this.contextManager.setLastActualOutputTokens(result.usage.outputTokens);
974
+ }
975
+ await this.contextManager.recordLastCallMessageCount();
976
+ }
977
+ if (result.finishReason !== "tool-calls" && contextInputTokens && this.shouldCompactFromActual(contextInputTokens)) {
978
+ this.logger.debug(
979
+ `Post-response: actual ${contextInputTokens} tokens exceeds threshold, compacting`
980
+ );
981
+ await this.compactContext(
982
+ contextInputTokens,
983
+ contributorContext,
984
+ request.toolDefinitions
985
+ );
986
+ }
987
+ }
988
+ async executeModelToolCalls(toolCalls) {
989
+ const preparedCalls = [];
990
+ for (const toolCall of toolCalls) {
991
+ preparedCalls.push(await this.prepareModelToolCall(toolCall));
992
+ }
993
+ const executionResults = await Promise.all(
994
+ preparedCalls.map((prepared) => this.executePreparedModelToolCall(prepared))
995
+ );
996
+ for (let index = 0; index < toolCalls.length; index += 1) {
997
+ const toolCall = toolCalls[index];
998
+ const executionResult = executionResults[index];
999
+ if (toolCall === void 0 || executionResult === void 0) {
1000
+ throw new Error("Tool call result count must match emitted tool call count");
1001
+ }
1002
+ await this.persistModelToolResult(toolCall, executionResult);
1003
+ }
1004
+ }
1005
+ async prepareModelToolCall(toolCall) {
1006
+ if (this.stepAbortController.signal.aborted) {
595
1007
  return {
596
- type: "text",
597
- value: `Tool ${toolName} failed${errorFlags}: ${errorResult.error}`
1008
+ kind: "terminal",
1009
+ toolCall,
1010
+ modelVisibleResult: this.cancelledToolResult(
1011
+ this.buildToolCallFallbackSnapshot(toolCall.toolName)
1012
+ )
598
1013
  };
599
1014
  }
600
- if (this.hasMultimodalContent(result)) {
601
- const contentArray = result.content;
602
- const contentValue = [];
603
- for (const part of contentArray) {
604
- if (part.type === "text" && typeof part.text === "string") {
605
- contentValue.push({ type: "text", text: part.text });
606
- } else if (part.type === "image") {
607
- const imageData = this.extractImageData(part);
608
- if (imageData) {
609
- contentValue.push({
610
- type: "media",
611
- data: imageData,
612
- mediaType: part.mimeType || "image/jpeg"
613
- });
614
- }
615
- } else if (part.type === "file") {
616
- const fileData = this.extractFileData(part);
617
- if (fileData) {
618
- contentValue.push({
619
- type: "media",
620
- data: fileData,
621
- mediaType: part.mimeType || "application/octet-stream"
622
- });
623
- }
624
- }
1015
+ let prepared;
1016
+ try {
1017
+ prepared = await this.toolManager.prepareToolCall({
1018
+ toolName: toolCall.toolName,
1019
+ input: toolCall.input,
1020
+ toolCallId: toolCall.toolCallId,
1021
+ sessionId: this.sessionId,
1022
+ ...this.runContext !== void 0 ? { runContext: this.runContext } : {}
1023
+ });
1024
+ } catch (error) {
1025
+ const modelVisibleResult = this.failedToolResult(
1026
+ toolCall.toolName,
1027
+ error,
1028
+ this.buildToolCallFallbackSnapshot(toolCall.toolName)
1029
+ );
1030
+ this.emitFallbackToolCall(toolCall, modelVisibleResult);
1031
+ return {
1032
+ kind: "terminal",
1033
+ toolCall,
1034
+ modelVisibleResult
1035
+ };
1036
+ }
1037
+ if (prepared.kind === "terminal") {
1038
+ if ("call" in prepared) {
1039
+ this.emitToolCall(toolCall, prepared.call);
1040
+ } else {
1041
+ this.emitFallbackToolCall(toolCall, prepared.modelVisibleResult);
1042
+ }
1043
+ } else {
1044
+ this.emitToolCall(toolCall, prepared.call);
1045
+ }
1046
+ return { kind: "prepared", toolCall, prepared };
1047
+ }
1048
+ async executePreparedModelToolCall(preparedCall) {
1049
+ try {
1050
+ if (preparedCall.kind === "terminal") {
1051
+ return preparedCall.modelVisibleResult;
625
1052
  }
626
- if (contentValue.length > 0 && contentValue.some((v) => v.type === "media")) {
627
- return { type: "content", value: contentValue };
1053
+ const { prepared } = preparedCall;
1054
+ if (prepared.kind === "terminal") {
1055
+ return prepared.modelVisibleResult;
1056
+ }
1057
+ if (prepared.kind === "ready") {
1058
+ return this.executePreparedToolCallWithAbort(
1059
+ prepared.call,
1060
+ this.resolveModelToolExecutionIdentity(preparedCall.toolCall.toolCallId)
1061
+ );
1062
+ }
1063
+ const identity = this.resolveToolApprovalIdentity();
1064
+ const recorded = await this.toolManager.recordApprovalRequest(prepared, identity);
1065
+ const approval = await this.requestApprovalDecisionWithAbort(recorded);
1066
+ if (approval.kind === "terminal") {
1067
+ return approval.modelVisibleResult;
1068
+ }
1069
+ const decision = this.toApprovalDecisionInput(approval.response);
1070
+ const applied = await this.toolManager.applyApprovalDecision(
1071
+ recorded,
1072
+ decision,
1073
+ this.runContext
1074
+ );
1075
+ if (applied.kind === "terminal") {
1076
+ return applied.modelVisibleResult;
628
1077
  }
629
- const textParts = contentArray.filter((p) => p.type === "text" && typeof p.text === "string").map((p) => p.text);
1078
+ return this.executePreparedToolCallWithAbort(
1079
+ applied.call,
1080
+ this.resolveModelToolExecutionIdentity(preparedCall.toolCall.toolCallId)
1081
+ );
1082
+ } catch (error) {
1083
+ return this.failedToolResult(
1084
+ preparedCall.toolCall.toolName,
1085
+ error,
1086
+ this.getPreparedToolCallSnapshot(preparedCall)
1087
+ );
1088
+ }
1089
+ }
1090
+ emitFallbackToolCall(toolCall, executionResult) {
1091
+ this.emitToolCall(toolCall, {
1092
+ input: this.getToolCallInputForEvent(toolCall.input),
1093
+ presentationSnapshot: executionResult.presentationSnapshot ?? this.buildToolCallFallbackSnapshot(toolCall.toolName),
1094
+ toolName: toolCall.toolName
1095
+ });
1096
+ }
1097
+ async executePreparedToolCallWithAbort(call, executionIdentity) {
1098
+ const abortSignal = this.stepAbortController.signal;
1099
+ let abortHandler = null;
1100
+ const abortPromise = new Promise((resolve) => {
1101
+ abortHandler = () => {
1102
+ this.logger.debug(`Tool ${call.toolName} cancelled during execution`);
1103
+ resolve(this.cancelledToolResult(call.presentationSnapshot, call));
1104
+ };
1105
+ abortSignal.addEventListener("abort", abortHandler, { once: true });
1106
+ });
1107
+ try {
1108
+ return await Promise.race([
1109
+ this.toolManager.executePreparedToolCall(call, {
1110
+ sessionId: this.sessionId,
1111
+ abortSignal,
1112
+ executionIdentity,
1113
+ ...this.runContext !== void 0 ? { runContext: this.runContext } : {}
1114
+ }),
1115
+ abortPromise
1116
+ ]);
1117
+ } finally {
1118
+ if (abortHandler) {
1119
+ abortSignal.removeEventListener("abort", abortHandler);
1120
+ }
1121
+ }
1122
+ }
1123
+ async requestApprovalDecisionWithAbort(recorded) {
1124
+ const abortSignal = this.stepAbortController.signal;
1125
+ if (abortSignal.aborted) {
630
1126
  return {
631
- type: "text",
632
- value: textParts.join("\n") || "[empty result]"
1127
+ kind: "terminal",
1128
+ modelVisibleResult: this.cancelledToolResult(
1129
+ recorded.prepared.call.presentationSnapshot,
1130
+ recorded.prepared.call
1131
+ )
633
1132
  };
634
1133
  }
635
- if (typeof result === "string") {
636
- return { type: "text", value: result };
1134
+ let abortHandler = null;
1135
+ const abortPromise = new Promise((resolve) => {
1136
+ abortHandler = () => {
1137
+ this.logger.debug(
1138
+ `Tool ${recorded.prepared.call.toolName} approval cancelled before execution`
1139
+ );
1140
+ resolve({
1141
+ kind: "terminal",
1142
+ modelVisibleResult: this.cancelledToolResult(
1143
+ recorded.prepared.call.presentationSnapshot,
1144
+ recorded.prepared.call
1145
+ )
1146
+ });
1147
+ };
1148
+ abortSignal.addEventListener("abort", abortHandler, { once: true });
1149
+ });
1150
+ try {
1151
+ return await Promise.race([
1152
+ this.toolManager.requestApprovalDecision(recorded).then((response) => ({ kind: "response", response })),
1153
+ abortPromise
1154
+ ]);
1155
+ } finally {
1156
+ if (abortHandler) {
1157
+ abortSignal.removeEventListener("abort", abortHandler);
1158
+ }
637
1159
  }
1160
+ }
1161
+ cancelledToolResult(presentationSnapshot, call) {
638
1162
  return {
639
- type: "text",
640
- value: typeof result === "object" && result !== null ? JSON.stringify(result) : String(result)
1163
+ result: { error: "Cancelled by user", cancelled: true },
1164
+ presentationSnapshot,
1165
+ ...call?.meta !== void 0 ? { meta: call.meta } : {},
1166
+ ...call?.approval !== void 0 ? call.approval : {}
641
1167
  };
642
1168
  }
643
- /**
644
- * Extract image data from a part, handling various formats.
645
- */
646
- extractImageData(part) {
647
- if (typeof part.image === "string") {
648
- return part.image;
649
- }
650
- if (typeof part.data === "string") {
651
- return part.data;
1169
+ failedToolResult(toolName, error, presentationSnapshot) {
1170
+ const message = (0, import_error_conversion.toError)(error, this.logger).message;
1171
+ this.logger.error(`Tool ${toolName} failed before execution result was produced`, {
1172
+ error: message
1173
+ });
1174
+ return {
1175
+ result: { error: message },
1176
+ presentationSnapshot
1177
+ };
1178
+ }
1179
+ getPreparedToolCallSnapshot(preparedCall) {
1180
+ if (preparedCall.kind === "terminal") {
1181
+ return preparedCall.modelVisibleResult.presentationSnapshot ?? this.buildToolCallFallbackSnapshot(preparedCall.toolCall.toolName);
652
1182
  }
653
- if (part.image instanceof Buffer) {
654
- return part.image.toString("base64");
1183
+ if ("call" in preparedCall.prepared) {
1184
+ return preparedCall.prepared.call.presentationSnapshot;
655
1185
  }
656
- if (part.data instanceof Buffer) {
657
- return part.data.toString("base64");
1186
+ return preparedCall.prepared.modelVisibleResult.presentationSnapshot ?? this.buildToolCallFallbackSnapshot(preparedCall.toolCall.toolName);
1187
+ }
1188
+ async persistModelToolResult(toolCall, executionResult) {
1189
+ const success = this.isToolExecutionSuccessful(executionResult);
1190
+ const sanitized = await (0, import_utils.sanitizeToolResult)(
1191
+ executionResult.result,
1192
+ {
1193
+ artifactStore: this.resourceManager.getArtifactStore(),
1194
+ toolName: toolCall.toolName,
1195
+ toolCallId: toolCall.toolCallId,
1196
+ success
1197
+ },
1198
+ this.logger
1199
+ );
1200
+ const truncated = (0, import_tool_output_truncator.truncateToolResult)(sanitized);
1201
+ const metadata = this.getToolExecutionMetadata(executionResult);
1202
+ const errorMessage = this.getToolExecutionErrorMessage(executionResult.result);
1203
+ await this.contextManager.addToolResult(
1204
+ toolCall.toolCallId,
1205
+ toolCall.toolName,
1206
+ truncated,
1207
+ metadata
1208
+ );
1209
+ this.eventBus.emit("llm:tool-result", {
1210
+ toolName: toolCall.toolName,
1211
+ ...metadata?.presentationSnapshot !== void 0 && {
1212
+ presentationSnapshot: metadata.presentationSnapshot
1213
+ },
1214
+ ...metadata?.meta !== void 0 && {
1215
+ meta: metadata.meta
1216
+ },
1217
+ callId: toolCall.toolCallId,
1218
+ success,
1219
+ sanitized: truncated,
1220
+ rawResult: executionResult.result,
1221
+ ...!success && errorMessage !== null ? { error: errorMessage } : {},
1222
+ ...metadata?.requireApproval !== void 0 && {
1223
+ requireApproval: metadata.requireApproval
1224
+ },
1225
+ ...metadata?.approvalStatus !== void 0 && {
1226
+ approvalStatus: metadata.approvalStatus
1227
+ }
1228
+ });
1229
+ }
1230
+ emitToolCall(toolCall, call) {
1231
+ this.eventBus.emit("llm:tool-call", {
1232
+ toolName: toolCall.toolName,
1233
+ ...call.presentationSnapshot !== void 0 && {
1234
+ presentationSnapshot: call.presentationSnapshot
1235
+ },
1236
+ args: call.input,
1237
+ ...call.meta !== void 0 ? { meta: call.meta } : {},
1238
+ ...call.callDescription !== void 0 && { callDescription: call.callDescription },
1239
+ callId: toolCall.toolCallId,
1240
+ ...this.runContext?.hostRuntime !== void 0 && {
1241
+ hostRuntime: this.runContext.hostRuntime
1242
+ }
1243
+ });
1244
+ }
1245
+ resolveToolApprovalIdentity() {
1246
+ const ids = this.runContext?.hostRuntime?.ids;
1247
+ return {
1248
+ runId: ids?.runId ?? this.sessionId,
1249
+ turnId: ids?.turnId ?? "in-memory-turn",
1250
+ modelStepId: ids?.modelStepId ?? this.currentModelStepId
1251
+ };
1252
+ }
1253
+ resolveModelToolExecutionIdentity(toolCallId) {
1254
+ const ids = this.runContext?.hostRuntime?.ids;
1255
+ return {
1256
+ runId: ids?.runId ?? this.sessionId,
1257
+ turnId: ids?.turnId ?? "in-memory-turn",
1258
+ modelStepId: ids?.modelStepId ?? this.currentModelStepId,
1259
+ toolCallId
1260
+ };
1261
+ }
1262
+ toApprovalDecisionInput(response) {
1263
+ if (response.status === import_types4.ApprovalStatus.APPROVED) {
1264
+ return {
1265
+ approvalId: response.approvalId,
1266
+ status: import_types4.ApprovalStatus.APPROVED,
1267
+ ...response.data !== void 0 ? { data: response.data } : {}
1268
+ };
658
1269
  }
659
- if (part.image instanceof ArrayBuffer) {
660
- return Buffer.from(new Uint8Array(part.image)).toString("base64");
1270
+ const status = response.status === import_types4.ApprovalStatus.DENIED ? import_types4.ApprovalStatus.DENIED : import_types4.ApprovalStatus.CANCELLED;
1271
+ return {
1272
+ approvalId: response.approvalId,
1273
+ status,
1274
+ ...response.reason !== void 0 ? { reason: response.reason } : {},
1275
+ ...response.message !== void 0 ? { message: response.message } : {},
1276
+ ...response.timeoutMs !== void 0 ? { timeoutMs: response.timeoutMs } : {},
1277
+ ...response.data !== void 0 ? { data: response.data } : {}
1278
+ };
1279
+ }
1280
+ getToolExecutionMetadata(executionResult) {
1281
+ const metadata = {};
1282
+ if (executionResult.presentationSnapshot !== void 0) {
1283
+ metadata.presentationSnapshot = executionResult.presentationSnapshot;
661
1284
  }
662
- if (part.data instanceof ArrayBuffer) {
663
- return Buffer.from(new Uint8Array(part.data)).toString("base64");
1285
+ if (executionResult.meta !== void 0) {
1286
+ metadata.meta = executionResult.meta;
664
1287
  }
665
- return null;
666
- }
667
- /**
668
- * Extract file data from a part.
669
- */
670
- extractFileData(part) {
671
- if (typeof part.data === "string") {
672
- return part.data;
1288
+ if (executionResult.requireApproval !== void 0) {
1289
+ metadata.requireApproval = executionResult.requireApproval;
673
1290
  }
674
- if (part.data instanceof Buffer) {
675
- return part.data.toString("base64");
1291
+ if (executionResult.approvalStatus !== void 0) {
1292
+ metadata.approvalStatus = executionResult.approvalStatus;
676
1293
  }
677
- if (part.data instanceof ArrayBuffer) {
678
- return Buffer.from(new Uint8Array(part.data)).toString("base64");
1294
+ return Object.keys(metadata).length > 0 ? metadata : void 0;
1295
+ }
1296
+ isToolExecutionSuccessful(executionResult) {
1297
+ return !this.getToolExecutionErrorMessage(executionResult.result);
1298
+ }
1299
+ getToolExecutionErrorMessage(result) {
1300
+ if (result && typeof result === "object" && "error" in result) {
1301
+ const error = result.error;
1302
+ return typeof error === "string" ? error : String(error);
679
1303
  }
680
1304
  return null;
681
1305
  }
682
- /**
683
- * Check if result has multimodal content array
684
- */
685
- hasMultimodalContent(result) {
686
- return result !== null && typeof result === "object" && "content" in result && Array.isArray(result.content);
1306
+ getToolCallInputForEvent(input) {
1307
+ return input !== null && typeof input === "object" && !Array.isArray(input) ? input : {};
1308
+ }
1309
+ buildToolCallFallbackSnapshot(toolName) {
1310
+ return {
1311
+ version: 1,
1312
+ source: {
1313
+ type: toolName.startsWith(MCP_TOOL_PREFIX) ? "mcp" : "local"
1314
+ },
1315
+ header: {
1316
+ title: toolName.replace(/[_-]+/g, " ")
1317
+ }
1318
+ };
687
1319
  }
688
1320
  /**
689
1321
  * Constants for pruning thresholds
@@ -754,16 +1386,16 @@ class TurnExecutor {
754
1386
  }
755
1387
  /**
756
1388
  * Cleanup resources when execution scope exits.
757
- * Called automatically via defer() on normal exit, throw, or abort.
1389
+ * Called automatically by the turn driver on normal exit, throw, or abort.
758
1390
  */
759
1391
  cleanup() {
760
1392
  this.logger.debug("TurnExecutor cleanup triggered");
761
1393
  if (!this.stepAbortController.signal.aborted) {
762
1394
  this.stepAbortController.abort();
763
1395
  }
764
- void this.messageQueue.clear().catch((error) => {
1396
+ void this.steerQueue.clear().catch((error) => {
765
1397
  this.logger.warn(
766
- `Failed to clear queued follow-up messages during cleanup: ${error instanceof Error ? error.message : String(error)}`
1398
+ `Failed to clear queued steer messages during cleanup: ${error instanceof Error ? error.message : String(error)}`
767
1399
  );
768
1400
  });
769
1401
  }
@@ -914,8 +1546,8 @@ class TurnExecutor {
914
1546
  }
915
1547
  return new import_DextoRuntimeError.DextoRuntimeError(
916
1548
  import_error_codes.LLMErrorCode.INSUFFICIENT_CREDITS,
917
- import_types5.ErrorScope.LLM,
918
- import_types5.ErrorType.PAYMENT_REQUIRED,
1549
+ import_types3.ErrorScope.LLM,
1550
+ import_types3.ErrorType.PAYMENT_REQUIRED,
919
1551
  `Insufficient Dexto credits${balance !== void 0 ? `. Balance: $${balance.toFixed(2)}` : ""}`,
920
1552
  {
921
1553
  sessionId: this.sessionId,
@@ -931,8 +1563,8 @@ class TurnExecutor {
931
1563
  if (status === 429) {
932
1564
  return new import_DextoRuntimeError.DextoRuntimeError(
933
1565
  import_error_codes.LLMErrorCode.RATE_LIMIT_EXCEEDED,
934
- import_types5.ErrorScope.LLM,
935
- import_types5.ErrorType.RATE_LIMIT,
1566
+ import_types3.ErrorScope.LLM,
1567
+ import_types3.ErrorType.RATE_LIMIT,
936
1568
  `Rate limit exceeded${body ? ` - ${body}` : ""}`,
937
1569
  {
938
1570
  sessionId: this.sessionId,
@@ -947,8 +1579,8 @@ class TurnExecutor {
947
1579
  if (status === 408) {
948
1580
  return new import_DextoRuntimeError.DextoRuntimeError(
949
1581
  import_error_codes.LLMErrorCode.GENERATION_FAILED,
950
- import_types5.ErrorScope.LLM,
951
- import_types5.ErrorType.TIMEOUT,
1582
+ import_types3.ErrorScope.LLM,
1583
+ import_types3.ErrorType.TIMEOUT,
952
1584
  `Provider timed out${body ? ` - ${body}` : ""}`,
953
1585
  {
954
1586
  sessionId: this.sessionId,
@@ -961,8 +1593,8 @@ class TurnExecutor {
961
1593
  }
962
1594
  return new import_DextoRuntimeError.DextoRuntimeError(
963
1595
  import_error_codes.LLMErrorCode.GENERATION_FAILED,
964
- import_types5.ErrorScope.LLM,
965
- import_types5.ErrorType.THIRD_PARTY,
1596
+ import_types3.ErrorScope.LLM,
1597
+ import_types3.ErrorType.THIRD_PARTY,
966
1598
  `Provider error ${status}${body ? ` - ${body}` : ""}`,
967
1599
  {
968
1600
  sessionId: this.sessionId,
@@ -978,5 +1610,8 @@ class TurnExecutor {
978
1610
  }
979
1611
  // Annotate the CommonJS export names for ESM import in node:
980
1612
  0 && (module.exports = {
981
- TurnExecutor
1613
+ ModelStepResultStateSchema,
1614
+ TurnDriverStateSchema,
1615
+ TurnExecutor,
1616
+ parseTurnDriverState
982
1617
  });