@qduc/term2 0.1.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 (621) hide show
  1. package/LICENSE +21 -0
  2. package/dist/agent.d.ts +19 -0
  3. package/dist/agent.d.ts.map +1 -0
  4. package/dist/agent.js +143 -0
  5. package/dist/agent.js.map +1 -0
  6. package/dist/app.d.ts +22 -0
  7. package/dist/app.d.ts.map +1 -0
  8. package/dist/app.js +403 -0
  9. package/dist/app.js.map +1 -0
  10. package/dist/app.model-command-feedback.test.d.ts +2 -0
  11. package/dist/app.model-command-feedback.test.d.ts.map +1 -0
  12. package/dist/app.model-command-feedback.test.js +19 -0
  13. package/dist/app.model-command-feedback.test.js.map +1 -0
  14. package/dist/app.parseInput.test.d.ts +2 -0
  15. package/dist/app.parseInput.test.d.ts.map +1 -0
  16. package/dist/app.parseInput.test.js +97 -0
  17. package/dist/app.parseInput.test.js.map +1 -0
  18. package/dist/cli.d.ts +3 -0
  19. package/dist/cli.d.ts.map +1 -0
  20. package/dist/cli.js +241 -0
  21. package/dist/cli.js.map +1 -0
  22. package/dist/components/ApprovalPrompt.d.ts +10 -0
  23. package/dist/components/ApprovalPrompt.d.ts.map +1 -0
  24. package/dist/components/ApprovalPrompt.js +163 -0
  25. package/dist/components/ApprovalPrompt.js.map +1 -0
  26. package/dist/components/Banner.d.ts +9 -0
  27. package/dist/components/Banner.d.ts.map +1 -0
  28. package/dist/components/Banner.js +86 -0
  29. package/dist/components/Banner.js.map +1 -0
  30. package/dist/components/BottomArea.d.ts +33 -0
  31. package/dist/components/BottomArea.d.ts.map +1 -0
  32. package/dist/components/BottomArea.js +31 -0
  33. package/dist/components/BottomArea.js.map +1 -0
  34. package/dist/components/BottomArea.test.d.ts +2 -0
  35. package/dist/components/BottomArea.test.d.ts.map +1 -0
  36. package/dist/components/BottomArea.test.js +73 -0
  37. package/dist/components/BottomArea.test.js.map +1 -0
  38. package/dist/components/ChatMessage.d.ts +7 -0
  39. package/dist/components/ChatMessage.d.ts.map +1 -0
  40. package/dist/components/ChatMessage.js +10 -0
  41. package/dist/components/ChatMessage.js.map +1 -0
  42. package/dist/components/CommandMessage.d.ts +15 -0
  43. package/dist/components/CommandMessage.d.ts.map +1 -0
  44. package/dist/components/CommandMessage.js +188 -0
  45. package/dist/components/CommandMessage.js.map +1 -0
  46. package/dist/components/CommandMessage.test.d.ts +2 -0
  47. package/dist/components/CommandMessage.test.d.ts.map +1 -0
  48. package/dist/components/CommandMessage.test.js +35 -0
  49. package/dist/components/CommandMessage.test.js.map +1 -0
  50. package/dist/components/ErrorBoundary.d.ts +27 -0
  51. package/dist/components/ErrorBoundary.d.ts.map +1 -0
  52. package/dist/components/ErrorBoundary.js +77 -0
  53. package/dist/components/ErrorBoundary.js.map +1 -0
  54. package/dist/components/ErrorBoundary.test.d.ts +2 -0
  55. package/dist/components/ErrorBoundary.test.d.ts.map +1 -0
  56. package/dist/components/ErrorBoundary.test.js +32 -0
  57. package/dist/components/ErrorBoundary.test.js.map +1 -0
  58. package/dist/components/Input/PopupManager.d.ts +42 -0
  59. package/dist/components/Input/PopupManager.d.ts.map +1 -0
  60. package/dist/components/Input/PopupManager.js +13 -0
  61. package/dist/components/Input/PopupManager.js.map +1 -0
  62. package/dist/components/InputBox.d.ts +18 -0
  63. package/dist/components/InputBox.d.ts.map +1 -0
  64. package/dist/components/InputBox.js +384 -0
  65. package/dist/components/InputBox.js.map +1 -0
  66. package/dist/components/InputBox.menu-logic.test.d.ts +2 -0
  67. package/dist/components/InputBox.menu-logic.test.d.ts.map +1 -0
  68. package/dist/components/InputBox.menu-logic.test.js +151 -0
  69. package/dist/components/InputBox.menu-logic.test.js.map +1 -0
  70. package/dist/components/InputBox.test.d.ts +2 -0
  71. package/dist/components/InputBox.test.d.ts.map +1 -0
  72. package/dist/components/InputBox.test.js +91 -0
  73. package/dist/components/InputBox.test.js.map +1 -0
  74. package/dist/components/LiveResponse.d.ts +13 -0
  75. package/dist/components/LiveResponse.d.ts.map +1 -0
  76. package/dist/components/LiveResponse.js +16 -0
  77. package/dist/components/LiveResponse.js.map +1 -0
  78. package/dist/components/MarkdownRenderer.d.ts +8 -0
  79. package/dist/components/MarkdownRenderer.d.ts.map +1 -0
  80. package/dist/components/MarkdownRenderer.js +225 -0
  81. package/dist/components/MarkdownRenderer.js.map +1 -0
  82. package/dist/components/MentorMode.test.d.ts +2 -0
  83. package/dist/components/MentorMode.test.d.ts.map +1 -0
  84. package/dist/components/MentorMode.test.js.map +1 -0
  85. package/dist/components/MessageList.d.ts +7 -0
  86. package/dist/components/MessageList.d.ts.map +1 -0
  87. package/dist/components/MessageList.js +29 -0
  88. package/dist/components/MessageList.js.map +1 -0
  89. package/dist/components/MessageList.test.d.ts +2 -0
  90. package/dist/components/MessageList.test.d.ts.map +1 -0
  91. package/dist/components/MessageList.test.js +15 -0
  92. package/dist/components/MessageList.test.js.map +1 -0
  93. package/dist/components/ModelSelectionMenu.d.ts +18 -0
  94. package/dist/components/ModelSelectionMenu.d.ts.map +1 -0
  95. package/dist/components/ModelSelectionMenu.js +91 -0
  96. package/dist/components/ModelSelectionMenu.js.map +1 -0
  97. package/dist/components/ModelSelectionMenu.test.d.ts +2 -0
  98. package/dist/components/ModelSelectionMenu.test.d.ts.map +1 -0
  99. package/dist/components/ModelSelectionMenu.test.js +83 -0
  100. package/dist/components/ModelSelectionMenu.test.js.map +1 -0
  101. package/dist/components/PathSelectionMenu.d.ts +12 -0
  102. package/dist/components/PathSelectionMenu.d.ts.map +1 -0
  103. package/dist/components/PathSelectionMenu.js +42 -0
  104. package/dist/components/PathSelectionMenu.js.map +1 -0
  105. package/dist/components/SettingsSelectionMenu.d.ts +9 -0
  106. package/dist/components/SettingsSelectionMenu.d.ts.map +1 -0
  107. package/dist/components/SettingsSelectionMenu.js +21 -0
  108. package/dist/components/SettingsSelectionMenu.js.map +1 -0
  109. package/dist/components/SlashCommandMenu.d.ts +15 -0
  110. package/dist/components/SlashCommandMenu.d.ts.map +1 -0
  111. package/dist/components/SlashCommandMenu.js +20 -0
  112. package/dist/components/SlashCommandMenu.js.map +1 -0
  113. package/dist/components/StatusBar.d.ts +11 -0
  114. package/dist/components/StatusBar.d.ts.map +1 -0
  115. package/dist/components/StatusBar.js +59 -0
  116. package/dist/components/StatusBar.js.map +1 -0
  117. package/dist/components/TextInput.d.ts +42 -0
  118. package/dist/components/TextInput.d.ts.map +1 -0
  119. package/dist/components/TextInput.js +397 -0
  120. package/dist/components/TextInput.js.map +1 -0
  121. package/dist/components/TextInput.test.d.ts +2 -0
  122. package/dist/components/TextInput.test.d.ts.map +1 -0
  123. package/dist/components/TextInput.test.js +75 -0
  124. package/dist/components/TextInput.test.js.map +1 -0
  125. package/dist/context/InputContext.d.ts +31 -0
  126. package/dist/context/InputContext.d.ts.map +1 -0
  127. package/dist/context/InputContext.js +36 -0
  128. package/dist/context/InputContext.js.map +1 -0
  129. package/dist/context/InputContext.stability.test.d.ts +2 -0
  130. package/dist/context/InputContext.stability.test.d.ts.map +1 -0
  131. package/dist/context/InputContext.stability.test.js +28 -0
  132. package/dist/context/InputContext.stability.test.js.map +1 -0
  133. package/dist/context/InputContext.test.d.ts +2 -0
  134. package/dist/context/InputContext.test.d.ts.map +1 -0
  135. package/dist/context/InputContext.test.js +168 -0
  136. package/dist/context/InputContext.test.js.map +1 -0
  137. package/dist/debug-schema.d.ts +2 -0
  138. package/dist/debug-schema.d.ts.map +1 -0
  139. package/dist/debug-schema.js +22 -0
  140. package/dist/debug-schema.js.map +1 -0
  141. package/dist/hooks/use-conversation.d.ts +78 -0
  142. package/dist/hooks/use-conversation.d.ts.map +1 -0
  143. package/dist/hooks/use-conversation.js +1017 -0
  144. package/dist/hooks/use-conversation.js.map +1 -0
  145. package/dist/hooks/use-input-history.d.ts +16 -0
  146. package/dist/hooks/use-input-history.d.ts.map +1 -0
  147. package/dist/hooks/use-input-history.js +71 -0
  148. package/dist/hooks/use-input-history.js.map +1 -0
  149. package/dist/hooks/use-model-selection.d.ts +27 -0
  150. package/dist/hooks/use-model-selection.d.ts.map +1 -0
  151. package/dist/hooks/use-model-selection.js +187 -0
  152. package/dist/hooks/use-model-selection.js.map +1 -0
  153. package/dist/hooks/use-model-selection.test.d.ts +2 -0
  154. package/dist/hooks/use-model-selection.test.d.ts.map +1 -0
  155. package/dist/hooks/use-model-selection.test.js +28 -0
  156. package/dist/hooks/use-model-selection.test.js.map +1 -0
  157. package/dist/hooks/use-path-completion.d.ts +22 -0
  158. package/dist/hooks/use-path-completion.d.ts.map +1 -0
  159. package/dist/hooks/use-path-completion.js +153 -0
  160. package/dist/hooks/use-path-completion.js.map +1 -0
  161. package/dist/hooks/use-path-completion.test.d.ts +2 -0
  162. package/dist/hooks/use-path-completion.test.d.ts.map +1 -0
  163. package/dist/hooks/use-path-completion.test.js +29 -0
  164. package/dist/hooks/use-path-completion.test.js.map +1 -0
  165. package/dist/hooks/use-setting.d.ts +7 -0
  166. package/dist/hooks/use-setting.d.ts.map +1 -0
  167. package/dist/hooks/use-setting.js +35 -0
  168. package/dist/hooks/use-setting.js.map +1 -0
  169. package/dist/hooks/use-settings-completion.d.ts +23 -0
  170. package/dist/hooks/use-settings-completion.d.ts.map +1 -0
  171. package/dist/hooks/use-settings-completion.js +164 -0
  172. package/dist/hooks/use-settings-completion.js.map +1 -0
  173. package/dist/hooks/use-settings-completion.test.d.ts +2 -0
  174. package/dist/hooks/use-settings-completion.test.d.ts.map +1 -0
  175. package/dist/hooks/use-settings-completion.test.js +334 -0
  176. package/dist/hooks/use-settings-completion.test.js.map +1 -0
  177. package/dist/hooks/use-slash-commands.d.ts +21 -0
  178. package/dist/hooks/use-slash-commands.d.ts.map +1 -0
  179. package/dist/hooks/use-slash-commands.js +87 -0
  180. package/dist/hooks/use-slash-commands.js.map +1 -0
  181. package/dist/hooks/use-slash-commands.test.d.ts +2 -0
  182. package/dist/hooks/use-slash-commands.test.d.ts.map +1 -0
  183. package/dist/hooks/use-slash-commands.test.js +246 -0
  184. package/dist/hooks/use-slash-commands.test.js.map +1 -0
  185. package/dist/lib/editor-impl.d.ts +23 -0
  186. package/dist/lib/editor-impl.d.ts.map +1 -0
  187. package/dist/lib/editor-impl.js +235 -0
  188. package/dist/lib/editor-impl.js.map +1 -0
  189. package/dist/lib/openai-agent-client.chat.test.d.ts +2 -0
  190. package/dist/lib/openai-agent-client.chat.test.d.ts.map +1 -0
  191. package/dist/lib/openai-agent-client.chat.test.js +68 -0
  192. package/dist/lib/openai-agent-client.chat.test.js.map +1 -0
  193. package/dist/lib/openai-agent-client.d.ts +48 -0
  194. package/dist/lib/openai-agent-client.d.ts.map +1 -0
  195. package/dist/lib/openai-agent-client.js +653 -0
  196. package/dist/lib/openai-agent-client.js.map +1 -0
  197. package/dist/lib/openai-agent-client.test.d.ts +2 -0
  198. package/dist/lib/openai-agent-client.test.d.ts.map +1 -0
  199. package/dist/lib/openai-agent-client.test.js +181 -0
  200. package/dist/lib/openai-agent-client.test.js.map +1 -0
  201. package/dist/lib/shell.d.ts +7 -0
  202. package/dist/lib/shell.d.ts.map +1 -0
  203. package/dist/lib/shell.js +56 -0
  204. package/dist/lib/shell.js.map +1 -0
  205. package/dist/lib/tool-invoke.d.ts +4 -0
  206. package/dist/lib/tool-invoke.d.ts.map +1 -0
  207. package/dist/lib/tool-invoke.js +26 -0
  208. package/dist/lib/tool-invoke.js.map +1 -0
  209. package/dist/lib/tool-invoke.test.d.ts +2 -0
  210. package/dist/lib/tool-invoke.test.d.ts.map +1 -0
  211. package/dist/lib/tool-invoke.test.js +19 -0
  212. package/dist/lib/tool-invoke.test.js.map +1 -0
  213. package/dist/no-singleton-imports.test.d.ts +2 -0
  214. package/dist/no-singleton-imports.test.d.ts.map +1 -0
  215. package/dist/no-singleton-imports.test.js +30 -0
  216. package/dist/no-singleton-imports.test.js.map +1 -0
  217. package/dist/prompts/anthropic.md +79 -0
  218. package/dist/prompts/codex.md +97 -0
  219. package/dist/prompts/default.md +77 -0
  220. package/dist/prompts/default.md.bak +77 -0
  221. package/dist/prompts/gpt-5.md +318 -0
  222. package/dist/prompts/lite.md +29 -0
  223. package/dist/prompts/simple-mentor.md +207 -0
  224. package/dist/prompts/simple.md +189 -0
  225. package/dist/providers/index.d.ts +5 -0
  226. package/dist/providers/index.d.ts.map +1 -0
  227. package/dist/providers/index.js +8 -0
  228. package/dist/providers/index.js.map +1 -0
  229. package/dist/providers/openai-compatible/api.d.ts +17 -0
  230. package/dist/providers/openai-compatible/api.d.ts.map +1 -0
  231. package/dist/providers/openai-compatible/api.js +58 -0
  232. package/dist/providers/openai-compatible/api.js.map +1 -0
  233. package/dist/providers/openai-compatible/model.d.ts +17 -0
  234. package/dist/providers/openai-compatible/model.d.ts.map +1 -0
  235. package/dist/providers/openai-compatible/model.js +435 -0
  236. package/dist/providers/openai-compatible/model.js.map +1 -0
  237. package/dist/providers/openai-compatible/provider.d.ts +22 -0
  238. package/dist/providers/openai-compatible/provider.d.ts.map +1 -0
  239. package/dist/providers/openai-compatible/provider.js +43 -0
  240. package/dist/providers/openai-compatible/provider.js.map +1 -0
  241. package/dist/providers/openai-compatible/utils.d.ts +3 -0
  242. package/dist/providers/openai-compatible/utils.d.ts.map +1 -0
  243. package/dist/providers/openai-compatible/utils.js +11 -0
  244. package/dist/providers/openai-compatible/utils.js.map +1 -0
  245. package/dist/providers/openai-compatible.provider.d.ts +8 -0
  246. package/dist/providers/openai-compatible.provider.d.ts.map +1 -0
  247. package/dist/providers/openai-compatible.provider.js +71 -0
  248. package/dist/providers/openai-compatible.provider.js.map +1 -0
  249. package/dist/providers/openai.provider.d.ts +2 -0
  250. package/dist/providers/openai.provider.d.ts.map +1 -0
  251. package/dist/providers/openai.provider.js +36 -0
  252. package/dist/providers/openai.provider.js.map +1 -0
  253. package/dist/providers/openrouter/api.d.ts +39 -0
  254. package/dist/providers/openrouter/api.d.ts.map +1 -0
  255. package/dist/providers/openrouter/api.js +172 -0
  256. package/dist/providers/openrouter/api.js.map +1 -0
  257. package/dist/providers/openrouter/converters.d.ts +8 -0
  258. package/dist/providers/openrouter/converters.d.ts.map +1 -0
  259. package/dist/providers/openrouter/converters.js +382 -0
  260. package/dist/providers/openrouter/converters.js.map +1 -0
  261. package/dist/providers/openrouter/converters.test.d.ts +2 -0
  262. package/dist/providers/openrouter/converters.test.d.ts.map +1 -0
  263. package/dist/providers/openrouter/converters.test.js +158 -0
  264. package/dist/providers/openrouter/converters.test.js.map +1 -0
  265. package/dist/providers/openrouter/index.d.ts +4 -0
  266. package/dist/providers/openrouter/index.d.ts.map +1 -0
  267. package/dist/providers/openrouter/index.js +4 -0
  268. package/dist/providers/openrouter/index.js.map +1 -0
  269. package/dist/providers/openrouter/model.d.ts +14 -0
  270. package/dist/providers/openrouter/model.d.ts.map +1 -0
  271. package/dist/providers/openrouter/model.js +485 -0
  272. package/dist/providers/openrouter/model.js.map +1 -0
  273. package/dist/providers/openrouter/provider.d.ts +15 -0
  274. package/dist/providers/openrouter/provider.d.ts.map +1 -0
  275. package/dist/providers/openrouter/provider.js +21 -0
  276. package/dist/providers/openrouter/provider.js.map +1 -0
  277. package/dist/providers/openrouter/utils.d.ts +10 -0
  278. package/dist/providers/openrouter/utils.d.ts.map +1 -0
  279. package/dist/providers/openrouter/utils.js +27 -0
  280. package/dist/providers/openrouter/utils.js.map +1 -0
  281. package/dist/providers/openrouter.api.retry.test.d.ts +2 -0
  282. package/dist/providers/openrouter.api.retry.test.d.ts.map +1 -0
  283. package/dist/providers/openrouter.api.retry.test.js +148 -0
  284. package/dist/providers/openrouter.api.retry.test.js.map +1 -0
  285. package/dist/providers/openrouter.d.ts +2 -0
  286. package/dist/providers/openrouter.d.ts.map +1 -0
  287. package/dist/providers/openrouter.history.test.d.ts +2 -0
  288. package/dist/providers/openrouter.history.test.d.ts.map +1 -0
  289. package/dist/providers/openrouter.history.test.js +533 -0
  290. package/dist/providers/openrouter.history.test.js.map +1 -0
  291. package/dist/providers/openrouter.js +4 -0
  292. package/dist/providers/openrouter.js.map +1 -0
  293. package/dist/providers/openrouter.provider.createRunner.test.d.ts +2 -0
  294. package/dist/providers/openrouter.provider.createRunner.test.d.ts.map +1 -0
  295. package/dist/providers/openrouter.provider.createRunner.test.js +23 -0
  296. package/dist/providers/openrouter.provider.createRunner.test.js.map +1 -0
  297. package/dist/providers/openrouter.provider.d.ts +2 -0
  298. package/dist/providers/openrouter.provider.d.ts.map +1 -0
  299. package/dist/providers/openrouter.provider.js +56 -0
  300. package/dist/providers/openrouter.provider.js.map +1 -0
  301. package/dist/providers/openrouter.test.d.ts +2 -0
  302. package/dist/providers/openrouter.test.d.ts.map +1 -0
  303. package/dist/providers/openrouter.test.js +1382 -0
  304. package/dist/providers/openrouter.test.js.map +1 -0
  305. package/dist/providers/registry.d.ts +65 -0
  306. package/dist/providers/registry.d.ts.map +1 -0
  307. package/dist/providers/registry.js +44 -0
  308. package/dist/providers/registry.js.map +1 -0
  309. package/dist/providers/registry.test.d.ts +2 -0
  310. package/dist/providers/registry.test.d.ts.map +1 -0
  311. package/dist/providers/registry.test.js +76 -0
  312. package/dist/providers/registry.test.js.map +1 -0
  313. package/dist/providers/web-search/index.d.ts +8 -0
  314. package/dist/providers/web-search/index.d.ts.map +1 -0
  315. package/dist/providers/web-search/index.js +9 -0
  316. package/dist/providers/web-search/index.js.map +1 -0
  317. package/dist/providers/web-search/registry.d.ts +35 -0
  318. package/dist/providers/web-search/registry.d.ts.map +1 -0
  319. package/dist/providers/web-search/registry.js +56 -0
  320. package/dist/providers/web-search/registry.js.map +1 -0
  321. package/dist/providers/web-search/registry.test.d.ts +2 -0
  322. package/dist/providers/web-search/registry.test.d.ts.map +1 -0
  323. package/dist/providers/web-search/registry.test.js +105 -0
  324. package/dist/providers/web-search/registry.test.js.map +1 -0
  325. package/dist/providers/web-search/tavily.provider.d.ts +15 -0
  326. package/dist/providers/web-search/tavily.provider.d.ts.map +1 -0
  327. package/dist/providers/web-search/tavily.provider.js +69 -0
  328. package/dist/providers/web-search/tavily.provider.js.map +1 -0
  329. package/dist/providers/web-search/tavily.provider.test.d.ts +2 -0
  330. package/dist/providers/web-search/tavily.provider.test.d.ts.map +1 -0
  331. package/dist/providers/web-search/tavily.provider.test.js +67 -0
  332. package/dist/providers/web-search/tavily.provider.test.js.map +1 -0
  333. package/dist/providers/web-search/types.d.ts +55 -0
  334. package/dist/providers/web-search/types.d.ts.map +1 -0
  335. package/dist/providers/web-search/types.js +6 -0
  336. package/dist/providers/web-search/types.js.map +1 -0
  337. package/dist/safety-checker.js +57 -0
  338. package/dist/services/conversation-events.d.ts +76 -0
  339. package/dist/services/conversation-events.d.ts.map +1 -0
  340. package/dist/services/conversation-events.js +2 -0
  341. package/dist/services/conversation-events.js.map +1 -0
  342. package/dist/services/conversation-service.d.ts +31 -0
  343. package/dist/services/conversation-service.d.ts.map +1 -0
  344. package/dist/services/conversation-service.js +46 -0
  345. package/dist/services/conversation-service.js.map +1 -0
  346. package/dist/services/conversation-service.test.js +190 -0
  347. package/dist/services/conversation-session.d.ts +99 -0
  348. package/dist/services/conversation-session.d.ts.map +1 -0
  349. package/dist/services/conversation-session.js +978 -0
  350. package/dist/services/conversation-session.js.map +1 -0
  351. package/dist/services/conversation-store.d.ts +24 -0
  352. package/dist/services/conversation-store.d.ts.map +1 -0
  353. package/dist/services/conversation-store.js +216 -0
  354. package/dist/services/conversation-store.js.map +1 -0
  355. package/dist/services/conversation-store.test.d.ts +2 -0
  356. package/dist/services/conversation-store.test.d.ts.map +1 -0
  357. package/dist/services/conversation-store.test.js +167 -0
  358. package/dist/services/conversation-store.test.js.map +1 -0
  359. package/dist/services/execution-context.d.ts +10 -0
  360. package/dist/services/execution-context.d.ts.map +1 -0
  361. package/dist/services/execution-context.js +22 -0
  362. package/dist/services/execution-context.js.map +1 -0
  363. package/dist/services/execution-context.test.d.ts +2 -0
  364. package/dist/services/execution-context.test.d.ts.map +1 -0
  365. package/dist/services/execution-context.test.js +49 -0
  366. package/dist/services/execution-context.test.js.map +1 -0
  367. package/dist/services/file-service.d.ts +12 -0
  368. package/dist/services/file-service.d.ts.map +1 -0
  369. package/dist/services/file-service.js +90 -0
  370. package/dist/services/file-service.js.map +1 -0
  371. package/dist/services/history-service.d.ts +39 -0
  372. package/dist/services/history-service.d.ts.map +1 -0
  373. package/dist/services/history-service.js +152 -0
  374. package/dist/services/history-service.js.map +1 -0
  375. package/dist/services/logging-service.d.ts +75 -0
  376. package/dist/services/logging-service.d.ts.map +1 -0
  377. package/dist/services/logging-service.js +343 -0
  378. package/dist/services/logging-service.js.map +1 -0
  379. package/dist/services/model-service.d.ts +15 -0
  380. package/dist/services/model-service.d.ts.map +1 -0
  381. package/dist/services/model-service.js +46 -0
  382. package/dist/services/model-service.js.map +1 -0
  383. package/dist/services/model-service.test.d.ts +2 -0
  384. package/dist/services/model-service.test.d.ts.map +1 -0
  385. package/dist/services/model-service.test.js +128 -0
  386. package/dist/services/model-service.test.js.map +1 -0
  387. package/dist/services/service-interfaces.d.ts +33 -0
  388. package/dist/services/service-interfaces.d.ts.map +1 -0
  389. package/dist/services/service-interfaces.js +2 -0
  390. package/dist/services/service-interfaces.js.map +1 -0
  391. package/dist/services/settings-service.d.ts +316 -0
  392. package/dist/services/settings-service.d.ts.map +1 -0
  393. package/dist/services/settings-service.js +1128 -0
  394. package/dist/services/settings-service.js.map +1 -0
  395. package/dist/services/settings-service.mock.d.ts +20 -0
  396. package/dist/services/settings-service.mock.d.ts.map +1 -0
  397. package/dist/services/settings-service.mock.js +55 -0
  398. package/dist/services/settings-service.mock.js.map +1 -0
  399. package/dist/services/singleton-deprecation.test.d.ts +2 -0
  400. package/dist/services/singleton-deprecation.test.d.ts.map +1 -0
  401. package/dist/services/singleton-deprecation.test.js +59 -0
  402. package/dist/services/singleton-deprecation.test.js.map +1 -0
  403. package/dist/services/ssh-service.d.ts +32 -0
  404. package/dist/services/ssh-service.d.ts.map +1 -0
  405. package/dist/services/ssh-service.js +119 -0
  406. package/dist/services/ssh-service.js.map +1 -0
  407. package/dist/services/ssh-service.test.d.ts +2 -0
  408. package/dist/services/ssh-service.test.d.ts.map +1 -0
  409. package/dist/services/ssh-service.test.js +269 -0
  410. package/dist/services/ssh-service.test.js.map +1 -0
  411. package/dist/test-search-tool.d.ts +2 -0
  412. package/dist/test-search-tool.d.ts.map +1 -0
  413. package/dist/test-search-tool.js +36 -0
  414. package/dist/test-search-tool.js.map +1 -0
  415. package/dist/tools/apply-patch.d.ts +28 -0
  416. package/dist/tools/apply-patch.d.ts.map +1 -0
  417. package/dist/tools/apply-patch.js +399 -0
  418. package/dist/tools/apply-patch.js.map +1 -0
  419. package/dist/tools/apply-patch.test.d.ts +2 -0
  420. package/dist/tools/apply-patch.test.d.ts.map +1 -0
  421. package/dist/tools/apply-patch.test.js +155 -0
  422. package/dist/tools/apply-patch.test.js.map +1 -0
  423. package/dist/tools/ask-mentor.d.ts +11 -0
  424. package/dist/tools/ask-mentor.d.ts.map +1 -0
  425. package/dist/tools/ask-mentor.js +52 -0
  426. package/dist/tools/ask-mentor.js.map +1 -0
  427. package/dist/tools/ask-mentor.test.d.ts +2 -0
  428. package/dist/tools/ask-mentor.test.d.ts.map +1 -0
  429. package/dist/tools/ask-mentor.test.js +47 -0
  430. package/dist/tools/ask-mentor.test.js.map +1 -0
  431. package/dist/tools/bash.d.ts +10 -0
  432. package/dist/tools/bash.d.ts.map +1 -0
  433. package/dist/tools/bash.js +55 -0
  434. package/dist/tools/bash.js.map +1 -0
  435. package/dist/tools/find-files.d.ts +15 -0
  436. package/dist/tools/find-files.d.ts.map +1 -0
  437. package/dist/tools/find-files.js +179 -0
  438. package/dist/tools/find-files.js.map +1 -0
  439. package/dist/tools/find-files.test.d.ts +2 -0
  440. package/dist/tools/find-files.test.d.ts.map +1 -0
  441. package/dist/tools/find-files.test.js +131 -0
  442. package/dist/tools/find-files.test.js.map +1 -0
  443. package/dist/tools/format-helpers.d.ts +34 -0
  444. package/dist/tools/format-helpers.d.ts.map +1 -0
  445. package/dist/tools/format-helpers.js +131 -0
  446. package/dist/tools/format-helpers.js.map +1 -0
  447. package/dist/tools/grep.d.ts +16 -0
  448. package/dist/tools/grep.d.ts.map +1 -0
  449. package/dist/tools/grep.js +211 -0
  450. package/dist/tools/grep.js.map +1 -0
  451. package/dist/tools/read-file.d.ts +15 -0
  452. package/dist/tools/read-file.d.ts.map +1 -0
  453. package/dist/tools/read-file.js +114 -0
  454. package/dist/tools/read-file.js.map +1 -0
  455. package/dist/tools/read-file.test.d.ts +2 -0
  456. package/dist/tools/read-file.test.d.ts.map +1 -0
  457. package/dist/tools/read-file.test.js +122 -0
  458. package/dist/tools/read-file.test.js.map +1 -0
  459. package/dist/tools/search-replace.d.ts +19 -0
  460. package/dist/tools/search-replace.d.ts.map +1 -0
  461. package/dist/tools/search-replace.js +411 -0
  462. package/dist/tools/search-replace.js.map +1 -0
  463. package/dist/tools/search-replace.test.d.ts +2 -0
  464. package/dist/tools/search-replace.test.d.ts.map +1 -0
  465. package/dist/tools/search-replace.test.js +302 -0
  466. package/dist/tools/search-replace.test.js.map +1 -0
  467. package/dist/tools/search.d.ts +15 -0
  468. package/dist/tools/search.d.ts.map +1 -0
  469. package/dist/tools/search.js +143 -0
  470. package/dist/tools/search.js.map +1 -0
  471. package/dist/tools/shell.d.ts +19 -0
  472. package/dist/tools/shell.d.ts.map +1 -0
  473. package/dist/tools/shell.js +278 -0
  474. package/dist/tools/shell.js.map +1 -0
  475. package/dist/tools/tool-execution-context.d.ts +7 -0
  476. package/dist/tools/tool-execution-context.d.ts.map +1 -0
  477. package/dist/tools/tool-execution-context.js +7 -0
  478. package/dist/tools/tool-execution-context.js.map +1 -0
  479. package/dist/tools/types.d.ts +30 -0
  480. package/dist/tools/types.d.ts.map +1 -0
  481. package/dist/tools/types.js +2 -0
  482. package/dist/tools/types.js.map +1 -0
  483. package/dist/tools/utils.d.ts +12 -0
  484. package/dist/tools/utils.d.ts.map +1 -0
  485. package/dist/tools/utils.js +19 -0
  486. package/dist/tools/utils.js.map +1 -0
  487. package/dist/tools/web-search.d.ts +29 -0
  488. package/dist/tools/web-search.d.ts.map +1 -0
  489. package/dist/tools/web-search.js +106 -0
  490. package/dist/tools/web-search.js.map +1 -0
  491. package/dist/tools/web-search.test.d.ts +2 -0
  492. package/dist/tools/web-search.test.d.ts.map +1 -0
  493. package/dist/tools/web-search.test.js +176 -0
  494. package/dist/tools/web-search.test.js.map +1 -0
  495. package/dist/utils/command-logger.d.ts +11 -0
  496. package/dist/utils/command-logger.d.ts.map +1 -0
  497. package/dist/utils/command-logger.js +34 -0
  498. package/dist/utils/command-logger.js.map +1 -0
  499. package/dist/utils/command-safety/constants.d.ts +21 -0
  500. package/dist/utils/command-safety/constants.d.ts.map +1 -0
  501. package/dist/utils/command-safety/constants.js +245 -0
  502. package/dist/utils/command-safety/constants.js.map +1 -0
  503. package/dist/utils/command-safety/find-helpers.d.ts +15 -0
  504. package/dist/utils/command-safety/find-helpers.d.ts.map +1 -0
  505. package/dist/utils/command-safety/find-helpers.js +218 -0
  506. package/dist/utils/command-safety/find-helpers.js.map +1 -0
  507. package/dist/utils/command-safety/handlers/find-handler.d.ts +6 -0
  508. package/dist/utils/command-safety/handlers/find-handler.d.ts.map +1 -0
  509. package/dist/utils/command-safety/handlers/find-handler.js +113 -0
  510. package/dist/utils/command-safety/handlers/find-handler.js.map +1 -0
  511. package/dist/utils/command-safety/handlers/git-handler.d.ts +6 -0
  512. package/dist/utils/command-safety/handlers/git-handler.d.ts.map +1 -0
  513. package/dist/utils/command-safety/handlers/git-handler.js +68 -0
  514. package/dist/utils/command-safety/handlers/git-handler.js.map +1 -0
  515. package/dist/utils/command-safety/handlers/index.d.ts +13 -0
  516. package/dist/utils/command-safety/handlers/index.d.ts.map +1 -0
  517. package/dist/utils/command-safety/handlers/index.js +20 -0
  518. package/dist/utils/command-safety/handlers/index.js.map +1 -0
  519. package/dist/utils/command-safety/handlers/sed-handler.d.ts +6 -0
  520. package/dist/utils/command-safety/handlers/sed-handler.d.ts.map +1 -0
  521. package/dist/utils/command-safety/handlers/sed-handler.js +94 -0
  522. package/dist/utils/command-safety/handlers/sed-handler.js.map +1 -0
  523. package/dist/utils/command-safety/handlers/types.d.ts +36 -0
  524. package/dist/utils/command-safety/handlers/types.d.ts.map +1 -0
  525. package/dist/utils/command-safety/handlers/types.js +2 -0
  526. package/dist/utils/command-safety/handlers/types.js.map +1 -0
  527. package/dist/utils/command-safety/index.d.ts +14 -0
  528. package/dist/utils/command-safety/index.d.ts.map +1 -0
  529. package/dist/utils/command-safety/index.js +183 -0
  530. package/dist/utils/command-safety/index.js.map +1 -0
  531. package/dist/utils/command-safety/path-analysis.d.ts +4 -0
  532. package/dist/utils/command-safety/path-analysis.d.ts.map +1 -0
  533. package/dist/utils/command-safety/path-analysis.js +153 -0
  534. package/dist/utils/command-safety/path-analysis.js.map +1 -0
  535. package/dist/utils/command-safety/utils.d.ts +2 -0
  536. package/dist/utils/command-safety/utils.d.ts.map +1 -0
  537. package/dist/utils/command-safety/utils.js +22 -0
  538. package/dist/utils/command-safety/utils.js.map +1 -0
  539. package/dist/utils/command-safety.d.ts +21 -0
  540. package/dist/utils/command-safety.d.ts.map +1 -0
  541. package/dist/utils/command-safety.find.test.d.ts +2 -0
  542. package/dist/utils/command-safety.find.test.d.ts.map +1 -0
  543. package/dist/utils/command-safety.find.test.js +342 -0
  544. package/dist/utils/command-safety.find.test.js.map +1 -0
  545. package/dist/utils/command-safety.js +702 -0
  546. package/dist/utils/command-safety.js.map +1 -0
  547. package/dist/utils/command-safety.path.test.d.ts +2 -0
  548. package/dist/utils/command-safety.path.test.d.ts.map +1 -0
  549. package/dist/utils/command-safety.path.test.js +360 -0
  550. package/dist/utils/command-safety.path.test.js.map +1 -0
  551. package/dist/utils/diff.d.ts +2 -0
  552. package/dist/utils/diff.d.ts.map +1 -0
  553. package/dist/utils/diff.js +44 -0
  554. package/dist/utils/diff.js.map +1 -0
  555. package/dist/utils/diff.test.d.ts +2 -0
  556. package/dist/utils/diff.test.d.ts.map +1 -0
  557. package/dist/utils/diff.test.js +85 -0
  558. package/dist/utils/diff.test.js.map +1 -0
  559. package/dist/utils/error-helpers.d.ts +6 -0
  560. package/dist/utils/error-helpers.d.ts.map +1 -0
  561. package/dist/utils/error-helpers.js +46 -0
  562. package/dist/utils/error-helpers.js.map +1 -0
  563. package/dist/utils/error-helpers.test.d.ts +2 -0
  564. package/dist/utils/error-helpers.test.d.ts.map +1 -0
  565. package/dist/utils/error-helpers.test.js +152 -0
  566. package/dist/utils/error-helpers.test.js.map +1 -0
  567. package/dist/utils/execute-shell.d.ts +15 -0
  568. package/dist/utils/execute-shell.d.ts.map +1 -0
  569. package/dist/utils/execute-shell.js +34 -0
  570. package/dist/utils/execute-shell.js.map +1 -0
  571. package/dist/utils/execute-shell.test.d.ts +2 -0
  572. package/dist/utils/execute-shell.test.d.ts.map +1 -0
  573. package/dist/utils/execute-shell.test.js +20 -0
  574. package/dist/utils/execute-shell.test.js.map +1 -0
  575. package/dist/utils/extract-command-messages.d.ts +5 -0
  576. package/dist/utils/extract-command-messages.d.ts.map +1 -0
  577. package/dist/utils/extract-command-messages.js +140 -0
  578. package/dist/utils/extract-command-messages.js.map +1 -0
  579. package/dist/utils/extract-command-messages.repro.test.d.ts +2 -0
  580. package/dist/utils/extract-command-messages.repro.test.d.ts.map +1 -0
  581. package/dist/utils/extract-command-messages.repro.test.js +31 -0
  582. package/dist/utils/extract-command-messages.repro.test.js.map +1 -0
  583. package/dist/utils/extract-command-messages.test.js +57 -0
  584. package/dist/utils/message-buffer.d.ts +2 -0
  585. package/dist/utils/message-buffer.d.ts.map +1 -0
  586. package/dist/utils/message-buffer.js +15 -0
  587. package/dist/utils/message-buffer.js.map +1 -0
  588. package/dist/utils/message-buffer.test.d.ts +2 -0
  589. package/dist/utils/message-buffer.test.d.ts.map +1 -0
  590. package/dist/utils/message-buffer.test.js +17 -0
  591. package/dist/utils/message-buffer.test.js.map +1 -0
  592. package/dist/utils/output-trim.d.ts +31 -0
  593. package/dist/utils/output-trim.d.ts.map +1 -0
  594. package/dist/utils/output-trim.js +71 -0
  595. package/dist/utils/output-trim.js.map +1 -0
  596. package/dist/utils/provider-credentials.d.ts +10 -0
  597. package/dist/utils/provider-credentials.d.ts.map +1 -0
  598. package/dist/utils/provider-credentials.js +22 -0
  599. package/dist/utils/provider-credentials.js.map +1 -0
  600. package/dist/utils/settings-command.d.ts +13 -0
  601. package/dist/utils/settings-command.d.ts.map +1 -0
  602. package/dist/utils/settings-command.js +173 -0
  603. package/dist/utils/settings-command.js.map +1 -0
  604. package/dist/utils/ssh-config-parser.d.ts +21 -0
  605. package/dist/utils/ssh-config-parser.d.ts.map +1 -0
  606. package/dist/utils/ssh-config-parser.js +89 -0
  607. package/dist/utils/ssh-config-parser.js.map +1 -0
  608. package/dist/utils/ssh-config-parser.test.d.ts +2 -0
  609. package/dist/utils/ssh-config-parser.test.d.ts.map +1 -0
  610. package/dist/utils/ssh-config-parser.test.js +153 -0
  611. package/dist/utils/ssh-config-parser.test.js.map +1 -0
  612. package/dist/utils/streaming-updater.d.ts +7 -0
  613. package/dist/utils/streaming-updater.d.ts.map +1 -0
  614. package/dist/utils/streaming-updater.js +41 -0
  615. package/dist/utils/streaming-updater.js.map +1 -0
  616. package/dist/utils/throttle.d.ts +7 -0
  617. package/dist/utils/throttle.d.ts.map +1 -0
  618. package/dist/utils/throttle.js +49 -0
  619. package/dist/utils/throttle.js.map +1 -0
  620. package/package.json +108 -0
  621. package/readme.md +428 -0
@@ -0,0 +1,978 @@
1
+ import { extractCommandMessages, markToolCallAsApprovalRejection, } from '../utils/extract-command-messages.js';
2
+ import { ConversationStore } from './conversation-store.js';
3
+ import { ModelBehaviorError } from '@openai/agents';
4
+ const getCommandFromArgs = (args) => {
5
+ if (!args) {
6
+ return '';
7
+ }
8
+ if (typeof args === 'string') {
9
+ try {
10
+ const parsed = JSON.parse(args);
11
+ // Handle shell tool's command parameter
12
+ if (parsed?.command) {
13
+ return parsed.command;
14
+ }
15
+ // Fallback for old 'commands' array format
16
+ if (Array.isArray(parsed?.commands)) {
17
+ return parsed.commands.join('\n');
18
+ }
19
+ return args;
20
+ }
21
+ catch {
22
+ return args;
23
+ }
24
+ }
25
+ if (typeof args === 'object') {
26
+ // Handle shell tool's command parameter
27
+ const cmdFromObject = 'command' in args ? String(args.command) : undefined;
28
+ // Fallback for old 'commands' array format
29
+ if ('commands' in args && Array.isArray(args.commands)) {
30
+ return args.commands.join('\n');
31
+ }
32
+ const argsFromObject = 'arguments' in args ? String(args.arguments) : undefined;
33
+ return cmdFromObject ?? argsFromObject ?? JSON.stringify(args);
34
+ }
35
+ return String(args);
36
+ };
37
+ /**
38
+ * Maximum number of retries when the model hallucinates a tool
39
+ */
40
+ const MAX_HALLUCINATION_RETRIES = 2;
41
+ /**
42
+ * Check if an error is a tool hallucination error (model called a non-existent tool)
43
+ */
44
+ const isToolHallucinationError = (error) => {
45
+ if (!(error instanceof ModelBehaviorError)) {
46
+ return false;
47
+ }
48
+ const message = error.message.toLowerCase();
49
+ return message.includes('tool') && message.includes('not found');
50
+ };
51
+ export class ConversationSession {
52
+ id;
53
+ agentClient;
54
+ logger;
55
+ conversationStore;
56
+ previousResponseId = null;
57
+ pendingApprovalContext = null;
58
+ abortedApprovalContext = null;
59
+ textDeltaCount = 0;
60
+ reasoningDeltaCount = 0;
61
+ toolCallArgumentsById = new Map();
62
+ lastEventType = null;
63
+ eventTypeCount = 0;
64
+ // private logStreamEvent = (eventType: string, eventData: any) => {
65
+ // if (eventData.item) {
66
+ // eventType = eventData.item.type;
67
+ // eventData = eventData.item.rawItem;
68
+ // // this.logStreamEvent(eventType, eventData);
69
+ // }
70
+ //
71
+ // // Deduplicate consecutive identical event types
72
+ // if (eventType !== this.lastEventType) {
73
+ // if (this.lastEventType !== null && this.eventTypeCount > 0) {
74
+ // this.logger.debug('Stream event summary', {
75
+ // eventType: this.lastEventType,
76
+ // count: this.eventTypeCount,
77
+ // });
78
+ // }
79
+ // this.lastEventType = eventType;
80
+ // this.eventTypeCount = 1;
81
+ // // Log the first occurrence with details
82
+ // this.logger.debug('Stream event', {
83
+ // eventType,
84
+ // ...eventData,
85
+ // });
86
+ // } else {
87
+ // this.eventTypeCount++;
88
+ // }
89
+ // };
90
+ flushStreamEventLog = () => {
91
+ if (this.lastEventType !== null && this.eventTypeCount > 1) {
92
+ this.logger.debug('Stream event summary', {
93
+ eventType: this.lastEventType,
94
+ count: this.eventTypeCount,
95
+ });
96
+ }
97
+ this.lastEventType = null;
98
+ this.eventTypeCount = 0;
99
+ };
100
+ constructor(id, { agentClient, deps, }) {
101
+ this.id = id;
102
+ this.agentClient = agentClient;
103
+ this.logger = deps.logger;
104
+ this.conversationStore = new ConversationStore();
105
+ }
106
+ reset() {
107
+ this.previousResponseId = null;
108
+ this.conversationStore.clear();
109
+ this.pendingApprovalContext = null;
110
+ this.abortedApprovalContext = null;
111
+ this.toolCallArgumentsById.clear();
112
+ if (typeof this.agentClient.clearConversations === 'function') {
113
+ this.agentClient.clearConversations();
114
+ }
115
+ }
116
+ setModel(model) {
117
+ this.agentClient.setModel(model);
118
+ }
119
+ setReasoningEffort(effort) {
120
+ if (typeof this.agentClient.setReasoningEffort === 'function') {
121
+ this.agentClient.setReasoningEffort(effort);
122
+ }
123
+ }
124
+ setTemperature(temperature) {
125
+ if (typeof this.agentClient.setTemperature === 'function') {
126
+ this.agentClient.setTemperature(temperature);
127
+ }
128
+ }
129
+ setProvider(provider) {
130
+ if (typeof this.agentClient.setProvider === 'function') {
131
+ this.agentClient.setProvider(provider);
132
+ }
133
+ }
134
+ setRetryCallback(callback) {
135
+ if (typeof this.agentClient.setRetryCallback === 'function') {
136
+ this.agentClient.setRetryCallback(callback);
137
+ }
138
+ }
139
+ addShellContext(historyText) {
140
+ this.conversationStore.addShellContext(historyText);
141
+ }
142
+ /**
143
+ * Abort the current running operation
144
+ */
145
+ abort() {
146
+ this.agentClient.abort();
147
+ // Save pending approval context so we can handle it in the next message
148
+ if (this.pendingApprovalContext) {
149
+ this.abortedApprovalContext = this.pendingApprovalContext;
150
+ this.pendingApprovalContext = null;
151
+ this.logger.debug('Aborted approval - will handle rejection on next message');
152
+ }
153
+ }
154
+ /**
155
+ * Phase 4: stream conversation events as an async iterator.
156
+ *
157
+ * This is the transport-friendly primitive that can later be bridged to SSE/WebSockets.
158
+ */
159
+ async *run(text, { hallucinationRetryCount = 0, skipUserMessage = false, } = {}) {
160
+ let stream = null;
161
+ try {
162
+ // Maintain canonical local history regardless of provider.
163
+ if (!skipUserMessage) {
164
+ this.conversationStore.addUserMessage(text);
165
+ }
166
+ // If there's an aborted approval, we need to resolve it first.
167
+ // The user's message is a new input, but the agent is stuck waiting for tool output.
168
+ if (this.abortedApprovalContext) {
169
+ this.logger.debug('Resolving aborted approval with fake execution', {
170
+ message: text,
171
+ });
172
+ const { state, interruption, emittedCommandIds, toolCallArgumentsById, } = this.abortedApprovalContext;
173
+ this.abortedApprovalContext = null;
174
+ // Restore cached tool-call arguments captured before abort so continuation can attach them
175
+ this.toolCallArgumentsById.clear();
176
+ if (toolCallArgumentsById?.size) {
177
+ for (const [key, value,] of toolCallArgumentsById.entries()) {
178
+ this.toolCallArgumentsById.set(key, value);
179
+ }
180
+ }
181
+ // Add interceptor for this tool execution
182
+ const toolName = interruption.name ?? 'unknown';
183
+ const expectedCallId = interruption.rawItem?.callId ??
184
+ interruption.callId;
185
+ const rejectionMessage = `Tool execution was not approved. User provided new input instead: ${text}`;
186
+ const removeInterceptor = this.agentClient.addToolInterceptor(async (name, _params, toolCallId) => {
187
+ // Match both tool name and call ID for stricter matching
188
+ if (name === toolName &&
189
+ (!expectedCallId || toolCallId === expectedCallId)) {
190
+ markToolCallAsApprovalRejection(toolCallId ?? expectedCallId);
191
+ return rejectionMessage;
192
+ }
193
+ return null;
194
+ });
195
+ state.approve(interruption);
196
+ try {
197
+ const stream = await this.agentClient.continueRunStream(state, {
198
+ previousResponseId: this.previousResponseId,
199
+ });
200
+ const acc = {
201
+ finalOutput: '',
202
+ reasoningOutput: '',
203
+ emittedCommandIds: new Set(emittedCommandIds),
204
+ };
205
+ yield* this.#streamEvents(stream, acc, {
206
+ preserveExistingToolArgs: true,
207
+ });
208
+ this.previousResponseId = stream.lastResponseId;
209
+ this.conversationStore.updateFromResult(stream);
210
+ // Check if another interruption occurred
211
+ if (stream.interruptions &&
212
+ stream.interruptions.length > 0) {
213
+ this.logger.warn('Another interruption occurred after fake execution - handling as approval');
214
+ // Let the normal flow handle this
215
+ const result = this.#buildResult(stream, acc.finalOutput, acc.reasoningOutput, acc.emittedCommandIds);
216
+ // Re-emit the terminal event explicitly.
217
+ if (result.type === 'approval_required') {
218
+ const interruption = result.approval.rawInterruption;
219
+ const callId = interruption?.rawItem?.callId ??
220
+ interruption?.callId ??
221
+ interruption?.call_id ??
222
+ interruption?.tool_call_id ??
223
+ interruption?.toolCallId ??
224
+ interruption?.id;
225
+ yield {
226
+ type: 'approval_required',
227
+ approval: {
228
+ agentName: result.approval.agentName,
229
+ toolName: result.approval.toolName,
230
+ argumentsText: result.approval.argumentsText,
231
+ ...(callId ? { callId: String(callId) } : {}),
232
+ },
233
+ };
234
+ }
235
+ else {
236
+ yield {
237
+ type: 'final',
238
+ finalText: result.finalText,
239
+ ...(result.reasoningText
240
+ ? { reasoningText: result.reasoningText }
241
+ : {}),
242
+ ...(result.commandMessages?.length
243
+ ? { commandMessages: result.commandMessages }
244
+ : {}),
245
+ };
246
+ }
247
+ return;
248
+ }
249
+ // Successfully resolved - agent should now have processed the fake rejection
250
+ this.logger.debug('Fake execution completed, agent received rejection message');
251
+ const result = this.#buildResult(stream, acc.finalOutput, acc.reasoningOutput, acc.emittedCommandIds);
252
+ if (result.type === 'approval_required') {
253
+ const interruption = result.approval.rawInterruption;
254
+ const callId = interruption?.rawItem?.callId ??
255
+ interruption?.callId ??
256
+ interruption?.call_id ??
257
+ interruption?.tool_call_id ??
258
+ interruption?.toolCallId ??
259
+ interruption?.id;
260
+ yield {
261
+ type: 'approval_required',
262
+ approval: {
263
+ agentName: result.approval.agentName,
264
+ toolName: result.approval.toolName,
265
+ argumentsText: result.approval.argumentsText,
266
+ ...(callId ? { callId: String(callId) } : {}),
267
+ },
268
+ };
269
+ }
270
+ else {
271
+ yield {
272
+ type: 'final',
273
+ finalText: result.finalText,
274
+ ...(result.reasoningText
275
+ ? { reasoningText: result.reasoningText }
276
+ : {}),
277
+ ...(result.commandMessages?.length
278
+ ? { commandMessages: result.commandMessages }
279
+ : {}),
280
+ };
281
+ }
282
+ return;
283
+ }
284
+ catch (error) {
285
+ this.logger.warn('Error resolving aborted approval with fake execution', {
286
+ error: error instanceof Error
287
+ ? error.message
288
+ : String(error),
289
+ });
290
+ // Fall through to normal message flow
291
+ }
292
+ finally {
293
+ // Always remove interceptor after use
294
+ removeInterceptor();
295
+ }
296
+ }
297
+ // Normal message flow
298
+ const provider = typeof this.agentClient.getProvider === 'function'
299
+ ? this.agentClient.getProvider()
300
+ : 'openai';
301
+ // Only OpenAI uses server-side conversation management via previousResponseId.
302
+ // All other providers (OpenRouter, openai-compatible) need full history.
303
+ stream = await this.agentClient.startStream(provider !== 'openai'
304
+ ? this.conversationStore.getHistory()
305
+ : text, {
306
+ previousResponseId: this.previousResponseId,
307
+ });
308
+ const acc = {
309
+ finalOutput: '',
310
+ reasoningOutput: '',
311
+ emittedCommandIds: new Set(),
312
+ };
313
+ yield* this.#streamEvents(stream, acc, {
314
+ preserveExistingToolArgs: false,
315
+ });
316
+ this.previousResponseId = stream.lastResponseId;
317
+ this.conversationStore.updateFromResult(stream);
318
+ // Build terminal event (approval_required or final)
319
+ const result = this.#buildResult(stream, acc.finalOutput || undefined, acc.reasoningOutput || undefined, acc.emittedCommandIds);
320
+ if (result.type === 'approval_required') {
321
+ const interruption = result.approval.rawInterruption;
322
+ const callId = interruption?.rawItem?.callId ??
323
+ interruption?.callId ??
324
+ interruption?.call_id ??
325
+ interruption?.tool_call_id ??
326
+ interruption?.toolCallId ??
327
+ interruption?.id;
328
+ yield {
329
+ type: 'approval_required',
330
+ approval: {
331
+ agentName: result.approval.agentName,
332
+ toolName: result.approval.toolName,
333
+ argumentsText: result.approval.argumentsText,
334
+ ...(callId ? { callId: String(callId) } : {}),
335
+ },
336
+ };
337
+ return;
338
+ }
339
+ yield {
340
+ type: 'final',
341
+ finalText: result.finalText,
342
+ ...(result.reasoningText
343
+ ? { reasoningText: result.reasoningText }
344
+ : {}),
345
+ ...(result.commandMessages?.length
346
+ ? { commandMessages: result.commandMessages }
347
+ : {}),
348
+ };
349
+ }
350
+ catch (error) {
351
+ // Handle tool hallucination: model called a non-existent tool
352
+ if (isToolHallucinationError(error) &&
353
+ hallucinationRetryCount < MAX_HALLUCINATION_RETRIES) {
354
+ const toolName = error instanceof Error
355
+ ? error.message.match(/Tool (\S+) not found/)?.[1] ||
356
+ 'unknown'
357
+ : 'unknown';
358
+ this.logger.warn('Tool hallucination detected, retrying', {
359
+ toolName,
360
+ attempt: hallucinationRetryCount + 1,
361
+ maxRetries: MAX_HALLUCINATION_RETRIES,
362
+ errorMessage: error instanceof Error ? error.message : String(error),
363
+ });
364
+ yield {
365
+ type: 'retry',
366
+ toolName,
367
+ attempt: hallucinationRetryCount + 1,
368
+ maxRetries: MAX_HALLUCINATION_RETRIES,
369
+ errorMessage: error instanceof Error ? error.message : String(error),
370
+ };
371
+ if (stream) {
372
+ // Update conversation store with partial results (successful tool calls)
373
+ this.conversationStore.updateFromResult(stream);
374
+ // Retry from current state without re-adding user message
375
+ yield* this.run(text, {
376
+ hallucinationRetryCount: hallucinationRetryCount + 1,
377
+ skipUserMessage: true,
378
+ });
379
+ }
380
+ else {
381
+ // Failed to start stream at all - clean slate retry
382
+ this.conversationStore.removeLastUserMessage();
383
+ yield* this.run(text, {
384
+ hallucinationRetryCount: hallucinationRetryCount + 1,
385
+ // skipUserMessage defaults to false, so user message is re-added
386
+ });
387
+ }
388
+ return;
389
+ }
390
+ yield {
391
+ type: 'error',
392
+ message: error instanceof Error ? error.message : String(error),
393
+ };
394
+ throw error;
395
+ }
396
+ }
397
+ /**
398
+ * Phase 4: continue a session after an approval decision.
399
+ *
400
+ * Named as a string-literal because `continue` is a keyword.
401
+ */
402
+ async *['continue']({ answer, rejectionReason, }) {
403
+ if (!this.pendingApprovalContext) {
404
+ return;
405
+ }
406
+ const { state, interruption, emittedCommandIds: previouslyEmittedIds, toolCallArgumentsById, } = this.pendingApprovalContext;
407
+ if (answer === 'y') {
408
+ state.approve(interruption);
409
+ }
410
+ else {
411
+ // If rejection reason provided, inject it as a tool interceptor result
412
+ if (rejectionReason) {
413
+ const toolName = interruption.name ?? 'unknown';
414
+ const expectedCallId = interruption.rawItem?.callId ??
415
+ interruption.callId;
416
+ const rejectionMessage = `Tool execution was not approved. User's reason: ${rejectionReason}`;
417
+ const removeInterceptor = this.agentClient.addToolInterceptor(async (name, _params, toolCallId) => {
418
+ if (name === toolName &&
419
+ (!expectedCallId || toolCallId === expectedCallId)) {
420
+ markToolCallAsApprovalRejection(toolCallId ?? expectedCallId);
421
+ return rejectionMessage;
422
+ }
423
+ return null;
424
+ });
425
+ // Approve to continue but interceptor will return rejection message
426
+ state.approve(interruption);
427
+ // Store interceptor cleanup for after stream
428
+ this.pendingApprovalContext = {
429
+ ...this.pendingApprovalContext,
430
+ removeInterceptor,
431
+ };
432
+ }
433
+ else {
434
+ state.reject(interruption);
435
+ }
436
+ }
437
+ // Restore cached tool-call arguments so continuation outputs can attach them
438
+ this.toolCallArgumentsById.clear();
439
+ if (toolCallArgumentsById?.size) {
440
+ for (const [key, value] of toolCallArgumentsById.entries()) {
441
+ this.toolCallArgumentsById.set(key, value);
442
+ }
443
+ }
444
+ try {
445
+ const stream = await this.agentClient.continueRunStream(state, {
446
+ previousResponseId: this.previousResponseId,
447
+ });
448
+ const acc = {
449
+ finalOutput: '',
450
+ reasoningOutput: '',
451
+ emittedCommandIds: new Set(),
452
+ };
453
+ yield* this.#streamEvents(stream, acc, {
454
+ preserveExistingToolArgs: true,
455
+ });
456
+ this.previousResponseId = stream.lastResponseId;
457
+ this.conversationStore.updateFromResult(stream);
458
+ // Merge previously emitted command IDs with newly emitted ones
459
+ // This prevents duplicates when result.history contains commands from the initial stream
460
+ const allEmittedIds = new Set([
461
+ ...previouslyEmittedIds,
462
+ ...acc.emittedCommandIds,
463
+ ]);
464
+ const result = this.#buildResult(stream, acc.finalOutput || undefined, acc.reasoningOutput || undefined, allEmittedIds);
465
+ if (result.type === 'approval_required') {
466
+ const interruption = result.approval.rawInterruption;
467
+ const callId = interruption?.rawItem?.callId ??
468
+ interruption?.callId ??
469
+ interruption?.call_id ??
470
+ interruption?.tool_call_id ??
471
+ interruption?.toolCallId ??
472
+ interruption?.id;
473
+ yield {
474
+ type: 'approval_required',
475
+ approval: {
476
+ agentName: result.approval.agentName,
477
+ toolName: result.approval.toolName,
478
+ argumentsText: result.approval.argumentsText,
479
+ ...(callId ? { callId: String(callId) } : {}),
480
+ },
481
+ };
482
+ return;
483
+ }
484
+ yield {
485
+ type: 'final',
486
+ finalText: result.finalText,
487
+ ...(result.reasoningText
488
+ ? { reasoningText: result.reasoningText }
489
+ : {}),
490
+ ...(result.commandMessages?.length
491
+ ? { commandMessages: result.commandMessages }
492
+ : {}),
493
+ };
494
+ }
495
+ catch (error) {
496
+ yield {
497
+ type: 'error',
498
+ message: error instanceof Error ? error.message : String(error),
499
+ };
500
+ throw error;
501
+ }
502
+ finally {
503
+ // Clean up interceptor if one was added for rejection reason
504
+ if (rejectionReason &&
505
+ this.pendingApprovalContext?.removeInterceptor) {
506
+ this.pendingApprovalContext.removeInterceptor();
507
+ }
508
+ }
509
+ }
510
+ async sendMessage(text, { onTextChunk, onReasoningChunk, onCommandMessage, onEvent, hallucinationRetryCount = 0, } = {}) {
511
+ let finalText = '';
512
+ let reasoningText = '';
513
+ const commandMessages = [];
514
+ let sawTerminalEvent = null;
515
+ for await (const event of this.run(text, { hallucinationRetryCount })) {
516
+ onEvent?.(event);
517
+ switch (event.type) {
518
+ case 'text_delta': {
519
+ const full = event.fullText ?? '';
520
+ onTextChunk?.(full, event.delta);
521
+ break;
522
+ }
523
+ case 'reasoning_delta': {
524
+ const full = event.fullText ?? '';
525
+ onReasoningChunk?.(full, event.delta);
526
+ break;
527
+ }
528
+ case 'command_message': {
529
+ onCommandMessage?.(event.message);
530
+ break;
531
+ }
532
+ case 'approval_required': {
533
+ sawTerminalEvent = event;
534
+ // pendingApprovalContext is set inside #buildResult during run()
535
+ const rawInterruption = this.pendingApprovalContext?.interruption;
536
+ return {
537
+ type: 'approval_required',
538
+ approval: {
539
+ agentName: event.approval.agentName,
540
+ toolName: event.approval.toolName,
541
+ argumentsText: event.approval.argumentsText,
542
+ rawInterruption,
543
+ },
544
+ };
545
+ }
546
+ case 'final': {
547
+ sawTerminalEvent = event;
548
+ finalText = event.finalText;
549
+ reasoningText = event.reasoningText ?? '';
550
+ if (event.commandMessages?.length) {
551
+ for (const msg of event.commandMessages) {
552
+ commandMessages.push(msg);
553
+ }
554
+ }
555
+ break;
556
+ }
557
+ case 'error': {
558
+ // Preserve legacy behavior (throwing) by throwing after the stream ends.
559
+ break;
560
+ }
561
+ default:
562
+ break;
563
+ }
564
+ }
565
+ // If we didn't see a terminal event, fall back to the legacy default.
566
+ if (!sawTerminalEvent) {
567
+ finalText = finalText || 'Done.';
568
+ }
569
+ return {
570
+ type: 'response',
571
+ commandMessages,
572
+ finalText: finalText || 'Done.',
573
+ ...(reasoningText ? { reasoningText } : {}),
574
+ };
575
+ }
576
+ async handleApprovalDecision(answer, rejectionReason, { onTextChunk, onReasoningChunk, onCommandMessage, onEvent, } = {}) {
577
+ if (!this.pendingApprovalContext) {
578
+ return null;
579
+ }
580
+ let finalText = '';
581
+ let reasoningText = '';
582
+ const commandMessages = [];
583
+ let sawTerminalEvent = null;
584
+ for await (const event of this['continue']({ answer, rejectionReason })) {
585
+ onEvent?.(event);
586
+ switch (event.type) {
587
+ case 'text_delta': {
588
+ const full = event.fullText ?? '';
589
+ onTextChunk?.(full, event.delta);
590
+ break;
591
+ }
592
+ case 'reasoning_delta': {
593
+ const full = event.fullText ?? '';
594
+ onReasoningChunk?.(full, event.delta);
595
+ break;
596
+ }
597
+ case 'command_message': {
598
+ onCommandMessage?.(event.message);
599
+ break;
600
+ }
601
+ case 'approval_required': {
602
+ sawTerminalEvent = event;
603
+ const rawInterruption = this.pendingApprovalContext?.interruption;
604
+ return {
605
+ type: 'approval_required',
606
+ approval: {
607
+ agentName: event.approval.agentName,
608
+ toolName: event.approval.toolName,
609
+ argumentsText: event.approval.argumentsText,
610
+ rawInterruption,
611
+ },
612
+ };
613
+ }
614
+ case 'final': {
615
+ sawTerminalEvent = event;
616
+ finalText = event.finalText;
617
+ reasoningText = event.reasoningText ?? '';
618
+ if (event.commandMessages?.length) {
619
+ for (const msg of event.commandMessages) {
620
+ commandMessages.push(msg);
621
+ }
622
+ }
623
+ break;
624
+ }
625
+ case 'error': {
626
+ break;
627
+ }
628
+ default:
629
+ break;
630
+ }
631
+ }
632
+ if (!sawTerminalEvent) {
633
+ return {
634
+ type: 'response',
635
+ commandMessages,
636
+ finalText: finalText || 'Done.',
637
+ ...(reasoningText ? { reasoningText } : {}),
638
+ };
639
+ }
640
+ return {
641
+ type: 'response',
642
+ commandMessages,
643
+ finalText: finalText || 'Done.',
644
+ ...(reasoningText ? { reasoningText } : {}),
645
+ };
646
+ }
647
+ async *#streamEvents(stream, acc, { preserveExistingToolArgs }) {
648
+ const toolCallArgumentsById = this.toolCallArgumentsById;
649
+ if (!preserveExistingToolArgs) {
650
+ toolCallArgumentsById.clear();
651
+ }
652
+ this.textDeltaCount = 0;
653
+ this.reasoningDeltaCount = 0;
654
+ const emitText = (delta) => {
655
+ if (!delta) {
656
+ return null;
657
+ }
658
+ acc.finalOutput += delta;
659
+ this.textDeltaCount++;
660
+ return {
661
+ type: 'text_delta',
662
+ delta,
663
+ fullText: acc.finalOutput,
664
+ };
665
+ };
666
+ const emitReasoning = (delta) => {
667
+ if (!delta || delta.replaceAll('\n', '') === '') {
668
+ return null;
669
+ }
670
+ acc.reasoningOutput += delta;
671
+ this.reasoningDeltaCount++;
672
+ return {
673
+ type: 'reasoning_delta',
674
+ delta,
675
+ fullText: acc.reasoningOutput,
676
+ };
677
+ };
678
+ for await (const event of stream) {
679
+ // Log event type with deduplication for ordering understanding
680
+ // const eventType = event?.type || 'unknown';
681
+ // this.logStreamEvent(eventType, {
682
+ // eventName: event?.name,
683
+ // hasData: !!event?.data,
684
+ // item: event?.item,
685
+ // });
686
+ const delta1 = this.#extractTextDelta(event);
687
+ if (delta1) {
688
+ const e = emitText(delta1);
689
+ if (e)
690
+ yield e;
691
+ }
692
+ if (event?.data) {
693
+ const delta2 = this.#extractTextDelta(event.data);
694
+ if (delta2) {
695
+ const e = emitText(delta2);
696
+ if (e)
697
+ yield e;
698
+ }
699
+ }
700
+ // Handle reasoning items
701
+ const reasoningDelta = (() => {
702
+ // OpenAI style
703
+ const data = event?.data;
704
+ if (data &&
705
+ typeof data === 'object' &&
706
+ data.type === 'model') {
707
+ const eventDetail = data.event;
708
+ if (eventDetail &&
709
+ typeof eventDetail === 'object' &&
710
+ eventDetail.type ===
711
+ 'response.reasoning_summary_text.delta') {
712
+ return eventDetail.delta ?? '';
713
+ }
714
+ }
715
+ // OpenRouter style
716
+ const choices = event?.data?.event?.choices;
717
+ if (!choices)
718
+ return '';
719
+ if (Array.isArray(choices)) {
720
+ return choices[0]?.delta?.reasoning ?? '';
721
+ }
722
+ if (typeof choices === 'object') {
723
+ const byZero = choices['0'];
724
+ const first = byZero ?? choices[Object.keys(choices)[0]];
725
+ return first?.delta?.reasoning ?? '';
726
+ }
727
+ return '';
728
+ })();
729
+ if (reasoningDelta) {
730
+ const e = emitReasoning(reasoningDelta);
731
+ if (e)
732
+ yield e;
733
+ }
734
+ const maybeEmitCommandMessagesFromItems = (items) => {
735
+ this.#attachCachedArguments(items, toolCallArgumentsById);
736
+ const commandMessages = extractCommandMessages(items);
737
+ const out = [];
738
+ for (const cmdMsg of commandMessages) {
739
+ if (acc.emittedCommandIds.has(cmdMsg.id)) {
740
+ continue;
741
+ }
742
+ if (cmdMsg.isApprovalRejection) {
743
+ continue;
744
+ }
745
+ acc.emittedCommandIds.add(cmdMsg.id);
746
+ out.push({ type: 'command_message', message: cmdMsg });
747
+ }
748
+ return out;
749
+ };
750
+ if (event?.type === 'run_item_stream_event') {
751
+ this.#captureToolCallArguments(event.item, toolCallArgumentsById);
752
+ // Emit tool_started event when a function_call is detected
753
+ const rawItem = event.item?.rawItem ?? event.item;
754
+ if (rawItem?.type === 'function_call') {
755
+ const callId = rawItem.callId ??
756
+ rawItem.call_id ??
757
+ rawItem.tool_call_id ??
758
+ rawItem.toolCallId ??
759
+ rawItem.id;
760
+ if (callId) {
761
+ const toolName = rawItem.name ?? event.item?.name;
762
+ const args = rawItem.arguments ??
763
+ rawItem.args ??
764
+ event.item?.arguments ??
765
+ event.item?.args;
766
+ // Providers sometimes surface arguments as a JSON string.
767
+ // Normalize here so downstream UI (pending/running display)
768
+ // can reliably render parameters.
769
+ const normalizedArgs = (() => {
770
+ if (typeof args !== 'string') {
771
+ return args;
772
+ }
773
+ const trimmed = args.trim();
774
+ if (!trimmed) {
775
+ return args;
776
+ }
777
+ try {
778
+ return JSON.parse(trimmed);
779
+ }
780
+ catch {
781
+ return args;
782
+ }
783
+ })();
784
+ yield {
785
+ type: 'tool_started',
786
+ toolCallId: callId,
787
+ toolName: toolName ?? 'unknown',
788
+ arguments: normalizedArgs,
789
+ };
790
+ }
791
+ }
792
+ for (const e of maybeEmitCommandMessagesFromItems([
793
+ event.item,
794
+ ])) {
795
+ yield e;
796
+ }
797
+ }
798
+ else if (event?.type === 'tool_call_output_item' ||
799
+ event?.rawItem?.type === 'function_call_output') {
800
+ this.#captureToolCallArguments(event, toolCallArgumentsById);
801
+ for (const e of maybeEmitCommandMessagesFromItems([event])) {
802
+ yield e;
803
+ }
804
+ }
805
+ }
806
+ await stream.completed;
807
+ this.flushStreamEventLog();
808
+ }
809
+ #captureToolCallArguments(item, toolCallArgumentsById) {
810
+ const rawItem = item?.rawItem ?? item;
811
+ if (!rawItem) {
812
+ return;
813
+ }
814
+ if (rawItem?.type !== 'function_call') {
815
+ return;
816
+ }
817
+ const callId = rawItem.callId ??
818
+ rawItem.call_id ??
819
+ rawItem.tool_call_id ??
820
+ rawItem.toolCallId ??
821
+ rawItem.id;
822
+ if (!callId) {
823
+ return;
824
+ }
825
+ const args = rawItem.arguments ?? rawItem.args ?? item?.arguments ?? item?.args;
826
+ if (!args) {
827
+ return;
828
+ }
829
+ toolCallArgumentsById.set(callId, args);
830
+ }
831
+ #attachCachedArguments(items = [], toolCallArgumentsById) {
832
+ if (!items?.length) {
833
+ return;
834
+ }
835
+ for (const item of items) {
836
+ if (!item) {
837
+ continue;
838
+ }
839
+ if (item.arguments ||
840
+ item.args ||
841
+ item?.rawItem?.arguments ||
842
+ item?.rawItem?.args) {
843
+ continue;
844
+ }
845
+ const rawItem = item?.rawItem ?? item;
846
+ const callId = rawItem?.callId ??
847
+ rawItem?.call_id ??
848
+ rawItem?.tool_call_id ??
849
+ rawItem?.toolCallId ??
850
+ rawItem?.id ??
851
+ item?.callId ??
852
+ item?.call_id ??
853
+ item?.tool_call_id ??
854
+ item?.toolCallId ??
855
+ item?.id;
856
+ if (!callId) {
857
+ continue;
858
+ }
859
+ const args = toolCallArgumentsById.get(callId);
860
+ if (!args) {
861
+ continue;
862
+ }
863
+ item.arguments = args;
864
+ }
865
+ }
866
+ #extractTextDelta(payload) {
867
+ if (payload === null || payload === undefined) {
868
+ return null;
869
+ }
870
+ if (typeof payload === 'string') {
871
+ return payload || null;
872
+ }
873
+ if (typeof payload !== 'object') {
874
+ return null;
875
+ }
876
+ const type = typeof payload.type === 'string' ? payload.type : '';
877
+ const looksLikeOutput = typeof type === 'string' && type.includes('output_text');
878
+ const hasOutputProperties = Boolean(payload.delta ??
879
+ payload.output_text ??
880
+ payload.text ??
881
+ payload.content);
882
+ if (!looksLikeOutput && !hasOutputProperties) {
883
+ return null;
884
+ }
885
+ const deltaCandidate = payload.delta ??
886
+ payload.output_text ??
887
+ payload.text ??
888
+ payload.content;
889
+ const text = this.#coerceToText(deltaCandidate);
890
+ return text || null;
891
+ }
892
+ #coerceToText(value) {
893
+ if (value === null || value === undefined) {
894
+ return '';
895
+ }
896
+ if (typeof value === 'string') {
897
+ return value;
898
+ }
899
+ if (typeof value === 'number' || typeof value === 'boolean') {
900
+ return String(value);
901
+ }
902
+ if (Array.isArray(value)) {
903
+ return value
904
+ .map(entry => this.#coerceToText(entry))
905
+ .filter(Boolean)
906
+ .join('');
907
+ }
908
+ if (typeof value === 'object') {
909
+ const record = value;
910
+ const candidates = ['text', 'value', 'content', 'delta'];
911
+ for (const field of candidates) {
912
+ if (field in record) {
913
+ const text = this.#coerceToText(record[field]);
914
+ if (text) {
915
+ return text;
916
+ }
917
+ }
918
+ }
919
+ }
920
+ return '';
921
+ }
922
+ #buildResult(result, finalOutputOverride, reasoningOutputOverride, emittedCommandIds) {
923
+ if (result.interruptions && result.interruptions.length > 0) {
924
+ const interruption = result.interruptions[0];
925
+ this.pendingApprovalContext = {
926
+ state: result.state,
927
+ interruption,
928
+ emittedCommandIds: emittedCommandIds ?? new Set(),
929
+ toolCallArgumentsById: new Map(this.toolCallArgumentsById),
930
+ };
931
+ let argumentsText = '';
932
+ const toolName = interruption.name;
933
+ // For shell_call (built-in shell tool), extract commands from action
934
+ // For function tools (bash, shell), extract from arguments
935
+ if (interruption.type === 'shell_call') {
936
+ if (interruption.action?.commands) {
937
+ argumentsText = Array.isArray(interruption.action.commands)
938
+ ? interruption.action.commands.join('\n')
939
+ : String(interruption.action.commands);
940
+ }
941
+ }
942
+ else {
943
+ argumentsText = getCommandFromArgs(interruption.arguments);
944
+ }
945
+ const callId = interruption?.rawItem?.callId ??
946
+ interruption?.callId ??
947
+ interruption?.call_id ??
948
+ interruption?.tool_call_id ??
949
+ interruption?.toolCallId ??
950
+ interruption?.id;
951
+ return {
952
+ type: 'approval_required',
953
+ approval: {
954
+ agentName: interruption.agent?.name ?? 'Agent',
955
+ toolName: toolName ?? 'Unknown Tool',
956
+ argumentsText,
957
+ rawInterruption: interruption,
958
+ ...(callId ? { callId: String(callId) } : {}),
959
+ },
960
+ };
961
+ }
962
+ this.pendingApprovalContext = null;
963
+ const allCommandMessages = extractCommandMessages(result.newItems || result.history || []);
964
+ // Filter out commands that were already emitted in real-time
965
+ const commandMessages = emittedCommandIds
966
+ ? allCommandMessages.filter(msg => !emittedCommandIds.has(msg.id))
967
+ : allCommandMessages;
968
+ const visibleCommandMessages = commandMessages.filter(msg => !msg.isApprovalRejection);
969
+ const response = {
970
+ type: 'response',
971
+ commandMessages: visibleCommandMessages,
972
+ finalText: finalOutputOverride ?? result.finalOutput ?? 'Done.',
973
+ reasoningText: reasoningOutputOverride,
974
+ };
975
+ return response;
976
+ }
977
+ }
978
+ //# sourceMappingURL=conversation-session.js.map