@qduc/term2 0.1.8 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (618) hide show
  1. package/dist/agent.d.ts.map +1 -1
  2. package/dist/agent.js +5 -3
  3. package/dist/agent.js.map +1 -1
  4. package/dist/app.d.ts +1 -5
  5. package/dist/app.d.ts.map +1 -1
  6. package/dist/app.js +31 -274
  7. package/dist/app.js.map +1 -1
  8. package/dist/app.parseInput.test.js +1 -9
  9. package/dist/app.parseInput.test.js.map +1 -1
  10. package/dist/cli.js +1 -0
  11. package/dist/cli.js.map +1 -1
  12. package/dist/components/ApprovalPrompt.d.ts +2 -1
  13. package/dist/components/ApprovalPrompt.d.ts.map +1 -1
  14. package/dist/components/ApprovalPrompt.js +15 -0
  15. package/dist/components/ApprovalPrompt.js.map +1 -1
  16. package/dist/components/BottomArea.d.ts +1 -1
  17. package/dist/components/BottomArea.d.ts.map +1 -1
  18. package/dist/components/Input/determine-active-menu.d.ts +23 -0
  19. package/dist/components/Input/determine-active-menu.d.ts.map +1 -0
  20. package/dist/components/Input/determine-active-menu.js +57 -0
  21. package/dist/components/Input/determine-active-menu.js.map +1 -0
  22. package/dist/components/Input/input-width.d.ts +7 -0
  23. package/dist/components/Input/input-width.d.ts.map +1 -0
  24. package/dist/components/Input/input-width.js +20 -0
  25. package/dist/components/Input/input-width.js.map +1 -0
  26. package/dist/components/Input/insertions.d.ts +34 -0
  27. package/dist/components/Input/insertions.d.ts.map +1 -0
  28. package/dist/components/Input/insertions.js +52 -0
  29. package/dist/components/Input/insertions.js.map +1 -0
  30. package/dist/components/Input/popup-props.d.ts +18 -0
  31. package/dist/components/Input/popup-props.d.ts.map +1 -0
  32. package/dist/components/Input/popup-props.js +42 -0
  33. package/dist/components/Input/popup-props.js.map +1 -0
  34. package/dist/components/Input/triggers.d.ts +9 -0
  35. package/dist/components/Input/triggers.d.ts.map +1 -0
  36. package/dist/components/Input/triggers.js +25 -0
  37. package/dist/components/Input/triggers.js.map +1 -0
  38. package/dist/components/InputBox.d.ts +2 -6
  39. package/dist/components/InputBox.d.ts.map +1 -1
  40. package/dist/components/InputBox.js +118 -406
  41. package/dist/components/InputBox.js.map +1 -1
  42. package/dist/components/InputBox.menu-logic.test.js +82 -99
  43. package/dist/components/InputBox.menu-logic.test.js.map +1 -1
  44. package/dist/components/MarkdownRenderer.d.ts.map +1 -1
  45. package/dist/components/MarkdownRenderer.js +96 -23
  46. package/dist/components/MarkdownRenderer.js.map +1 -1
  47. package/dist/components/MessageList.d.ts +8 -0
  48. package/dist/components/MessageList.d.ts.map +1 -1
  49. package/dist/components/MessageList.js +25 -7
  50. package/dist/components/MessageList.js.map +1 -1
  51. package/dist/components/MessageList.test.js +48 -1
  52. package/dist/components/MessageList.test.js.map +1 -1
  53. package/dist/components/StatusBar.d.ts +1 -1
  54. package/dist/components/StatusBar.d.ts.map +1 -1
  55. package/dist/components/StatusBar.js +49 -38
  56. package/dist/components/StatusBar.js.map +1 -1
  57. package/dist/contracts/conversation.d.ts +9 -0
  58. package/dist/contracts/conversation.d.ts.map +1 -1
  59. package/dist/hooks/message-id.d.ts +3 -0
  60. package/dist/hooks/message-id.d.ts.map +1 -0
  61. package/dist/hooks/message-id.js +17 -0
  62. package/dist/hooks/message-id.js.map +1 -0
  63. package/dist/hooks/message-id.test.d.ts +2 -0
  64. package/dist/hooks/message-id.test.d.ts.map +1 -0
  65. package/dist/hooks/message-id.test.js +17 -0
  66. package/dist/hooks/message-id.test.js.map +1 -0
  67. package/dist/hooks/use-app-commands.d.ts +20 -0
  68. package/dist/hooks/use-app-commands.d.ts.map +1 -0
  69. package/dist/hooks/use-app-commands.js +197 -0
  70. package/dist/hooks/use-app-commands.js.map +1 -0
  71. package/dist/hooks/use-app-commands.test.d.ts +2 -0
  72. package/dist/hooks/use-app-commands.test.d.ts.map +1 -0
  73. package/dist/hooks/use-app-commands.test.js +34 -0
  74. package/dist/hooks/use-app-commands.test.js.map +1 -0
  75. package/dist/hooks/use-conversation.d.ts +11 -11
  76. package/dist/hooks/use-conversation.d.ts.map +1 -1
  77. package/dist/hooks/use-conversation.js +13 -10
  78. package/dist/hooks/use-conversation.js.map +1 -1
  79. package/dist/hooks/use-escape-key.d.ts +24 -0
  80. package/dist/hooks/use-escape-key.d.ts.map +1 -0
  81. package/dist/hooks/use-escape-key.js +60 -0
  82. package/dist/hooks/use-escape-key.js.map +1 -0
  83. package/dist/hooks/use-escape-key.test.d.ts +2 -0
  84. package/dist/hooks/use-escape-key.test.d.ts.map +1 -0
  85. package/dist/hooks/use-escape-key.test.js +49 -0
  86. package/dist/hooks/use-escape-key.test.js.map +1 -0
  87. package/dist/hooks/use-mode-handlers.d.ts +35 -0
  88. package/dist/hooks/use-mode-handlers.d.ts.map +1 -0
  89. package/dist/hooks/use-mode-handlers.js +79 -0
  90. package/dist/hooks/use-mode-handlers.js.map +1 -0
  91. package/dist/hooks/use-model-selection.d.ts +6 -3
  92. package/dist/hooks/use-model-selection.d.ts.map +1 -1
  93. package/dist/hooks/use-model-selection.js +19 -16
  94. package/dist/hooks/use-model-selection.js.map +1 -1
  95. package/dist/hooks/use-model-selection.test.d.ts.map +1 -1
  96. package/dist/hooks/use-model-selection.test.js +53 -22
  97. package/dist/hooks/use-model-selection.test.js.map +1 -1
  98. package/dist/hooks/use-path-completion.d.ts.map +1 -1
  99. package/dist/hooks/use-path-completion.js +5 -36
  100. package/dist/hooks/use-path-completion.js.map +1 -1
  101. package/dist/hooks/use-runtime-settings.d.ts +12 -0
  102. package/dist/hooks/use-runtime-settings.d.ts.map +1 -0
  103. package/dist/hooks/use-runtime-settings.js +68 -0
  104. package/dist/hooks/use-runtime-settings.js.map +1 -0
  105. package/dist/hooks/use-selection.d.ts +8 -0
  106. package/dist/hooks/use-selection.d.ts.map +1 -0
  107. package/dist/hooks/use-selection.js +31 -0
  108. package/dist/hooks/use-selection.js.map +1 -0
  109. package/dist/hooks/use-settings-completion.d.ts.map +1 -1
  110. package/dist/hooks/use-settings-completion.js +15 -30
  111. package/dist/hooks/use-settings-completion.js.map +1 -1
  112. package/dist/hooks/use-settings-completion.test.js +9 -9
  113. package/dist/hooks/use-settings-completion.test.js.map +1 -1
  114. package/dist/hooks/use-settings-value-completion.d.ts.map +1 -1
  115. package/dist/hooks/use-settings-value-completion.js +30 -28
  116. package/dist/hooks/use-settings-value-completion.js.map +1 -1
  117. package/dist/hooks/use-settings-value-completion.test.js +13 -0
  118. package/dist/hooks/use-settings-value-completion.test.js.map +1 -1
  119. package/dist/hooks/use-shell-mode.d.ts +31 -0
  120. package/dist/hooks/use-shell-mode.d.ts.map +1 -0
  121. package/dist/hooks/use-shell-mode.js +85 -0
  122. package/dist/hooks/use-shell-mode.js.map +1 -0
  123. package/dist/hooks/use-slash-commands.d.ts +1 -0
  124. package/dist/hooks/use-slash-commands.d.ts.map +1 -1
  125. package/dist/hooks/use-slash-commands.js +32 -23
  126. package/dist/hooks/use-slash-commands.js.map +1 -1
  127. package/dist/hooks/use-terminal-width.d.ts +7 -0
  128. package/dist/hooks/use-terminal-width.d.ts.map +1 -0
  129. package/dist/hooks/use-terminal-width.js +33 -0
  130. package/dist/hooks/use-terminal-width.js.map +1 -0
  131. package/dist/hooks/use-trigger-detection.d.ts +40 -0
  132. package/dist/hooks/use-trigger-detection.d.ts.map +1 -0
  133. package/dist/hooks/use-trigger-detection.js +45 -0
  134. package/dist/hooks/use-trigger-detection.js.map +1 -0
  135. package/dist/lib/editor-impl.js +6 -6
  136. package/dist/lib/editor-impl.js.map +1 -1
  137. package/dist/lib/openai-agent-client.d.ts +2 -0
  138. package/dist/lib/openai-agent-client.d.ts.map +1 -1
  139. package/dist/lib/openai-agent-client.js +187 -191
  140. package/dist/lib/openai-agent-client.js.map +1 -1
  141. package/dist/lib/openai-agent-client.public-methods.test.js +61 -13
  142. package/dist/lib/openai-agent-client.public-methods.test.js.map +1 -1
  143. package/dist/lib/retry-executor.d.ts +16 -0
  144. package/dist/lib/retry-executor.d.ts.map +1 -0
  145. package/dist/lib/retry-executor.js +71 -0
  146. package/dist/lib/retry-executor.js.map +1 -0
  147. package/dist/lib/retry-executor.test.d.ts +2 -0
  148. package/dist/lib/retry-executor.test.d.ts.map +1 -0
  149. package/dist/lib/retry-executor.test.js +178 -0
  150. package/dist/lib/retry-executor.test.js.map +1 -0
  151. package/dist/lib/tool-selection-policy.d.ts +14 -0
  152. package/dist/lib/tool-selection-policy.d.ts.map +1 -0
  153. package/dist/lib/tool-selection-policy.js +17 -0
  154. package/dist/lib/tool-selection-policy.js.map +1 -0
  155. package/dist/lib/tool-selection-policy.test.d.ts +2 -0
  156. package/dist/lib/tool-selection-policy.test.d.ts.map +1 -0
  157. package/dist/lib/tool-selection-policy.test.js +69 -0
  158. package/dist/lib/tool-selection-policy.test.js.map +1 -0
  159. package/dist/providers/index.d.ts +1 -1
  160. package/dist/providers/index.d.ts.map +1 -1
  161. package/dist/providers/index.js +1 -1
  162. package/dist/providers/index.js.map +1 -1
  163. package/dist/providers/openai-compatible/model.d.ts.map +1 -1
  164. package/dist/providers/openai-compatible/model.js +68 -7
  165. package/dist/providers/openai-compatible/model.js.map +1 -1
  166. package/dist/providers/openai-compatible/reasoning-content.test.js +107 -6
  167. package/dist/providers/openai-compatible/reasoning-content.test.js.map +1 -1
  168. package/dist/providers/openai-compatible.provider.d.ts.map +1 -1
  169. package/dist/providers/openai-compatible.provider.js.map +1 -1
  170. package/dist/providers/openai.provider.js +2 -0
  171. package/dist/providers/openai.provider.js.map +1 -1
  172. package/dist/providers/openrouter/converters.d.ts.map +1 -1
  173. package/dist/providers/openrouter/converters.js +8 -6
  174. package/dist/providers/openrouter/converters.js.map +1 -1
  175. package/dist/providers/openrouter/converters.test.js +24 -0
  176. package/dist/providers/openrouter/converters.test.js.map +1 -1
  177. package/dist/providers/openrouter/model.d.ts.map +1 -1
  178. package/dist/providers/openrouter/model.js +13 -5
  179. package/dist/providers/openrouter/model.js.map +1 -1
  180. package/dist/providers/openrouter/reasoning-content.test.js +48 -2
  181. package/dist/providers/openrouter/reasoning-content.test.js.map +1 -1
  182. package/dist/providers/openrouter.provider.createRunner.test.js +17 -9
  183. package/dist/providers/openrouter.provider.createRunner.test.js.map +1 -1
  184. package/dist/providers/openrouter.provider.js.map +1 -1
  185. package/dist/providers/openrouter.test.js +0 -2
  186. package/dist/providers/openrouter.test.js.map +1 -1
  187. package/dist/providers/registry.d.ts +17 -8
  188. package/dist/providers/registry.d.ts.map +1 -1
  189. package/dist/providers/registry.js +9 -0
  190. package/dist/providers/registry.js.map +1 -1
  191. package/dist/providers/web-search/exa.provider.d.ts +15 -0
  192. package/dist/providers/web-search/exa.provider.d.ts.map +1 -0
  193. package/dist/providers/web-search/exa.provider.js +82 -0
  194. package/dist/providers/web-search/exa.provider.js.map +1 -0
  195. package/dist/providers/web-search/exa.provider.test.d.ts +2 -0
  196. package/dist/providers/web-search/exa.provider.test.d.ts.map +1 -0
  197. package/dist/providers/web-search/exa.provider.test.js +67 -0
  198. package/dist/providers/web-search/exa.provider.test.js.map +1 -0
  199. package/dist/providers/web-search/index.d.ts +1 -0
  200. package/dist/providers/web-search/index.d.ts.map +1 -1
  201. package/dist/providers/web-search/index.js +1 -0
  202. package/dist/providers/web-search/index.js.map +1 -1
  203. package/dist/scripts/eval-auto-approval/cache.d.ts +9 -0
  204. package/dist/scripts/eval-auto-approval/cache.d.ts.map +1 -0
  205. package/dist/scripts/eval-auto-approval/cache.js +64 -0
  206. package/dist/scripts/eval-auto-approval/cache.js.map +1 -0
  207. package/dist/scripts/eval-auto-approval/dataset.d.ts +45 -0
  208. package/dist/scripts/eval-auto-approval/dataset.d.ts.map +1 -0
  209. package/dist/scripts/eval-auto-approval/dataset.js +65 -0
  210. package/dist/scripts/eval-auto-approval/dataset.js.map +1 -0
  211. package/dist/scripts/eval-auto-approval/dataset.test.d.ts +2 -0
  212. package/dist/scripts/eval-auto-approval/dataset.test.d.ts.map +1 -0
  213. package/dist/scripts/eval-auto-approval/dataset.test.js +88 -0
  214. package/dist/scripts/eval-auto-approval/dataset.test.js.map +1 -0
  215. package/dist/scripts/eval-auto-approval/leaderboard.d.ts +92 -0
  216. package/dist/scripts/eval-auto-approval/leaderboard.d.ts.map +1 -0
  217. package/dist/scripts/eval-auto-approval/leaderboard.js +402 -0
  218. package/dist/scripts/eval-auto-approval/leaderboard.js.map +1 -0
  219. package/dist/scripts/eval-auto-approval/leaderboard.test.d.ts +2 -0
  220. package/dist/scripts/eval-auto-approval/leaderboard.test.d.ts.map +1 -0
  221. package/dist/scripts/eval-auto-approval/leaderboard.test.js +689 -0
  222. package/dist/scripts/eval-auto-approval/leaderboard.test.js.map +1 -0
  223. package/dist/scripts/eval-auto-approval/metrics.d.ts +34 -0
  224. package/dist/scripts/eval-auto-approval/metrics.d.ts.map +1 -0
  225. package/dist/scripts/eval-auto-approval/metrics.js +74 -0
  226. package/dist/scripts/eval-auto-approval/metrics.js.map +1 -0
  227. package/dist/scripts/eval-auto-approval/metrics.test.d.ts +2 -0
  228. package/dist/scripts/eval-auto-approval/metrics.test.d.ts.map +1 -0
  229. package/dist/scripts/eval-auto-approval/metrics.test.js +79 -0
  230. package/dist/scripts/eval-auto-approval/metrics.test.js.map +1 -0
  231. package/dist/scripts/eval-auto-approval/report.d.ts +5 -0
  232. package/dist/scripts/eval-auto-approval/report.d.ts.map +1 -0
  233. package/dist/scripts/eval-auto-approval/report.js +51 -0
  234. package/dist/scripts/eval-auto-approval/report.js.map +1 -0
  235. package/dist/scripts/eval-auto-approval/report.test.d.ts +2 -0
  236. package/dist/scripts/eval-auto-approval/report.test.d.ts.map +1 -0
  237. package/dist/scripts/eval-auto-approval/report.test.js +23 -0
  238. package/dist/scripts/eval-auto-approval/report.test.js.map +1 -0
  239. package/dist/scripts/eval-auto-approval/runner-utils.d.ts +41 -0
  240. package/dist/scripts/eval-auto-approval/runner-utils.d.ts.map +1 -0
  241. package/dist/scripts/eval-auto-approval/runner-utils.js +187 -0
  242. package/dist/scripts/eval-auto-approval/runner-utils.js.map +1 -0
  243. package/dist/scripts/eval-auto-approval/runner-utils.test.d.ts +2 -0
  244. package/dist/scripts/eval-auto-approval/runner-utils.test.d.ts.map +1 -0
  245. package/dist/scripts/eval-auto-approval/runner-utils.test.js +135 -0
  246. package/dist/scripts/eval-auto-approval/runner-utils.test.js.map +1 -0
  247. package/dist/scripts/eval-auto-approval/runner.d.ts +2 -0
  248. package/dist/scripts/eval-auto-approval/runner.d.ts.map +1 -0
  249. package/dist/scripts/eval-auto-approval/runner.js +326 -0
  250. package/dist/scripts/eval-auto-approval/runner.js.map +1 -0
  251. package/dist/services/agent-stream.d.ts +11 -0
  252. package/dist/services/agent-stream.d.ts.map +1 -0
  253. package/dist/services/agent-stream.js +2 -0
  254. package/dist/services/agent-stream.js.map +1 -0
  255. package/dist/services/approval-flow-coordinator.d.ts +43 -0
  256. package/dist/services/approval-flow-coordinator.d.ts.map +1 -0
  257. package/dist/services/approval-flow-coordinator.js +120 -0
  258. package/dist/services/approval-flow-coordinator.js.map +1 -0
  259. package/dist/services/approval-flow-coordinator.test.d.ts +2 -0
  260. package/dist/services/approval-flow-coordinator.test.d.ts.map +1 -0
  261. package/dist/services/approval-flow-coordinator.test.js +168 -0
  262. package/dist/services/approval-flow-coordinator.test.js.map +1 -0
  263. package/dist/services/approval-rejection-interceptor.d.ts +16 -0
  264. package/dist/services/approval-rejection-interceptor.d.ts.map +1 -0
  265. package/dist/services/approval-rejection-interceptor.js +20 -0
  266. package/dist/services/approval-rejection-interceptor.js.map +1 -0
  267. package/dist/services/approval-rejection-interceptor.test.d.ts +2 -0
  268. package/dist/services/approval-rejection-interceptor.test.d.ts.map +1 -0
  269. package/dist/services/approval-rejection-interceptor.test.js +60 -0
  270. package/dist/services/approval-rejection-interceptor.test.js.map +1 -0
  271. package/dist/services/conversation-events.d.ts +4 -2
  272. package/dist/services/conversation-events.d.ts.map +1 -1
  273. package/dist/services/conversation-result-builder.d.ts +34 -34
  274. package/dist/services/conversation-result-builder.d.ts.map +1 -1
  275. package/dist/services/conversation-result-builder.js +64 -76
  276. package/dist/services/conversation-result-builder.js.map +1 -1
  277. package/dist/services/conversation-result-builder.test.js +145 -65
  278. package/dist/services/conversation-result-builder.test.js.map +1 -1
  279. package/dist/services/conversation-retry-policy.d.ts +37 -0
  280. package/dist/services/conversation-retry-policy.d.ts.map +1 -0
  281. package/dist/services/conversation-retry-policy.js +51 -0
  282. package/dist/services/conversation-retry-policy.js.map +1 -0
  283. package/dist/services/conversation-retry-policy.test.d.ts +2 -0
  284. package/dist/services/conversation-retry-policy.test.d.ts.map +1 -0
  285. package/dist/services/conversation-retry-policy.test.js +79 -0
  286. package/dist/services/conversation-retry-policy.test.js.map +1 -0
  287. package/dist/services/conversation-service.d.ts +2 -1
  288. package/dist/services/conversation-service.d.ts.map +1 -1
  289. package/dist/services/conversation-session.auto-approval.test.d.ts +2 -0
  290. package/dist/services/conversation-session.auto-approval.test.d.ts.map +1 -0
  291. package/dist/services/conversation-session.auto-approval.test.js +617 -0
  292. package/dist/services/conversation-session.auto-approval.test.js.map +1 -0
  293. package/dist/services/conversation-session.d.ts +6 -3
  294. package/dist/services/conversation-session.d.ts.map +1 -1
  295. package/dist/services/conversation-session.js +164 -696
  296. package/dist/services/conversation-session.js.map +1 -1
  297. package/dist/services/interruption-info.d.ts +13 -0
  298. package/dist/services/interruption-info.d.ts.map +1 -0
  299. package/dist/services/interruption-info.js +89 -0
  300. package/dist/services/interruption-info.js.map +1 -0
  301. package/dist/services/interruption-info.test.d.ts +2 -0
  302. package/dist/services/interruption-info.test.d.ts.map +1 -0
  303. package/dist/services/interruption-info.test.js +84 -0
  304. package/dist/services/interruption-info.test.js.map +1 -0
  305. package/dist/services/logging-contract.d.ts +1 -1
  306. package/dist/services/logging-service.d.ts +6 -2
  307. package/dist/services/logging-service.d.ts.map +1 -1
  308. package/dist/services/logging-service.js +48 -91
  309. package/dist/services/logging-service.js.map +1 -1
  310. package/dist/services/settings-env.d.ts.map +1 -1
  311. package/dist/services/settings-env.js +3 -0
  312. package/dist/services/settings-env.js.map +1 -1
  313. package/dist/services/settings-schema.d.ts +34 -0
  314. package/dist/services/settings-schema.d.ts.map +1 -1
  315. package/dist/services/settings-schema.js +37 -0
  316. package/dist/services/settings-schema.js.map +1 -1
  317. package/dist/services/settings-service.d.ts.map +1 -1
  318. package/dist/services/settings-service.js +12 -166
  319. package/dist/services/settings-service.js.map +1 -1
  320. package/dist/services/settings-sources.d.ts +5 -0
  321. package/dist/services/settings-sources.d.ts.map +1 -0
  322. package/dist/services/settings-sources.js +92 -0
  323. package/dist/services/settings-sources.js.map +1 -0
  324. package/dist/services/settings-sources.test.d.ts +2 -0
  325. package/dist/services/settings-sources.test.d.ts.map +1 -0
  326. package/dist/services/settings-sources.test.js +34 -0
  327. package/dist/services/settings-sources.test.js.map +1 -0
  328. package/dist/services/shell-auto-approval-evaluator.d.ts +19 -0
  329. package/dist/services/shell-auto-approval-evaluator.d.ts.map +1 -0
  330. package/dist/services/shell-auto-approval-evaluator.js +207 -0
  331. package/dist/services/shell-auto-approval-evaluator.js.map +1 -0
  332. package/dist/services/shell-auto-approval-evaluator.test.d.ts +2 -0
  333. package/dist/services/shell-auto-approval-evaluator.test.d.ts.map +1 -0
  334. package/dist/services/shell-auto-approval-evaluator.test.js +211 -0
  335. package/dist/services/shell-auto-approval-evaluator.test.js.map +1 -0
  336. package/dist/services/shell-auto-approval-resolver.d.ts +24 -0
  337. package/dist/services/shell-auto-approval-resolver.d.ts.map +1 -0
  338. package/dist/services/shell-auto-approval-resolver.js +59 -0
  339. package/dist/services/shell-auto-approval-resolver.js.map +1 -0
  340. package/dist/services/shell-auto-approval-resolver.test.d.ts +2 -0
  341. package/dist/services/shell-auto-approval-resolver.test.d.ts.map +1 -0
  342. package/dist/services/shell-auto-approval-resolver.test.js +110 -0
  343. package/dist/services/shell-auto-approval-resolver.test.js.map +1 -0
  344. package/dist/services/ssh-service.test.js +2 -2
  345. package/dist/services/ssh-service.test.js.map +1 -1
  346. package/dist/services/stream-event-processor.d.ts +18 -23
  347. package/dist/services/stream-event-processor.d.ts.map +1 -1
  348. package/dist/services/stream-event-processor.js +186 -325
  349. package/dist/services/stream-event-processor.js.map +1 -1
  350. package/dist/services/stream-event-processor.test.js +143 -90
  351. package/dist/services/stream-event-processor.test.js.map +1 -1
  352. package/dist/services/terminal-result-collector.d.ts +12 -0
  353. package/dist/services/terminal-result-collector.d.ts.map +1 -0
  354. package/dist/services/terminal-result-collector.js +64 -0
  355. package/dist/services/terminal-result-collector.js.map +1 -0
  356. package/dist/services/terminal-result-collector.test.d.ts +2 -0
  357. package/dist/services/terminal-result-collector.test.d.ts.map +1 -0
  358. package/dist/services/terminal-result-collector.test.js +93 -0
  359. package/dist/services/terminal-result-collector.test.js.map +1 -0
  360. package/dist/tools/apply-patch.js +5 -5
  361. package/dist/tools/apply-patch.js.map +1 -1
  362. package/dist/tools/create-file.js +2 -2
  363. package/dist/tools/create-file.js.map +1 -1
  364. package/dist/tools/edit-healing.d.ts.map +1 -1
  365. package/dist/tools/edit-healing.js +4 -1
  366. package/dist/tools/edit-healing.js.map +1 -1
  367. package/dist/tools/edit-healing.test.js +22 -0
  368. package/dist/tools/edit-healing.test.js.map +1 -1
  369. package/dist/tools/search-replace.d.ts.map +1 -1
  370. package/dist/tools/search-replace.js +114 -194
  371. package/dist/tools/search-replace.js.map +1 -1
  372. package/dist/tools/search-replace.test.js +38 -0
  373. package/dist/tools/search-replace.test.js.map +1 -1
  374. package/dist/tools/shell.js +2 -2
  375. package/dist/tools/shell.js.map +1 -1
  376. package/dist/tools/shell.test.js +0 -5
  377. package/dist/tools/shell.test.js.map +1 -1
  378. package/dist/tools/web-fetch.test.js +3 -3
  379. package/dist/tools/web-fetch.test.js.map +1 -1
  380. package/dist/utils/clipboard.d.ts +16 -0
  381. package/dist/utils/clipboard.d.ts.map +1 -0
  382. package/dist/utils/clipboard.js +55 -0
  383. package/dist/utils/clipboard.js.map +1 -0
  384. package/dist/utils/clipboard.test.d.ts +2 -0
  385. package/dist/utils/clipboard.test.d.ts.map +1 -0
  386. package/dist/utils/clipboard.test.js +59 -0
  387. package/dist/utils/clipboard.test.js.map +1 -0
  388. package/dist/utils/command-safety/constants.d.ts.map +1 -1
  389. package/dist/utils/command-safety/constants.js +3 -21
  390. package/dist/utils/command-safety/constants.js.map +1 -1
  391. package/dist/utils/command-safety/find-helpers.d.ts.map +1 -1
  392. package/dist/utils/command-safety/find-helpers.js +13 -95
  393. package/dist/utils/command-safety/find-helpers.js.map +1 -1
  394. package/dist/utils/command-safety/handlers/sed-handler.d.ts.map +1 -1
  395. package/dist/utils/command-safety/handlers/sed-handler.js +2 -4
  396. package/dist/utils/command-safety/handlers/sed-handler.js.map +1 -1
  397. package/dist/utils/command-safety/index.d.ts +9 -0
  398. package/dist/utils/command-safety/index.d.ts.map +1 -1
  399. package/dist/utils/command-safety/index.js +12 -2
  400. package/dist/utils/command-safety/index.js.map +1 -1
  401. package/dist/utils/command-safety/path-analysis.d.ts.map +1 -1
  402. package/dist/utils/command-safety/path-analysis.js +7 -6
  403. package/dist/utils/command-safety/path-analysis.js.map +1 -1
  404. package/dist/utils/command-safety.find.test.js +56 -39
  405. package/dist/utils/command-safety.find.test.js.map +1 -1
  406. package/dist/utils/command-safety.path.test.js +7 -7
  407. package/dist/utils/command-safety.path.test.js.map +1 -1
  408. package/dist/utils/command-safety.red-yellow-policy.test.d.ts +2 -0
  409. package/dist/utils/command-safety.red-yellow-policy.test.d.ts.map +1 -0
  410. package/dist/utils/command-safety.red-yellow-policy.test.js +36 -0
  411. package/dist/utils/command-safety.red-yellow-policy.test.js.map +1 -0
  412. package/dist/utils/conversation-event-handler.d.ts +4 -3
  413. package/dist/utils/conversation-event-handler.d.ts.map +1 -1
  414. package/dist/utils/conversation-event-handler.js +15 -5
  415. package/dist/utils/conversation-event-handler.js.map +1 -1
  416. package/dist/utils/conversation-event-handler.test.js +24 -0
  417. package/dist/utils/conversation-event-handler.test.js.map +1 -1
  418. package/dist/utils/conversation-utils.d.ts +1 -1
  419. package/dist/utils/execute-shell.d.ts +10 -0
  420. package/dist/utils/execute-shell.d.ts.map +1 -1
  421. package/dist/utils/execute-shell.js +3 -3
  422. package/dist/utils/execute-shell.js.map +1 -1
  423. package/dist/utils/execute-shell.test.js +19 -3
  424. package/dist/utils/execute-shell.test.js.map +1 -1
  425. package/dist/utils/input-parser.d.ts +13 -0
  426. package/dist/utils/input-parser.d.ts.map +1 -0
  427. package/dist/utils/input-parser.js +10 -0
  428. package/dist/utils/input-parser.js.map +1 -0
  429. package/dist/utils/model-provider-arg.d.ts +5 -0
  430. package/dist/utils/model-provider-arg.d.ts.map +1 -0
  431. package/dist/utils/model-provider-arg.js +15 -0
  432. package/dist/utils/model-provider-arg.js.map +1 -0
  433. package/dist/utils/model-provider-arg.test.d.ts +2 -0
  434. package/dist/utils/model-provider-arg.test.d.ts.map +1 -0
  435. package/dist/utils/model-provider-arg.test.js +21 -0
  436. package/dist/utils/model-provider-arg.test.js.map +1 -0
  437. package/dist/utils/model-settings.d.ts +12 -0
  438. package/dist/utils/model-settings.d.ts.map +1 -0
  439. package/dist/utils/model-settings.js +35 -0
  440. package/dist/utils/model-settings.js.map +1 -0
  441. package/dist/utils/provider-traffic-extractor.d.ts +1 -0
  442. package/dist/utils/provider-traffic-extractor.d.ts.map +1 -1
  443. package/dist/utils/provider-traffic-extractor.js +90 -5
  444. package/dist/utils/provider-traffic-extractor.js.map +1 -1
  445. package/dist/utils/settings-command.d.ts.map +1 -1
  446. package/dist/utils/settings-command.js +10 -8
  447. package/dist/utils/settings-command.js.map +1 -1
  448. package/dist/utils/streaming-session-factory.d.ts +1 -1
  449. package/dist/utils/streaming-session-factory.d.ts.map +1 -1
  450. package/dist/utils/streaming-session-factory.js +5 -2
  451. package/dist/utils/streaming-session-factory.js.map +1 -1
  452. package/dist/utils/streaming-session-factory.test.js +2 -2
  453. package/dist/utils/streaming-session-factory.test.js.map +1 -1
  454. package/dist/utils/streaming-updater.d.ts +2 -1
  455. package/dist/utils/streaming-updater.d.ts.map +1 -1
  456. package/dist/utils/streaming-updater.js +2 -2
  457. package/dist/utils/streaming-updater.js.map +1 -1
  458. package/dist/utils/throttle.d.ts +6 -1
  459. package/dist/utils/throttle.d.ts.map +1 -1
  460. package/dist/utils/throttle.js +11 -6
  461. package/dist/utils/throttle.js.map +1 -1
  462. package/dist/utils/viewport.d.ts +6 -0
  463. package/dist/utils/viewport.d.ts.map +1 -0
  464. package/dist/utils/viewport.js +20 -0
  465. package/dist/utils/viewport.js.map +1 -0
  466. package/dist/utils/viewport.test.d.ts +2 -0
  467. package/dist/utils/viewport.test.d.ts.map +1 -0
  468. package/dist/utils/viewport.test.js +43 -0
  469. package/dist/utils/viewport.test.js.map +1 -0
  470. package/package.json +5 -4
  471. package/dist/app.model-command-feedback.test.d.ts +0 -2
  472. package/dist/app.model-command-feedback.test.d.ts.map +0 -1
  473. package/dist/app.model-command-feedback.test.js +0 -19
  474. package/dist/app.model-command-feedback.test.js.map +0 -1
  475. package/dist/components/MentorMode.test.d.ts +0 -2
  476. package/dist/components/MentorMode.test.d.ts.map +0 -1
  477. package/dist/components/MentorMode.test.js.map +0 -1
  478. package/dist/components/ModelSelectionMenu.error-tabs.test.d.ts +0 -2
  479. package/dist/components/ModelSelectionMenu.error-tabs.test.d.ts.map +0 -1
  480. package/dist/components/ModelSelectionMenu.error-tabs.test.js +0 -18
  481. package/dist/components/ModelSelectionMenu.error-tabs.test.js.map +0 -1
  482. package/dist/components/StatusBar.test.d.ts +0 -2
  483. package/dist/components/StatusBar.test.d.ts.map +0 -1
  484. package/dist/components/StatusBar.test.js +0 -19
  485. package/dist/components/StatusBar.test.js.map +0 -1
  486. package/dist/components/TextInput.d.ts +0 -42
  487. package/dist/components/TextInput.d.ts.map +0 -1
  488. package/dist/components/TextInput.js +0 -397
  489. package/dist/components/TextInput.js.map +0 -1
  490. package/dist/components/TextInput.test.d.ts +0 -2
  491. package/dist/components/TextInput.test.d.ts.map +0 -1
  492. package/dist/components/TextInput.test.js +0 -75
  493. package/dist/components/TextInput.test.js.map +0 -1
  494. package/dist/debug-schema.d.ts +0 -2
  495. package/dist/debug-schema.d.ts.map +0 -1
  496. package/dist/debug-schema.js +0 -22
  497. package/dist/debug-schema.js.map +0 -1
  498. package/dist/hooks/use-path-completion.test.d.ts +0 -2
  499. package/dist/hooks/use-path-completion.test.d.ts.map +0 -1
  500. package/dist/hooks/use-path-completion.test.js +0 -29
  501. package/dist/hooks/use-path-completion.test.js.map +0 -1
  502. package/dist/lib/mentor-client.d.ts +0 -41
  503. package/dist/lib/mentor-client.d.ts.map +0 -1
  504. package/dist/lib/mentor-client.js +0 -146
  505. package/dist/lib/mentor-client.js.map +0 -1
  506. package/dist/lib/mentor-client.test.d.ts +0 -2
  507. package/dist/lib/mentor-client.test.d.ts.map +0 -1
  508. package/dist/lib/mentor-client.test.js +0 -440
  509. package/dist/lib/mentor-client.test.js.map +0 -1
  510. package/dist/lib/retry-strategy.d.ts +0 -43
  511. package/dist/lib/retry-strategy.d.ts.map +0 -1
  512. package/dist/lib/retry-strategy.js +0 -93
  513. package/dist/lib/retry-strategy.js.map +0 -1
  514. package/dist/lib/retry-strategy.test.d.ts +0 -2
  515. package/dist/lib/retry-strategy.test.d.ts.map +0 -1
  516. package/dist/lib/retry-strategy.test.js +0 -200
  517. package/dist/lib/retry-strategy.test.js.map +0 -1
  518. package/dist/lib/shell.d.ts +0 -7
  519. package/dist/lib/shell.d.ts.map +0 -1
  520. package/dist/lib/shell.js +0 -56
  521. package/dist/lib/shell.js.map +0 -1
  522. package/dist/prompts/default.md.bak +0 -77
  523. package/dist/prompts/simple-mentor.md +0 -207
  524. package/dist/providers/github-copilot/converters.d.ts +0 -45
  525. package/dist/providers/github-copilot/converters.d.ts.map +0 -1
  526. package/dist/providers/github-copilot/converters.js +0 -118
  527. package/dist/providers/github-copilot/converters.js.map +0 -1
  528. package/dist/providers/github-copilot/converters.test.d.ts +0 -2
  529. package/dist/providers/github-copilot/converters.test.d.ts.map +0 -1
  530. package/dist/providers/github-copilot/converters.test.js +0 -162
  531. package/dist/providers/github-copilot/converters.test.js.map +0 -1
  532. package/dist/providers/github-copilot/github-copilot.provider.d.ts +0 -2
  533. package/dist/providers/github-copilot/github-copilot.provider.d.ts.map +0 -1
  534. package/dist/providers/github-copilot/github-copilot.provider.js +0 -75
  535. package/dist/providers/github-copilot/github-copilot.provider.js.map +0 -1
  536. package/dist/providers/github-copilot/github-copilot.provider.test.d.ts +0 -2
  537. package/dist/providers/github-copilot/github-copilot.provider.test.d.ts.map +0 -1
  538. package/dist/providers/github-copilot/github-copilot.provider.test.js +0 -26
  539. package/dist/providers/github-copilot/github-copilot.provider.test.js.map +0 -1
  540. package/dist/providers/github-copilot/index.d.ts +0 -4
  541. package/dist/providers/github-copilot/index.d.ts.map +0 -1
  542. package/dist/providers/github-copilot/index.js +0 -4
  543. package/dist/providers/github-copilot/index.js.map +0 -1
  544. package/dist/providers/github-copilot/model-direct.d.ts +0 -34
  545. package/dist/providers/github-copilot/model-direct.d.ts.map +0 -1
  546. package/dist/providers/github-copilot/model-direct.js +0 -443
  547. package/dist/providers/github-copilot/model-direct.js.map +0 -1
  548. package/dist/providers/github-copilot/model.d.ts +0 -24
  549. package/dist/providers/github-copilot/model.d.ts.map +0 -1
  550. package/dist/providers/github-copilot/model.delta.test.d.ts +0 -2
  551. package/dist/providers/github-copilot/model.delta.test.d.ts.map +0 -1
  552. package/dist/providers/github-copilot/model.delta.test.js +0 -15
  553. package/dist/providers/github-copilot/model.delta.test.js.map +0 -1
  554. package/dist/providers/github-copilot/model.js +0 -581
  555. package/dist/providers/github-copilot/model.js.map +0 -1
  556. package/dist/providers/github-copilot/provider.d.ts +0 -20
  557. package/dist/providers/github-copilot/provider.d.ts.map +0 -1
  558. package/dist/providers/github-copilot/provider.js +0 -30
  559. package/dist/providers/github-copilot/provider.js.map +0 -1
  560. package/dist/providers/github-copilot/provider.test.d.ts +0 -2
  561. package/dist/providers/github-copilot/provider.test.d.ts.map +0 -1
  562. package/dist/providers/github-copilot/provider.test.js +0 -52
  563. package/dist/providers/github-copilot/provider.test.js.map +0 -1
  564. package/dist/providers/github-copilot/utils.d.ts +0 -20
  565. package/dist/providers/github-copilot/utils.d.ts.map +0 -1
  566. package/dist/providers/github-copilot/utils.js +0 -142
  567. package/dist/providers/github-copilot/utils.js.map +0 -1
  568. package/dist/providers/github-copilot/utils.test.d.ts +0 -2
  569. package/dist/providers/github-copilot/utils.test.d.ts.map +0 -1
  570. package/dist/providers/github-copilot/utils.test.js +0 -21
  571. package/dist/providers/github-copilot/utils.test.js.map +0 -1
  572. package/dist/providers/openrouter/merge-messages.test.d.ts +0 -2
  573. package/dist/providers/openrouter/merge-messages.test.d.ts.map +0 -1
  574. package/dist/providers/openrouter/merge-messages.test.js +0 -83
  575. package/dist/providers/openrouter/merge-messages.test.js.map +0 -1
  576. package/dist/providers/openrouter.history.test.d.ts +0 -2
  577. package/dist/providers/openrouter.history.test.d.ts.map +0 -1
  578. package/dist/providers/openrouter.history.test.js +0 -533
  579. package/dist/providers/openrouter.history.test.js.map +0 -1
  580. package/dist/reproduce_issue.test.d.ts +0 -2
  581. package/dist/reproduce_issue.test.d.ts.map +0 -1
  582. package/dist/reproduce_issue.test.js +0 -31
  583. package/dist/reproduce_issue.test.js.map +0 -1
  584. package/dist/safety-checker.js +0 -57
  585. package/dist/services/conversation-service.test.js +0 -190
  586. package/dist/services/conversation-session.usage.test.d.ts +0 -2
  587. package/dist/services/conversation-session.usage.test.d.ts.map +0 -1
  588. package/dist/services/conversation-session.usage.test.js +0 -59
  589. package/dist/services/conversation-session.usage.test.js.map +0 -1
  590. package/dist/test-search-tool.d.ts +0 -2
  591. package/dist/test-search-tool.d.ts.map +0 -1
  592. package/dist/test-search-tool.js +0 -36
  593. package/dist/test-search-tool.js.map +0 -1
  594. package/dist/tools/bash.d.ts +0 -10
  595. package/dist/tools/bash.d.ts.map +0 -1
  596. package/dist/tools/bash.js +0 -55
  597. package/dist/tools/bash.js.map +0 -1
  598. package/dist/types/messages.d.ts +0 -29
  599. package/dist/types/messages.d.ts.map +0 -1
  600. package/dist/types/messages.js +0 -2
  601. package/dist/types/messages.js.map +0 -1
  602. package/dist/utils/command-safety.d.ts +0 -21
  603. package/dist/utils/command-safety.d.ts.map +0 -1
  604. package/dist/utils/command-safety.js +0 -702
  605. package/dist/utils/command-safety.js.map +0 -1
  606. package/dist/utils/extract-command-messages.repro.test.d.ts +0 -2
  607. package/dist/utils/extract-command-messages.repro.test.d.ts.map +0 -1
  608. package/dist/utils/extract-command-messages.repro.test.js +0 -31
  609. package/dist/utils/extract-command-messages.repro.test.js.map +0 -1
  610. package/dist/utils/extract-command-messages.test.js +0 -57
  611. package/dist/utils/message-utils.d.ts +0 -17
  612. package/dist/utils/message-utils.d.ts.map +0 -1
  613. package/dist/utils/message-utils.js +0 -52
  614. package/dist/utils/message-utils.js.map +0 -1
  615. package/dist/utils/message-utils.test.d.ts +0 -2
  616. package/dist/utils/message-utils.test.d.ts.map +0 -1
  617. package/dist/utils/message-utils.test.js +0 -48
  618. package/dist/utils/message-utils.test.js.map +0 -1
@@ -1,104 +1,13 @@
1
- import { extractCommandMessages, markToolCallAsApprovalRejection } from '../utils/extract-command-messages.js';
2
1
  import { ConversationStore } from './conversation-store.js';
3
- import { ModelBehaviorError } from '@openai/agents';
4
- import { extractUsage } from '../utils/token-usage.js';
2
+ import { decideRetry, MAX_HALLUCINATION_RETRIES } from './conversation-retry-policy.js';
5
3
  import { getProvider } from '../providers/index.js';
6
- import { extractReasoningDelta, extractTextDelta } from './stream-event-parsing.js';
7
- import { captureToolCallArguments, emitCommandMessagesFromItems } from './command-message-streaming.js';
8
4
  import { ApprovalState } from './approval-state.js';
9
- import { createInvalidToolCallDiagnostic } from './logging-contract.js';
10
- const asRecord = (value) => value && typeof value === 'object' && !Array.isArray(value) ? value : undefined;
11
- const getString = (record, key) => {
12
- const value = record?.[key];
13
- return typeof value === 'string' ? value : undefined;
14
- };
15
- const getMethod = (target, key) => {
16
- const record = asRecord(target);
17
- const candidate = record?.[key];
18
- return typeof candidate === 'function' ? candidate : null;
19
- };
20
- const getCallIdFromObject = (value) => {
21
- const record = asRecord(value);
22
- const callId = getString(record, 'callId') ??
23
- getString(record, 'call_id') ??
24
- getString(record, 'tool_call_id') ??
25
- getString(record, 'toolCallId') ??
26
- getString(record, 'id');
27
- if (callId) {
28
- return callId;
29
- }
30
- const rawItem = asRecord(record?.rawItem);
31
- return (getString(rawItem, 'callId') ??
32
- getString(rawItem, 'call_id') ??
33
- getString(rawItem, 'tool_call_id') ??
34
- getString(rawItem, 'toolCallId') ??
35
- getString(rawItem, 'id'));
36
- };
37
- const getCommandFromArgs = (args) => {
38
- if (!args) {
39
- return '';
40
- }
41
- if (typeof args === 'string') {
42
- try {
43
- const parsed = JSON.parse(args);
44
- // Handle shell tool's command parameter
45
- if (parsed?.command) {
46
- return parsed.command;
47
- }
48
- // Fallback for old 'commands' array format
49
- if (Array.isArray(parsed?.commands)) {
50
- return parsed.commands.join('\n');
51
- }
52
- return JSON.stringify(parsed);
53
- }
54
- catch {
55
- return args;
56
- }
57
- }
58
- if (typeof args === 'object') {
59
- const argsRecord = asRecord(args);
60
- // Handle shell tool's command parameter
61
- const cmdFromObject = argsRecord?.command !== undefined ? String(argsRecord.command) : undefined;
62
- // Fallback for old 'commands' array format
63
- if (Array.isArray(argsRecord?.commands)) {
64
- return argsRecord.commands.join('\n');
65
- }
66
- let argsFromObject;
67
- if (argsRecord?.arguments !== undefined) {
68
- const rawArguments = argsRecord.arguments;
69
- if (typeof rawArguments === 'string') {
70
- try {
71
- argsFromObject = JSON.stringify(JSON.parse(rawArguments));
72
- }
73
- catch {
74
- argsFromObject = String(rawArguments);
75
- }
76
- }
77
- else if (rawArguments !== undefined) {
78
- argsFromObject = String(rawArguments);
79
- }
80
- }
81
- return cmdFromObject ?? argsFromObject ?? JSON.stringify(args);
82
- }
83
- return String(args);
84
- };
85
- /**
86
- * Maximum number of retries when the model hallucinates a tool
87
- */
88
- const MAX_HALLUCINATION_RETRIES = 2;
89
- /**
90
- * Check if an error is a recoverable model behavior error (hallucination, parsing error, etc.)
91
- */
92
- const isRecoverableModelError = (error) => {
93
- if (!(error instanceof ModelBehaviorError)) {
94
- return false;
95
- }
96
- const message = error.message.toLowerCase();
97
- return ((message.includes('tool') && message.includes('not found')) || // Hallucination
98
- message.includes('model did not produce a final response') || // Give up/exhausted
99
- message.includes('parsing tool arguments') || // Bad JSON
100
- message.includes('valid json'));
101
- };
5
+ import { collectTerminalResult } from './terminal-result-collector.js';
6
+ import { getMethod } from './interruption-info.js';
7
+ import { createStreamAccumulator, processStreamEvents } from './stream-event-processor.js';
8
+ import { ShellAutoApprovalResolver } from './shell-auto-approval-resolver.js';
9
+ import { ApprovalFlowCoordinator } from './approval-flow-coordinator.js';
10
+ import { buildConversationResult, toTerminalEvent } from './conversation-result-builder.js';
102
11
  const supportsConversationChaining = (providerId) => {
103
12
  const providerDef = getProvider(providerId);
104
13
  return providerDef?.capabilities?.supportsConversationChaining ?? false;
@@ -110,15 +19,29 @@ export class ConversationSession {
110
19
  conversationStore;
111
20
  previousResponseId = null;
112
21
  approvalState = new ApprovalState();
113
- textDeltaCount = 0;
114
- reasoningDeltaCount = 0;
115
22
  toolCallArgumentsById = new Map();
116
23
  emittedInvalidToolCallPackets = new Set();
117
- constructor(id, { agentClient, deps }) {
24
+ shellAutoApproval;
25
+ approvalFlow;
26
+ settingsService;
27
+ constructor(id, { agentClient, deps, }) {
118
28
  this.id = id;
119
29
  this.agentClient = agentClient;
120
30
  this.logger = deps.logger;
31
+ this.settingsService = deps.settingsService;
121
32
  this.conversationStore = new ConversationStore();
33
+ this.shellAutoApproval = new ShellAutoApprovalResolver({
34
+ conversationStore: this.conversationStore,
35
+ agentClient: this.agentClient,
36
+ logger: this.logger,
37
+ settingsService: this.settingsService,
38
+ });
39
+ this.approvalFlow = new ApprovalFlowCoordinator({
40
+ agentClient: this.agentClient,
41
+ approvalState: this.approvalState,
42
+ logger: this.logger,
43
+ sessionId: this.id,
44
+ });
122
45
  }
123
46
  reset() {
124
47
  this.previousResponseId = null;
@@ -126,6 +49,7 @@ export class ConversationSession {
126
49
  this.approvalState.clearPending();
127
50
  this.approvalState.consumeAborted();
128
51
  this.toolCallArgumentsById.clear();
52
+ this.shellAutoApproval.clearCache();
129
53
  const clearConversations = getMethod(this.agentClient, 'clearConversations');
130
54
  clearConversations?.call(this.agentClient);
131
55
  }
@@ -156,17 +80,7 @@ export class ConversationSession {
156
80
  * Abort the current running operation
157
81
  */
158
82
  abort() {
159
- this.agentClient.abort();
160
- // Save pending approval context so we can handle it in the next message
161
- if (this.approvalState.abortPending()) {
162
- this.logger.debug('Aborted approval - will handle rejection on next message', {
163
- eventType: 'approval.aborted',
164
- category: 'approval',
165
- phase: 'abort',
166
- sessionId: this.id,
167
- traceId: this.logger.getCorrelationId(),
168
- });
169
- }
83
+ this.approvalFlow.abort();
170
84
  }
171
85
  /**
172
86
  * Phase 4: stream conversation events as an async iterator.
@@ -176,14 +90,14 @@ export class ConversationSession {
176
90
  async *run(text, { hallucinationRetryCount = 0, skipUserMessage = false, } = {}) {
177
91
  let stream = null;
178
92
  try {
179
- this.logger.info('Conversation stream start', {
93
+ this.logger.debug('Conversation stream start', {
180
94
  eventType: 'stream.started',
181
95
  category: 'stream',
182
96
  phase: 'request_start',
183
97
  sessionId: this.id,
184
98
  traceId: this.logger.getCorrelationId(),
185
99
  });
186
- const abortedContext = this.approvalState.consumeAborted();
100
+ const abortedContext = this.approvalFlow.consumeAborted();
187
101
  const shouldAddUserMessage = !skipUserMessage && !abortedContext;
188
102
  // Maintain canonical local history regardless of provider.
189
103
  if (shouldAddUserMessage) {
@@ -195,56 +109,39 @@ export class ConversationSession {
195
109
  this.logger.debug('Resolving aborted approval with fake execution', {
196
110
  message: text,
197
111
  });
198
- const { state, interruption, emittedCommandIds, toolCallArgumentsById } = abortedContext;
199
- const interruptionRecord = asRecord(interruption);
200
112
  // Restore cached tool-call arguments captured before abort so continuation can attach them
201
113
  this.toolCallArgumentsById.clear();
202
- if (toolCallArgumentsById?.size) {
203
- for (const [key, value] of toolCallArgumentsById.entries()) {
114
+ if (abortedContext.toolCallArgumentsById?.size) {
115
+ for (const [key, value] of abortedContext.toolCallArgumentsById.entries()) {
204
116
  this.toolCallArgumentsById.set(key, value);
205
117
  }
206
118
  }
207
- // Add interceptor for this tool execution
208
- const toolName = getString(interruptionRecord, 'name') ?? 'unknown';
209
- const expectedCallId = getCallIdFromObject(interruption);
210
- const rejectionMessage = `Tool execution was not approved. User provided new input instead: ${text}`;
211
- const removeInterceptor = this.agentClient.addToolInterceptor(async (name, _params, toolCallId) => {
212
- // Match both tool name and call ID for stricter matching
213
- if (name === toolName && (!expectedCallId || toolCallId === expectedCallId)) {
214
- markToolCallAsApprovalRejection(toolCallId ?? expectedCallId);
215
- return rejectionMessage;
216
- }
217
- return null;
218
- });
219
- const approve = getMethod(state, 'approve');
220
- approve?.call(state, interruption);
119
+ const { removeInterceptor } = this.approvalFlow.prepareAbortResolution(abortedContext, text);
221
120
  try {
222
- const continuedStream = (await this.agentClient.continueRunStream(state, {
121
+ const continuedStream = (await this.agentClient.continueRunStream(abortedContext.state, {
223
122
  previousResponseId: this.previousResponseId,
224
123
  }));
225
- const acc = {
226
- finalOutput: '',
227
- reasoningOutput: '',
228
- emittedCommandIds: new Set(emittedCommandIds),
229
- latestUsage: undefined,
230
- };
231
- yield* this.#streamEvents(continuedStream, acc, {
124
+ const acc = createStreamAccumulator();
125
+ acc.emittedCommandIds = new Set(abortedContext.emittedCommandIds);
126
+ yield* processStreamEvents(continuedStream, acc, {
127
+ toolCallArgumentsById: this.toolCallArgumentsById,
128
+ emittedInvalidToolCallPackets: this.emittedInvalidToolCallPackets,
232
129
  preserveExistingToolArgs: true,
233
- });
130
+ }, { logger: this.logger, sessionId: this.id });
234
131
  this.previousResponseId = continuedStream.lastResponseId ?? null;
235
132
  this.conversationStore.updateFromResult(continuedStream);
236
133
  // Check if another interruption occurred
237
134
  if (continuedStream.interruptions && continuedStream.interruptions.length > 0) {
238
135
  this.logger.warn('Another interruption occurred after fake execution - handling as approval');
239
136
  // Let the normal flow handle this
240
- const result = this.#buildResult(continuedStream, acc.finalOutput, acc.reasoningOutput, acc.emittedCommandIds, acc.latestUsage);
241
- yield this.#toTerminalEvent(result);
137
+ const resolvedResult = yield* this.#buildAndResolve(continuedStream, acc.finalOutput, acc.reasoningOutput, acc.emittedCommandIds, acc.latestUsage);
138
+ yield toTerminalEvent(resolvedResult);
242
139
  return;
243
140
  }
244
141
  // Successfully resolved - agent should now have processed the fake rejection
245
142
  this.logger.debug('Fake execution completed, agent received rejection message');
246
- const result = this.#buildResult(continuedStream, acc.finalOutput, acc.reasoningOutput, acc.emittedCommandIds, acc.latestUsage);
247
- yield this.#toTerminalEvent(result);
143
+ const resolvedResult = yield* this.#buildAndResolve(continuedStream, acc.finalOutput, acc.reasoningOutput, acc.emittedCommandIds, acc.latestUsage);
144
+ yield toTerminalEvent(resolvedResult);
248
145
  return;
249
146
  }
250
147
  catch (error) {
@@ -265,83 +162,57 @@ export class ConversationSession {
265
162
  stream = (await this.agentClient.startStream(supportsChaining ? text : this.conversationStore.getHistory(), {
266
163
  previousResponseId: this.previousResponseId,
267
164
  }));
268
- const acc = {
269
- finalOutput: '',
270
- reasoningOutput: '',
271
- emittedCommandIds: new Set(),
272
- latestUsage: undefined,
273
- };
274
- yield* this.#streamEvents(stream, acc, {
165
+ const acc = createStreamAccumulator();
166
+ yield* processStreamEvents(stream, acc, {
167
+ toolCallArgumentsById: this.toolCallArgumentsById,
168
+ emittedInvalidToolCallPackets: this.emittedInvalidToolCallPackets,
275
169
  preserveExistingToolArgs: false,
276
- });
170
+ }, { logger: this.logger, sessionId: this.id });
277
171
  this.previousResponseId = stream.lastResponseId ?? null;
278
172
  this.conversationStore.updateFromResult(stream);
279
- // Build terminal event (approval_required or final)
280
- const result = this.#buildResult(stream, acc.finalOutput || undefined, acc.reasoningOutput || undefined, acc.emittedCommandIds, acc.latestUsage);
281
- if (result.type === 'approval_required') {
282
- this.logger.info('Tool approval required', {
173
+ const resolvedResult = yield* this.#buildAndResolve(stream, acc.finalOutput || undefined, acc.reasoningOutput || undefined, acc.emittedCommandIds, acc.latestUsage);
174
+ if (resolvedResult.type === 'approval_required') {
175
+ this.logger.debug('Tool approval required', {
283
176
  eventType: 'approval.required',
284
177
  category: 'approval',
285
178
  phase: 'approval',
286
179
  sessionId: this.id,
287
180
  traceId: this.logger.getCorrelationId(),
288
- toolName: result.approval.toolName,
181
+ toolName: resolvedResult.approval.toolName,
289
182
  });
290
- yield this.#toTerminalEvent(result);
183
+ yield toTerminalEvent(resolvedResult);
291
184
  return;
292
185
  }
293
- yield this.#toTerminalEvent(result);
186
+ yield toTerminalEvent(resolvedResult);
294
187
  }
295
188
  catch (error) {
296
- // Handle recoverable model errors (hallucination, parsing error, etc.)
297
- if (isRecoverableModelError(error) && hallucinationRetryCount < MAX_HALLUCINATION_RETRIES) {
298
- const message = error instanceof Error ? error.message : String(error);
299
- const isHallucination = message.toLowerCase().includes('not found');
300
- const isParsingError = message.toLowerCase().includes('parsing tool arguments') || message.toLowerCase().includes('valid json');
301
- const toolName = isHallucination ? message.match(/Tool (\S+) not found/)?.[1] || 'unknown' : 'unknown';
189
+ const streamHistoryLength = Array.isArray(stream?.history) ? stream.history.length : 0;
190
+ const decision = decideRetry(error, hallucinationRetryCount, Boolean(stream), streamHistoryLength);
191
+ if (decision.kind === 'retry') {
302
192
  this.logger.warn('Recoverable model error detected, retrying', {
303
193
  eventType: 'retry.model_error',
304
194
  category: 'retry',
305
195
  phase: 'retry',
306
- toolName,
307
- retryType: isHallucination ? 'hallucination' : isParsingError ? 'parsing_error' : 'behavior',
308
- retryAttempt: hallucinationRetryCount + 1,
309
- attempt: hallucinationRetryCount + 1,
196
+ toolName: decision.logPayload.toolName,
197
+ retryType: decision.logPayload.retryType,
198
+ retryAttempt: decision.attempt,
199
+ attempt: decision.attempt,
310
200
  maxRetries: MAX_HALLUCINATION_RETRIES,
311
201
  sessionId: this.id,
312
202
  traceId: this.logger.getCorrelationId(),
313
- errorMessage: message,
203
+ errorMessage: decision.message,
314
204
  });
315
- yield {
316
- type: 'retry',
317
- toolName: isHallucination ? toolName : 'model',
318
- attempt: hallucinationRetryCount + 1,
319
- maxRetries: MAX_HALLUCINATION_RETRIES,
320
- errorMessage: message,
321
- };
322
- if (stream) {
323
- // Update conversation store with partial results (including the parse error output if it was yielded)
205
+ yield decision.retryEvent;
206
+ if (decision.hadStream && stream) {
324
207
  this.conversationStore.updateFromResult(stream);
325
- // If stream produced no usable history, inject error context so the
326
- // model has explicit feedback about the failure on retry.
327
- const streamHistory = Array.isArray(stream.history) ? stream.history : [];
328
- if (streamHistory.length === 0) {
329
- this.conversationStore.addErrorContext(`[System: Previous attempt failed with error: ${message}. Please retry with corrected output.]`);
208
+ if (decision.shouldInjectErrorContext) {
209
+ this.conversationStore.addErrorContext(decision.errorContextMessage);
330
210
  }
331
- // Retry from current state without re-adding user message
332
- yield* this.run(text, {
333
- hallucinationRetryCount: hallucinationRetryCount + 1,
334
- skipUserMessage: true,
335
- });
336
211
  }
337
212
  else {
338
- // Failed to start stream at all - clean slate retry
339
213
  this.conversationStore.removeLastUserMessage();
340
- yield* this.run(text, {
341
- hallucinationRetryCount: hallucinationRetryCount + 1,
342
- // skipUserMessage defaults to false, so user message is re-added
343
- });
344
214
  }
215
+ yield* this.run(text, decision.nextRunOptions);
345
216
  return;
346
217
  }
347
218
  yield {
@@ -365,58 +236,14 @@ export class ConversationSession {
365
236
  * Named as a string-literal because `continue` is a keyword.
366
237
  */
367
238
  async *['continue']({ answer, rejectionReason, }) {
368
- const pendingApprovalContext = this.approvalState.getPending();
369
- if (!pendingApprovalContext) {
239
+ const plan = this.approvalFlow.prepareContinuation(answer, rejectionReason);
240
+ if (!plan) {
370
241
  return;
371
242
  }
372
- const { state, interruption, emittedCommandIds: previouslyEmittedIds, toolCallArgumentsById, } = pendingApprovalContext;
373
- const interruptionRecord = asRecord(interruption);
374
- let removeInterceptor = null;
375
- if (answer === 'y') {
376
- this.logger.info('Tool approval granted', {
377
- eventType: 'approval.granted',
378
- category: 'approval',
379
- phase: 'approval',
380
- sessionId: this.id,
381
- traceId: this.logger.getCorrelationId(),
382
- });
383
- const approve = getMethod(state, 'approve');
384
- approve?.call(state, interruption);
385
- }
386
- else {
387
- const toolName = getString(interruptionRecord, 'name') ?? 'unknown';
388
- const expectedCallId = getCallIdFromObject(interruption);
389
- const rejectionMessage = rejectionReason
390
- ? `Tool execution was not approved. User's reason: ${rejectionReason}`
391
- : 'Tool execution was not approved.';
392
- if (typeof this.agentClient.addToolInterceptor === 'function') {
393
- const removeInterceptor = this.agentClient.addToolInterceptor(async (name, _params, toolCallId) => {
394
- if (name === toolName && (!expectedCallId || toolCallId === expectedCallId)) {
395
- markToolCallAsApprovalRejection(toolCallId ?? expectedCallId);
396
- return rejectionMessage;
397
- }
398
- return null;
399
- });
400
- // Approve to continue but interceptor will return rejection message
401
- const approve = getMethod(state, 'approve');
402
- approve?.call(state, interruption);
403
- // Store interceptor cleanup for after stream
404
- this.approvalState.setPendingRemoveInterceptor(removeInterceptor);
405
- }
406
- else {
407
- // Fallback for clients without tool interceptors
408
- const reject = getMethod(state, 'reject');
409
- reject?.call(state, interruption);
410
- }
411
- this.logger.info('Tool approval rejected', {
412
- eventType: 'approval.rejected',
413
- category: 'approval',
414
- phase: 'approval',
415
- sessionId: this.id,
416
- traceId: this.logger.getCorrelationId(),
417
- });
243
+ const { pendingApprovalContext: { state, toolCallArgumentsById, emittedCommandIds: previouslyEmittedIds }, toolStartedEvent, removeInterceptor, } = plan;
244
+ if (toolStartedEvent) {
245
+ yield toolStartedEvent;
418
246
  }
419
- removeInterceptor = this.approvalState.getPending()?.removeInterceptor ?? null;
420
247
  // Restore cached tool-call arguments so continuation outputs can attach them
421
248
  this.toolCallArgumentsById.clear();
422
249
  if (toolCallArgumentsById?.size) {
@@ -428,34 +255,31 @@ export class ConversationSession {
428
255
  const stream = (await this.agentClient.continueRunStream(state, {
429
256
  previousResponseId: this.previousResponseId,
430
257
  }));
431
- const acc = {
432
- finalOutput: '',
433
- reasoningOutput: '',
434
- emittedCommandIds: new Set(),
435
- latestUsage: undefined,
436
- };
437
- yield* this.#streamEvents(stream, acc, {
258
+ const acc = createStreamAccumulator();
259
+ yield* processStreamEvents(stream, acc, {
260
+ toolCallArgumentsById: this.toolCallArgumentsById,
261
+ emittedInvalidToolCallPackets: this.emittedInvalidToolCallPackets,
438
262
  preserveExistingToolArgs: true,
439
- });
263
+ }, { logger: this.logger, sessionId: this.id });
440
264
  this.previousResponseId = stream.lastResponseId ?? null;
441
265
  this.conversationStore.updateFromResult(stream);
442
266
  // Merge previously emitted command IDs with newly emitted ones
443
267
  // This prevents duplicates when result.history contains commands from the initial stream
444
268
  const allEmittedIds = new Set([...previouslyEmittedIds, ...acc.emittedCommandIds]);
445
- const result = this.#buildResult(stream, acc.finalOutput || undefined, acc.reasoningOutput || undefined, allEmittedIds, acc.latestUsage);
446
- if (result.type === 'approval_required') {
447
- this.logger.info('Tool approval required', {
269
+ const resolvedResult = yield* this.#buildAndResolve(stream, acc.finalOutput || undefined, acc.reasoningOutput || undefined, allEmittedIds, acc.latestUsage);
270
+ if (resolvedResult.type === 'approval_required') {
271
+ this.logger.debug('Tool approval required', {
448
272
  eventType: 'approval.required',
449
273
  category: 'approval',
450
274
  phase: 'approval',
451
275
  sessionId: this.id,
452
276
  traceId: this.logger.getCorrelationId(),
453
- toolName: result.approval.toolName,
277
+ toolName: resolvedResult.approval.toolName,
454
278
  });
455
- yield this.#toTerminalEvent(result);
279
+ yield toTerminalEvent(resolvedResult);
456
280
  return;
457
281
  }
458
- yield this.#toTerminalEvent(result);
282
+ yield toTerminalEvent(resolvedResult);
459
283
  }
460
284
  catch (error) {
461
285
  yield {
@@ -466,468 +290,112 @@ export class ConversationSession {
466
290
  }
467
291
  finally {
468
292
  // Clean up interceptor if one was added for rejection reason
469
- removeInterceptor?.();
293
+ removeInterceptor();
470
294
  }
471
295
  }
472
296
  async sendMessage(text, { onTextChunk, onReasoningChunk, onCommandMessage, onEvent, hallucinationRetryCount = 0, } = {}) {
473
- let finalText = '';
474
- let reasoningText = '';
475
- const commandMessages = [];
476
- let usage;
477
- let sawTerminalEvent = null;
478
- for await (const event of this.run(text, { hallucinationRetryCount })) {
479
- onEvent?.(event);
480
- switch (event.type) {
481
- case 'text_delta': {
482
- const full = event.fullText ?? '';
483
- onTextChunk?.(full, event.delta);
484
- break;
485
- }
486
- case 'reasoning_delta': {
487
- const full = event.fullText ?? '';
488
- onReasoningChunk?.(full, event.delta);
489
- break;
490
- }
491
- case 'command_message': {
492
- onCommandMessage?.(event.message);
493
- break;
494
- }
495
- case 'approval_required': {
496
- sawTerminalEvent = event;
497
- // pendingApprovalContext is set inside #buildResult during run()
498
- const rawInterruption = this.approvalState.getPending()?.interruption;
499
- return {
500
- type: 'approval_required',
501
- approval: {
502
- agentName: event.approval.agentName,
503
- toolName: event.approval.toolName,
504
- argumentsText: event.approval.argumentsText,
505
- rawInterruption,
506
- callId: event.approval.callId,
507
- },
508
- };
509
- }
510
- case 'final': {
511
- sawTerminalEvent = event;
512
- finalText = event.finalText;
513
- reasoningText = event.reasoningText ?? '';
514
- usage = event.usage;
515
- this.logger.debug('sendMessage received final event', {
516
- sessionId: this.id,
517
- hasUsage: Boolean(event.usage),
518
- usage: event.usage,
519
- });
520
- if (event.commandMessages?.length) {
521
- for (const msg of event.commandMessages) {
522
- commandMessages.push(msg);
523
- }
524
- }
525
- break;
526
- }
527
- case 'error': {
528
- // Preserve legacy behavior (throwing) by throwing after the stream ends.
529
- break;
530
- }
531
- default:
532
- break;
533
- }
534
- }
535
- // If we didn't see a terminal event, fall back to the legacy default.
536
- if (!sawTerminalEvent) {
537
- finalText = finalText || 'Done.';
538
- }
539
- const response = {
540
- type: 'response',
541
- commandMessages,
542
- finalText: finalText || 'Done.',
543
- ...(reasoningText ? { reasoningText } : {}),
544
- ...(usage ? { usage } : {}),
545
- };
546
- this.logger.debug('sendMessage returning response', {
547
- sessionId: this.id,
548
- hasUsage: Boolean(usage),
549
- usage,
297
+ const result = await collectTerminalResult(this.run(text, { hallucinationRetryCount }), {
298
+ onTextChunk,
299
+ onReasoningChunk,
300
+ onCommandMessage,
301
+ onEvent,
302
+ getRawInterruption: () => this.approvalFlow.getPendingInterruption(),
303
+ onFinalEvent: (event) => {
304
+ this.logger.debug('sendMessage received final event', {
305
+ sessionId: this.id,
306
+ hasUsage: Boolean(event.usage),
307
+ usage: event.usage,
308
+ });
309
+ },
550
310
  });
551
- return response;
311
+ if (result.type === 'response') {
312
+ this.logger.debug('sendMessage returning response', {
313
+ sessionId: this.id,
314
+ hasUsage: Boolean(result.usage),
315
+ usage: result.usage,
316
+ });
317
+ }
318
+ return result;
552
319
  }
553
320
  async handleApprovalDecision(answer, rejectionReason, { onTextChunk, onReasoningChunk, onCommandMessage, onEvent, } = {}) {
554
- if (!this.approvalState.getPending()) {
321
+ if (!this.approvalFlow.getPending()) {
555
322
  return null;
556
323
  }
557
- let finalText = '';
558
- let reasoningText = '';
559
- const commandMessages = [];
560
- let usage;
561
- let sawTerminalEvent = null;
562
- for await (const event of this['continue']({ answer, rejectionReason })) {
563
- onEvent?.(event);
564
- switch (event.type) {
565
- case 'text_delta': {
566
- const full = event.fullText ?? '';
567
- onTextChunk?.(full, event.delta);
568
- break;
569
- }
570
- case 'reasoning_delta': {
571
- const full = event.fullText ?? '';
572
- onReasoningChunk?.(full, event.delta);
573
- break;
574
- }
575
- case 'command_message': {
576
- onCommandMessage?.(event.message);
577
- break;
578
- }
579
- case 'approval_required': {
580
- sawTerminalEvent = event;
581
- const rawInterruption = this.approvalState.getPending()?.interruption;
582
- return {
583
- type: 'approval_required',
584
- approval: {
585
- agentName: event.approval.agentName,
586
- toolName: event.approval.toolName,
587
- argumentsText: event.approval.argumentsText,
588
- rawInterruption,
589
- callId: event.approval.callId,
590
- },
591
- };
592
- }
593
- case 'final': {
594
- sawTerminalEvent = event;
595
- finalText = event.finalText;
596
- reasoningText = event.reasoningText ?? '';
597
- usage = event.usage;
598
- this.logger.debug('handleApprovalDecision received final event', {
599
- sessionId: this.id,
600
- hasUsage: Boolean(event.usage),
601
- usage: event.usage,
602
- });
603
- if (event.commandMessages?.length) {
604
- for (const msg of event.commandMessages) {
605
- commandMessages.push(msg);
606
- }
607
- }
608
- break;
609
- }
610
- case 'error': {
611
- break;
612
- }
613
- default:
614
- break;
615
- }
616
- }
617
- if (!sawTerminalEvent) {
618
- const response = {
619
- type: 'response',
620
- commandMessages,
621
- finalText: finalText || 'Done.',
622
- ...(reasoningText ? { reasoningText } : {}),
623
- ...(usage ? { usage } : {}),
624
- };
324
+ const result = await collectTerminalResult(this['continue']({ answer, rejectionReason }), {
325
+ onTextChunk,
326
+ onReasoningChunk,
327
+ onCommandMessage,
328
+ onEvent,
329
+ getRawInterruption: () => this.approvalFlow.getPendingInterruption(),
330
+ onFinalEvent: (event) => {
331
+ this.logger.debug('handleApprovalDecision received final event', {
332
+ sessionId: this.id,
333
+ hasUsage: Boolean(event.usage),
334
+ usage: event.usage,
335
+ });
336
+ },
337
+ });
338
+ if (result.type === 'response') {
625
339
  this.logger.debug('handleApprovalDecision returning response', {
626
340
  sessionId: this.id,
627
- hasUsage: Boolean(usage),
628
- usage,
341
+ hasUsage: Boolean(result.usage),
342
+ usage: result.usage,
629
343
  });
630
- return response;
631
344
  }
632
- const response = {
633
- type: 'response',
634
- commandMessages,
635
- finalText: finalText || 'Done.',
636
- ...(reasoningText ? { reasoningText } : {}),
637
- ...(usage ? { usage } : {}),
638
- };
639
- this.logger.debug('handleApprovalDecision returning response', {
640
- sessionId: this.id,
641
- hasUsage: Boolean(usage),
345
+ return result;
346
+ }
347
+ async *#buildAndResolve(result, finalOutputOverride, reasoningOutputOverride, emittedCommandIds, usage) {
348
+ const outcome = await buildConversationResult({
349
+ result,
350
+ finalOutputOverride,
351
+ reasoningOutputOverride,
352
+ emittedCommandIds,
642
353
  usage,
354
+ toolCallArgumentsById: this.toolCallArgumentsById,
355
+ }, {
356
+ approvalFlow: this.approvalFlow,
357
+ shellAutoApproval: this.shellAutoApproval,
358
+ logger: this.logger,
359
+ sessionId: this.id,
643
360
  });
644
- return response;
645
- }
646
- async *#streamEvents(stream, acc, { preserveExistingToolArgs }) {
647
- const toolCallArgumentsById = this.toolCallArgumentsById;
648
- if (!preserveExistingToolArgs) {
649
- toolCallArgumentsById.clear();
361
+ if (outcome.kind !== 'auto_approve') {
362
+ return outcome.result;
650
363
  }
651
- this.textDeltaCount = 0;
652
- this.reasoningDeltaCount = 0;
653
- const emitText = (delta) => {
654
- if (!delta) {
655
- return null;
656
- }
657
- acc.finalOutput += delta;
658
- this.textDeltaCount++;
659
- return {
660
- type: 'text_delta',
661
- delta,
662
- fullText: acc.finalOutput,
663
- };
664
- };
665
- const emitReasoning = (delta) => {
666
- if (!delta || delta.replaceAll('\n', '') === '') {
667
- return null;
668
- }
669
- acc.reasoningOutput += delta;
670
- this.reasoningDeltaCount++;
671
- return {
672
- type: 'reasoning_delta',
673
- delta,
674
- fullText: acc.reasoningOutput,
675
- };
676
- };
677
- for await (const rawEvent of stream) {
678
- const event = asRecord(rawEvent);
679
- const eventData = asRecord(event?.data);
680
- const eventType = getString(event, 'type');
681
- // Extract usage if present in any of the common locations.
682
- // Check both the top-level event and event.data, since raw_model_stream_event
683
- // nests response data (including usage) under .data (e.g. data.response.usage).
684
- const usage = extractUsage(rawEvent) ?? (eventData ? extractUsage(eventData) : undefined);
685
- if (usage) {
686
- acc.latestUsage = usage;
687
- this.logger.debug('Usage extracted from stream event', {
688
- sessionId: this.id,
689
- source: 'stream_event',
690
- eventType: eventType ?? getString(eventData, 'type') ?? 'unknown',
691
- usage,
692
- });
693
- // Emit usage update event for real-time token tracking
694
- yield {
695
- type: 'usage_update',
696
- usage,
364
+ let finalText = '';
365
+ let reasoningText = '';
366
+ let finalUsage;
367
+ const commandMessages = [];
368
+ let approvalRequiredResult;
369
+ for await (const event of this['continue']({ answer: 'y' })) {
370
+ yield event;
371
+ if (event.type === 'approval_required') {
372
+ approvalRequiredResult = {
373
+ type: 'approval_required',
374
+ approval: {
375
+ ...event.approval,
376
+ rawInterruption: this.approvalFlow.getPendingInterruption(),
377
+ },
697
378
  };
698
379
  }
699
- // Log event type with deduplication for ordering understanding
700
- const delta1 = extractTextDelta(rawEvent);
701
- if (delta1) {
702
- const e = emitText(delta1);
703
- if (e)
704
- yield e;
705
- }
706
- if (eventData) {
707
- const delta2 = extractTextDelta(eventData);
708
- if (delta2) {
709
- const e = emitText(delta2);
710
- if (e)
711
- yield e;
712
- }
713
- }
714
- // Handle reasoning items
715
- const reasoningDelta = extractReasoningDelta(rawEvent);
716
- if (reasoningDelta) {
717
- const e = emitReasoning(reasoningDelta);
718
- if (e)
719
- yield e;
720
- }
721
- const maybeEmitCommandMessagesFromItems = (items) => emitCommandMessagesFromItems(items, {
722
- toolCallArgumentsById,
723
- emittedCommandIds: acc.emittedCommandIds,
724
- });
725
- if (eventType === 'run_item_stream_event') {
726
- const eventItem = event?.item;
727
- const eventItemRecord = asRecord(eventItem);
728
- captureToolCallArguments(eventItem, toolCallArgumentsById);
729
- // Emit tool_started event when a function_call is detected
730
- const rawItem = asRecord(eventItemRecord?.rawItem) ?? eventItemRecord;
731
- if (getString(rawItem, 'type') === 'function_call') {
732
- const callId = getString(rawItem, 'callId') ??
733
- getString(rawItem, 'call_id') ??
734
- getString(rawItem, 'tool_call_id') ??
735
- getString(rawItem, 'toolCallId') ??
736
- getString(rawItem, 'id');
737
- if (callId) {
738
- const toolName = getString(rawItem, 'name') ?? getString(eventItemRecord, 'name');
739
- const args = rawItem?.arguments ?? rawItem?.args ?? eventItemRecord?.arguments ?? eventItemRecord?.args;
740
- // Providers sometimes surface arguments as a JSON string.
741
- // Normalize here so downstream UI (pending/running display)
742
- // can reliably render parameters.
743
- const normalizedArgs = (() => {
744
- if (typeof args !== 'string') {
745
- return args;
746
- }
747
- const trimmed = args.trim();
748
- if (!trimmed) {
749
- return args;
750
- }
751
- try {
752
- return JSON.parse(trimmed);
753
- }
754
- catch {
755
- if ((trimmed.startsWith('{') || trimmed.startsWith('[')) &&
756
- !this.emittedInvalidToolCallPackets.has(String(callId))) {
757
- this.emittedInvalidToolCallPackets.add(String(callId));
758
- const diagnostic = createInvalidToolCallDiagnostic({
759
- toolName: toolName ?? 'unknown',
760
- toolCallId: String(callId),
761
- rawPayload: trimmed,
762
- normalizedToolCall: {
763
- toolName: toolName ?? 'unknown',
764
- toolCallId: String(callId),
765
- arguments: args,
766
- },
767
- validationErrors: ['arguments must be valid JSON'],
768
- traceId: this.logger.getCorrelationId() ?? 'trace-unknown',
769
- retryContext: {
770
- sessionId: this.id,
771
- },
772
- });
773
- this.logger.error('Invalid tool call argument payload', {
774
- ...diagnostic,
775
- sessionId: this.id,
776
- messageId: String(callId),
777
- });
778
- }
779
- return args;
780
- }
781
- })();
782
- yield {
783
- type: 'tool_started',
784
- toolCallId: callId,
785
- toolName: toolName ?? 'unknown',
786
- arguments: normalizedArgs,
787
- };
788
- this.logger.info('Tool execution started', {
789
- eventType: 'tool_call.execution_started',
790
- category: 'tool',
791
- phase: 'execution',
792
- sessionId: this.id,
793
- traceId: this.logger.getCorrelationId(),
794
- toolName: toolName ?? 'unknown',
795
- toolCallId: String(callId),
796
- messageId: String(callId),
797
- });
798
- }
799
- }
800
- for (const e of maybeEmitCommandMessagesFromItems([eventItem])) {
801
- yield e;
802
- }
803
- }
804
- else if (eventType === 'tool_call_output_item' ||
805
- getString(asRecord(event?.rawItem), 'type') === 'function_call_output') {
806
- captureToolCallArguments(rawEvent, toolCallArgumentsById);
807
- for (const e of maybeEmitCommandMessagesFromItems([rawEvent])) {
808
- yield e;
380
+ else if (event.type === 'final') {
381
+ finalText = event.finalText;
382
+ reasoningText = event.reasoningText ?? '';
383
+ finalUsage = event.usage;
384
+ if (event.commandMessages) {
385
+ commandMessages.push(...event.commandMessages);
809
386
  }
810
387
  }
811
388
  }
812
- const completedResult = await stream.completed;
813
- const rawResponses = Array.isArray(stream?.rawResponses) ? stream.rawResponses : [];
814
- let usageFromRawResponses;
815
- for (let i = rawResponses.length - 1; i >= 0; i--) {
816
- const candidate = extractUsage(rawResponses[i]);
817
- if (candidate) {
818
- usageFromRawResponses = candidate;
819
- break;
820
- }
821
- }
822
- const finalUsage = extractUsage(completedResult) || extractUsage(stream) || usageFromRawResponses;
823
- if (finalUsage) {
824
- acc.latestUsage = finalUsage;
825
- const usageSource = extractUsage(completedResult)
826
- ? 'completed_result'
827
- : extractUsage(stream)
828
- ? 'stream_object'
829
- : 'stream_raw_responses';
830
- this.logger.debug('Usage extracted from stream completion', {
831
- sessionId: this.id,
832
- source: 'stream_completed',
833
- usageSource,
834
- usage: finalUsage,
835
- });
836
- }
837
- else {
838
- const completedResultRecord = completedResult && typeof completedResult === 'object' && !Array.isArray(completedResult)
839
- ? completedResult
840
- : undefined;
841
- const streamRecord = stream && typeof stream === 'object' && !Array.isArray(stream)
842
- ? stream
843
- : undefined;
844
- this.logger.debug('No usage found in stream completion', {
845
- sessionId: this.id,
846
- source: 'stream_completed',
847
- completedResultType: completedResult === null ? 'null' : Array.isArray(completedResult) ? 'array' : typeof completedResult,
848
- completedResultKeys: completedResultRecord ? Object.keys(completedResultRecord) : [],
849
- streamKeys: streamRecord ? Object.keys(streamRecord) : [],
850
- completedResultHasUsagePath: {
851
- usage: Boolean(completedResultRecord?.usage),
852
- usageMetadata: Boolean(completedResultRecord?.usageMetadata),
853
- usage_metadata: Boolean(completedResultRecord?.usage_metadata),
854
- responseUsage: Boolean(asRecord(completedResultRecord?.response)?.usage),
855
- },
856
- });
857
- }
858
- }
859
- #toTerminalEvent(result) {
860
- if (result.type === 'approval_required') {
861
- return {
862
- type: 'approval_required',
863
- approval: {
864
- agentName: result.approval.agentName,
865
- toolName: result.approval.toolName,
866
- argumentsText: result.approval.argumentsText,
867
- ...(result.approval.callId ? { callId: result.approval.callId } : {}),
868
- },
869
- };
389
+ if (approvalRequiredResult) {
390
+ return approvalRequiredResult;
870
391
  }
871
392
  return {
872
- type: 'final',
873
- finalText: result.finalText,
874
- ...(result.reasoningText ? { reasoningText: result.reasoningText } : {}),
875
- ...(result.commandMessages?.length ? { commandMessages: result.commandMessages } : {}),
876
- ...(result.usage ? { usage: result.usage } : {}),
877
- };
878
- }
879
- #buildResult(result, finalOutputOverride, reasoningOutputOverride, emittedCommandIds, usage) {
880
- if (result.interruptions && result.interruptions.length > 0) {
881
- const interruption = result.interruptions[0];
882
- this.approvalState.setPending({
883
- state: result.state,
884
- interruption,
885
- emittedCommandIds: emittedCommandIds ?? new Set(),
886
- toolCallArgumentsById: new Map(this.toolCallArgumentsById),
887
- });
888
- let argumentsText = '';
889
- const interruptionRecord = asRecord(interruption);
890
- const toolName = getString(interruptionRecord, 'name');
891
- // For shell_call (built-in shell tool), extract commands from action
892
- // For function tools (bash, shell), extract from arguments
893
- if (getString(interruptionRecord, 'type') === 'shell_call') {
894
- const action = asRecord(interruptionRecord?.action);
895
- const actionCommands = action?.commands;
896
- if (actionCommands) {
897
- argumentsText = Array.isArray(actionCommands) ? actionCommands.join('\n') : String(actionCommands);
898
- }
899
- }
900
- else {
901
- argumentsText = getCommandFromArgs(interruptionRecord?.arguments);
902
- }
903
- const agent = asRecord(interruptionRecord?.agent);
904
- const callId = getCallIdFromObject(interruption);
905
- return {
906
- type: 'approval_required',
907
- approval: {
908
- agentName: getString(agent, 'name') ?? 'Agent',
909
- toolName: toolName ?? 'Unknown Tool',
910
- argumentsText,
911
- rawInterruption: interruption,
912
- ...(callId ? { callId: String(callId) } : {}),
913
- },
914
- };
915
- }
916
- this.approvalState.clearPending();
917
- const allCommandMessages = extractCommandMessages(result.newItems || result.history || []);
918
- // Filter out commands that were already emitted in real-time
919
- const commandMessages = emittedCommandIds
920
- ? allCommandMessages.filter((msg) => !emittedCommandIds.has(msg.id))
921
- : allCommandMessages;
922
- const visibleCommandMessages = commandMessages.filter((msg) => !msg.isApprovalRejection);
923
- const response = {
924
393
  type: 'response',
925
- commandMessages: visibleCommandMessages,
926
- finalText: finalOutputOverride ?? result.finalOutput ?? 'Done.',
927
- reasoningText: reasoningOutputOverride,
928
- usage: usage ?? extractUsage(result),
394
+ commandMessages,
395
+ finalText: finalText || 'Done.',
396
+ ...(reasoningText ? { reasoningText } : {}),
397
+ ...(finalUsage ? { usage: finalUsage } : {}),
929
398
  };
930
- return response;
931
399
  }
932
400
  }
933
401
  //# sourceMappingURL=conversation-session.js.map