@qduc/term2 0.12.0 → 0.14.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 (635) hide show
  1. package/README.md +6 -1
  2. package/dist/agent.d.ts +3 -0
  3. package/dist/agent.d.ts.map +1 -1
  4. package/dist/agent.js +38 -14
  5. package/dist/agent.js.map +1 -1
  6. package/dist/app.d.ts.map +1 -1
  7. package/dist/app.js +91 -17
  8. package/dist/app.js.map +1 -1
  9. package/dist/cli.js +34 -23
  10. package/dist/cli.js.map +1 -1
  11. package/dist/commands/auto-approve-command.d.ts.map +1 -1
  12. package/dist/commands/auto-approve-command.js +12 -4
  13. package/dist/commands/auto-approve-command.js.map +1 -1
  14. package/dist/commands/compact-command.d.ts +6 -0
  15. package/dist/commands/compact-command.d.ts.map +1 -0
  16. package/dist/commands/compact-command.js +12 -0
  17. package/dist/commands/compact-command.js.map +1 -0
  18. package/dist/commands/copy-command.d.ts +3 -1
  19. package/dist/commands/copy-command.d.ts.map +1 -1
  20. package/dist/commands/copy-command.js +36 -9
  21. package/dist/commands/copy-command.js.map +1 -1
  22. package/dist/commands/sandbox-command.d.ts.map +1 -1
  23. package/dist/commands/sandbox-command.js +6 -1
  24. package/dist/commands/sandbox-command.js.map +1 -1
  25. package/dist/components/InputBox.d.ts +1 -2
  26. package/dist/components/InputBox.d.ts.map +1 -1
  27. package/dist/components/InputBox.js +5 -1
  28. package/dist/components/InputBox.js.map +1 -1
  29. package/dist/components/input/ApplicationInputSurface.d.ts +7 -2
  30. package/dist/components/input/ApplicationInputSurface.d.ts.map +1 -1
  31. package/dist/components/input/ApplicationInputSurface.js +7 -1
  32. package/dist/components/input/ApplicationInputSurface.js.map +1 -1
  33. package/dist/components/input/CopyMenuSession.d.ts +16 -0
  34. package/dist/components/input/CopyMenuSession.d.ts.map +1 -0
  35. package/dist/components/input/CopyMenuSession.js +49 -0
  36. package/dist/components/input/CopyMenuSession.js.map +1 -0
  37. package/dist/components/input/FirstRunSetupPrompt.d.ts +9 -0
  38. package/dist/components/input/FirstRunSetupPrompt.d.ts.map +1 -0
  39. package/dist/components/input/FirstRunSetupPrompt.js +20 -0
  40. package/dist/components/input/FirstRunSetupPrompt.js.map +1 -0
  41. package/dist/components/input/MentorPoolMenuSession.d.ts +9 -0
  42. package/dist/components/input/MentorPoolMenuSession.d.ts.map +1 -0
  43. package/dist/components/input/MentorPoolMenuSession.js +131 -0
  44. package/dist/components/input/MentorPoolMenuSession.js.map +1 -0
  45. package/dist/components/input/MenuSurface.d.ts.map +1 -1
  46. package/dist/components/input/MenuSurface.js +16 -2
  47. package/dist/components/input/MenuSurface.js.map +1 -1
  48. package/dist/components/input/ModelMenuSession.d.ts.map +1 -1
  49. package/dist/components/input/ModelMenuSession.js +11 -1
  50. package/dist/components/input/ModelMenuSession.js.map +1 -1
  51. package/dist/components/input/ProviderMenuSession.d.ts.map +1 -1
  52. package/dist/components/input/ProviderMenuSession.js +8 -2
  53. package/dist/components/input/ProviderMenuSession.js.map +1 -1
  54. package/dist/components/input/SettingsMenuSession.d.ts.map +1 -1
  55. package/dist/components/input/SettingsMenuSession.js +35 -22
  56. package/dist/components/input/SettingsMenuSession.js.map +1 -1
  57. package/dist/components/input/SkillsMenuSession.d.ts +3 -0
  58. package/dist/components/input/SkillsMenuSession.d.ts.map +1 -1
  59. package/dist/components/input/SkillsMenuSession.js +6 -12
  60. package/dist/components/input/SkillsMenuSession.js.map +1 -1
  61. package/dist/components/input/SlashMenuSession.d.ts +11 -3
  62. package/dist/components/input/SlashMenuSession.d.ts.map +1 -1
  63. package/dist/components/input/SlashMenuSession.js +54 -42
  64. package/dist/components/input/SlashMenuSession.js.map +1 -1
  65. package/dist/components/input/menu-controller.d.ts.map +1 -1
  66. package/dist/components/input/menu-controller.js +18 -1
  67. package/dist/components/input/menu-controller.js.map +1 -1
  68. package/dist/components/input/menu-registry.d.ts.map +1 -1
  69. package/dist/components/input/menu-registry.js +4 -0
  70. package/dist/components/input/menu-registry.js.map +1 -1
  71. package/dist/components/input/menu-types.d.ts +12 -0
  72. package/dist/components/input/menu-types.d.ts.map +1 -1
  73. package/dist/components/input/triggers.d.ts.map +1 -1
  74. package/dist/components/input/triggers.js +33 -0
  75. package/dist/components/input/triggers.js.map +1 -1
  76. package/dist/components/layout/BackgroundTaskManager.d.ts.map +1 -1
  77. package/dist/components/layout/BackgroundTaskManager.js +28 -10
  78. package/dist/components/layout/BackgroundTaskManager.js.map +1 -1
  79. package/dist/components/layout/BackgroundTasksPanel.d.ts +4 -1
  80. package/dist/components/layout/BackgroundTasksPanel.d.ts.map +1 -1
  81. package/dist/components/layout/BackgroundTasksPanel.js +58 -12
  82. package/dist/components/layout/BackgroundTasksPanel.js.map +1 -1
  83. package/dist/components/layout/BottomArea.d.ts +16 -2
  84. package/dist/components/layout/BottomArea.d.ts.map +1 -1
  85. package/dist/components/layout/BottomArea.js +7 -4
  86. package/dist/components/layout/BottomArea.js.map +1 -1
  87. package/dist/components/layout/StatusBar.d.ts.map +1 -1
  88. package/dist/components/layout/StatusBar.js +66 -51
  89. package/dist/components/layout/StatusBar.js.map +1 -1
  90. package/dist/components/menu/CopyMenu.d.ts +10 -0
  91. package/dist/components/menu/CopyMenu.d.ts.map +1 -0
  92. package/dist/components/menu/CopyMenu.js +20 -0
  93. package/dist/components/menu/CopyMenu.js.map +1 -0
  94. package/dist/components/menu/MentorPoolSelectionMenu.d.ts +13 -0
  95. package/dist/components/menu/MentorPoolSelectionMenu.d.ts.map +1 -0
  96. package/dist/components/menu/MentorPoolSelectionMenu.js +98 -0
  97. package/dist/components/menu/MentorPoolSelectionMenu.js.map +1 -0
  98. package/dist/components/menu/ModelSelectionMenu.d.ts +2 -0
  99. package/dist/components/menu/ModelSelectionMenu.d.ts.map +1 -1
  100. package/dist/components/menu/ModelSelectionMenu.js +26 -7
  101. package/dist/components/menu/ModelSelectionMenu.js.map +1 -1
  102. package/dist/components/menu/ProviderSelectionMenu.d.ts +1 -0
  103. package/dist/components/menu/ProviderSelectionMenu.d.ts.map +1 -1
  104. package/dist/components/menu/ProviderSelectionMenu.js +12 -4
  105. package/dist/components/menu/ProviderSelectionMenu.js.map +1 -1
  106. package/dist/components/menu/SlashCommandMenu.d.ts.map +1 -1
  107. package/dist/components/menu/SlashCommandMenu.js +12 -9
  108. package/dist/components/menu/SlashCommandMenu.js.map +1 -1
  109. package/dist/components/message/CommandMessage.js +4 -0
  110. package/dist/components/message/CommandMessage.js.map +1 -1
  111. package/dist/components/message/SubagentActivityMessage.d.ts +1 -0
  112. package/dist/components/message/SubagentActivityMessage.d.ts.map +1 -1
  113. package/dist/components/message/SubagentActivityMessage.js +14 -1
  114. package/dist/components/message/SubagentActivityMessage.js.map +1 -1
  115. package/dist/components/prompt/ApprovalPrompt.d.ts.map +1 -1
  116. package/dist/components/prompt/ApprovalPrompt.js +0 -25
  117. package/dist/components/prompt/ApprovalPrompt.js.map +1 -1
  118. package/dist/context/InputContext.d.ts +1 -1
  119. package/dist/context/InputContext.d.ts.map +1 -1
  120. package/dist/context/InputContext.js +4 -0
  121. package/dist/context/InputContext.js.map +1 -1
  122. package/dist/contracts/application-stream.d.ts +13 -0
  123. package/dist/contracts/application-stream.d.ts.map +1 -1
  124. package/dist/contracts/provider-input.d.ts +15 -0
  125. package/dist/contracts/provider-input.d.ts.map +1 -1
  126. package/dist/contracts/provider-input.js +6 -1
  127. package/dist/contracts/provider-input.js.map +1 -1
  128. package/dist/hooks/conversation-ui-reducer.d.ts +6 -0
  129. package/dist/hooks/conversation-ui-reducer.d.ts.map +1 -1
  130. package/dist/hooks/conversation-ui-reducer.js +3 -0
  131. package/dist/hooks/conversation-ui-reducer.js.map +1 -1
  132. package/dist/hooks/settings-completion-config.d.ts.map +1 -1
  133. package/dist/hooks/settings-completion-config.js +12 -2
  134. package/dist/hooks/settings-completion-config.js.map +1 -1
  135. package/dist/hooks/use-app-commands.d.ts +4 -1
  136. package/dist/hooks/use-app-commands.d.ts.map +1 -1
  137. package/dist/hooks/use-app-commands.js +6 -2
  138. package/dist/hooks/use-app-commands.js.map +1 -1
  139. package/dist/hooks/use-app-keyboard-shortcuts.d.ts +7 -1
  140. package/dist/hooks/use-app-keyboard-shortcuts.d.ts.map +1 -1
  141. package/dist/hooks/use-app-keyboard-shortcuts.js +77 -7
  142. package/dist/hooks/use-app-keyboard-shortcuts.js.map +1 -1
  143. package/dist/hooks/use-conversation.d.ts +6 -2
  144. package/dist/hooks/use-conversation.d.ts.map +1 -1
  145. package/dist/hooks/use-conversation.js +21 -4
  146. package/dist/hooks/use-conversation.js.map +1 -1
  147. package/dist/hooks/use-debounced-value.d.ts +13 -0
  148. package/dist/hooks/use-debounced-value.d.ts.map +1 -0
  149. package/dist/hooks/use-debounced-value.js +27 -0
  150. package/dist/hooks/use-debounced-value.js.map +1 -0
  151. package/dist/hooks/use-first-run-setup.d.ts +24 -0
  152. package/dist/hooks/use-first-run-setup.d.ts.map +1 -0
  153. package/dist/hooks/use-first-run-setup.js +114 -0
  154. package/dist/hooks/use-first-run-setup.js.map +1 -0
  155. package/dist/hooks/use-mentor-pool-selection.d.ts +103 -0
  156. package/dist/hooks/use-mentor-pool-selection.d.ts.map +1 -0
  157. package/dist/hooks/use-mentor-pool-selection.js +642 -0
  158. package/dist/hooks/use-mentor-pool-selection.js.map +1 -0
  159. package/dist/hooks/use-model-selection.d.ts +1 -0
  160. package/dist/hooks/use-model-selection.d.ts.map +1 -1
  161. package/dist/hooks/use-model-selection.js +44 -1
  162. package/dist/hooks/use-model-selection.js.map +1 -1
  163. package/dist/hooks/use-provider-selection.d.ts +5 -1
  164. package/dist/hooks/use-provider-selection.d.ts.map +1 -1
  165. package/dist/hooks/use-provider-selection.js +37 -12
  166. package/dist/hooks/use-provider-selection.js.map +1 -1
  167. package/dist/hooks/use-slash-commands.d.ts +0 -1
  168. package/dist/hooks/use-slash-commands.d.ts.map +1 -1
  169. package/dist/hooks/use-slash-commands.js +1 -9
  170. package/dist/hooks/use-slash-commands.js.map +1 -1
  171. package/dist/lib/agent-chat-service.d.ts +3 -6
  172. package/dist/lib/agent-chat-service.d.ts.map +1 -1
  173. package/dist/lib/agent-chat-service.js +20 -6
  174. package/dist/lib/agent-chat-service.js.map +1 -1
  175. package/dist/lib/agent-client.d.ts +20 -2
  176. package/dist/lib/agent-client.d.ts.map +1 -1
  177. package/dist/lib/agent-client.js +147 -3
  178. package/dist/lib/agent-client.js.map +1 -1
  179. package/dist/lib/agent-configuration.d.ts +3 -0
  180. package/dist/lib/agent-configuration.d.ts.map +1 -1
  181. package/dist/lib/agent-configuration.js +5 -0
  182. package/dist/lib/agent-configuration.js.map +1 -1
  183. package/dist/lib/agent-factory.d.ts +3 -0
  184. package/dist/lib/agent-factory.d.ts.map +1 -1
  185. package/dist/lib/agent-factory.js +15 -6
  186. package/dist/lib/agent-factory.js.map +1 -1
  187. package/dist/lib/input-owner.d.ts +3 -0
  188. package/dist/lib/input-owner.d.ts.map +1 -1
  189. package/dist/lib/input-owner.js +5 -0
  190. package/dist/lib/input-owner.js.map +1 -1
  191. package/dist/lib/subagent-bridge.d.ts +2 -0
  192. package/dist/lib/subagent-bridge.d.ts.map +1 -1
  193. package/dist/lib/subagent-bridge.js +4 -1
  194. package/dist/lib/subagent-bridge.js.map +1 -1
  195. package/dist/prompts/background-shell.d.ts +3 -0
  196. package/dist/prompts/background-shell.d.ts.map +1 -0
  197. package/dist/prompts/background-shell.js +11 -0
  198. package/dist/prompts/background-shell.js.map +1 -0
  199. package/dist/prompts/background-shell.ts +10 -0
  200. package/dist/prompts/context-compaction.d.ts +4 -0
  201. package/dist/prompts/context-compaction.d.ts.map +1 -0
  202. package/dist/prompts/context-compaction.js +18 -0
  203. package/dist/prompts/context-compaction.js.map +1 -0
  204. package/dist/prompts/context-compaction.ts +23 -0
  205. package/dist/prompts/explorer-delegation-contract.test.ts +22 -0
  206. package/dist/prompts/gpt-5.6.md +1 -1
  207. package/dist/prompts/kimi.md +1 -1
  208. package/dist/prompts/orchestrator-prompt.test.ts +7 -0
  209. package/dist/prompts/orchestrator.md +1 -1
  210. package/dist/prompts/plan-mode-info.md +2 -2
  211. package/dist/prompts/prompt-constructor.d.ts +1 -0
  212. package/dist/prompts/prompt-constructor.d.ts.map +1 -1
  213. package/dist/prompts/prompt-constructor.js +5 -1
  214. package/dist/prompts/prompt-constructor.js.map +1 -1
  215. package/dist/prompts/prompt-constructor.test.ts +16 -1
  216. package/dist/prompts/prompt-constructor.ts +7 -0
  217. package/dist/prompts/subagent-delegation.d.ts.map +1 -1
  218. package/dist/prompts/subagent-delegation.js +5 -3
  219. package/dist/prompts/subagent-delegation.js.map +1 -1
  220. package/dist/prompts/subagent-delegation.test.ts +10 -0
  221. package/dist/prompts/subagent-delegation.ts +5 -3
  222. package/dist/prompts/subagents/explorer.md +10 -5
  223. package/dist/prompts/subagents/librarian.md +1 -1
  224. package/dist/prompts/subagents/worker.md +2 -2
  225. package/dist/providers/aborted-stream-recorder.d.ts +20 -0
  226. package/dist/providers/aborted-stream-recorder.d.ts.map +1 -0
  227. package/dist/providers/aborted-stream-recorder.js +63 -0
  228. package/dist/providers/aborted-stream-recorder.js.map +1 -0
  229. package/dist/providers/codex-auth.d.ts +6 -0
  230. package/dist/providers/codex-auth.d.ts.map +1 -0
  231. package/dist/providers/codex-auth.js +35 -0
  232. package/dist/providers/codex-auth.js.map +1 -0
  233. package/dist/providers/codex-responses-model.d.ts +7 -2
  234. package/dist/providers/codex-responses-model.d.ts.map +1 -1
  235. package/dist/providers/codex-responses-model.js +88 -48
  236. package/dist/providers/codex-responses-model.js.map +1 -1
  237. package/dist/providers/codex.provider.d.ts +5 -3
  238. package/dist/providers/codex.provider.d.ts.map +1 -1
  239. package/dist/providers/codex.provider.js +27 -39
  240. package/dist/providers/codex.provider.js.map +1 -1
  241. package/dist/providers/model-catalog/catalog.d.ts +35 -2
  242. package/dist/providers/model-catalog/catalog.d.ts.map +1 -1
  243. package/dist/providers/model-catalog/catalog.generated.d.ts +406 -166
  244. package/dist/providers/model-catalog/catalog.generated.d.ts.map +1 -1
  245. package/dist/providers/model-catalog/catalog.generated.js +406 -166
  246. package/dist/providers/model-catalog/catalog.generated.js.map +1 -1
  247. package/dist/providers/model-catalog/catalog.js +93 -29
  248. package/dist/providers/model-catalog/catalog.js.map +1 -1
  249. package/dist/providers/openai-chat-completions-model.d.ts +2 -1
  250. package/dist/providers/openai-chat-completions-model.d.ts.map +1 -1
  251. package/dist/providers/openai-chat-completions-model.js +223 -53
  252. package/dist/providers/openai-chat-completions-model.js.map +1 -1
  253. package/dist/providers/openai-compatible-lazy.d.ts.map +1 -1
  254. package/dist/providers/openai-compatible-lazy.js +2 -1
  255. package/dist/providers/openai-compatible-lazy.js.map +1 -1
  256. package/dist/providers/openai-compatible-middleware.d.ts.map +1 -1
  257. package/dist/providers/openai-compatible-middleware.js +1 -13
  258. package/dist/providers/openai-compatible-middleware.js.map +1 -1
  259. package/dist/providers/openai-compatible-response-normalizer.d.ts +5 -4
  260. package/dist/providers/openai-compatible-response-normalizer.d.ts.map +1 -1
  261. package/dist/providers/openai-compatible-response-normalizer.js +6 -17
  262. package/dist/providers/openai-compatible-response-normalizer.js.map +1 -1
  263. package/dist/providers/openai-compatible.provider.d.ts +1 -0
  264. package/dist/providers/openai-compatible.provider.d.ts.map +1 -1
  265. package/dist/providers/openai-compatible.provider.js +13 -4
  266. package/dist/providers/openai-compatible.provider.js.map +1 -1
  267. package/dist/providers/openai-responses-model.d.ts +9 -1
  268. package/dist/providers/openai-responses-model.d.ts.map +1 -1
  269. package/dist/providers/openai-responses-model.js +34 -12
  270. package/dist/providers/openai-responses-model.js.map +1 -1
  271. package/dist/providers/provider-service.d.ts +1 -0
  272. package/dist/providers/provider-service.d.ts.map +1 -1
  273. package/dist/providers/provider-service.js +4 -0
  274. package/dist/providers/provider-service.js.map +1 -1
  275. package/dist/scripts/eval-context-compaction/runner.d.ts +2 -0
  276. package/dist/scripts/eval-context-compaction/runner.d.ts.map +1 -0
  277. package/dist/scripts/eval-context-compaction/runner.js +159 -0
  278. package/dist/scripts/eval-context-compaction/runner.js.map +1 -0
  279. package/dist/services/agent-runtime/application-run-loop.d.ts +30 -0
  280. package/dist/services/agent-runtime/application-run-loop.d.ts.map +1 -1
  281. package/dist/services/agent-runtime/application-run-loop.js +251 -107
  282. package/dist/services/agent-runtime/application-run-loop.js.map +1 -1
  283. package/dist/services/agent-runtime/context-compaction/index.d.ts +56 -0
  284. package/dist/services/agent-runtime/context-compaction/index.d.ts.map +1 -0
  285. package/dist/services/agent-runtime/context-compaction/index.js +131 -0
  286. package/dist/services/agent-runtime/context-compaction/index.js.map +1 -0
  287. package/dist/services/agent-runtime/context-compaction/local-context-compactor.d.ts +76 -0
  288. package/dist/services/agent-runtime/context-compaction/local-context-compactor.d.ts.map +1 -0
  289. package/dist/services/agent-runtime/context-compaction/local-context-compactor.js +146 -0
  290. package/dist/services/agent-runtime/context-compaction/local-context-compactor.js.map +1 -0
  291. package/dist/services/agent-runtime/generation-guard.d.ts +15 -1
  292. package/dist/services/agent-runtime/generation-guard.d.ts.map +1 -1
  293. package/dist/services/agent-runtime/generation-guard.js +34 -2
  294. package/dist/services/agent-runtime/generation-guard.js.map +1 -1
  295. package/dist/services/agent-runtime/scope-resolver.d.ts.map +1 -1
  296. package/dist/services/agent-runtime/scope-resolver.js +2 -1
  297. package/dist/services/agent-runtime/scope-resolver.js.map +1 -1
  298. package/dist/services/agent-stream.d.ts.map +1 -1
  299. package/dist/services/agent-stream.js +2 -1
  300. package/dist/services/agent-stream.js.map +1 -1
  301. package/dist/services/approval/approval-decision-executor.d.ts.map +1 -1
  302. package/dist/services/approval/approval-decision-executor.js +5 -2
  303. package/dist/services/approval/approval-decision-executor.js.map +1 -1
  304. package/dist/services/approval/approval-decision-policy.d.ts.map +1 -1
  305. package/dist/services/approval/approval-decision-policy.js +0 -2
  306. package/dist/services/approval/approval-decision-policy.js.map +1 -1
  307. package/dist/services/approval/session-read-access.d.ts.map +1 -1
  308. package/dist/services/approval/session-read-access.js +2 -1
  309. package/dist/services/approval/session-read-access.js.map +1 -1
  310. package/dist/services/approval/shell-auto-approval-resolver.d.ts +1 -1
  311. package/dist/services/approval/shell-auto-approval-resolver.d.ts.map +1 -1
  312. package/dist/services/approval/shell-auto-approval-resolver.js +9 -1
  313. package/dist/services/approval/shell-auto-approval-resolver.js.map +1 -1
  314. package/dist/services/approval/tool-approval-batch-coordinator.d.ts.map +1 -1
  315. package/dist/services/approval/tool-approval-batch-coordinator.js +2 -1
  316. package/dist/services/approval/tool-approval-batch-coordinator.js.map +1 -1
  317. package/dist/services/conversation/conversation-admission-workflow.d.ts.map +1 -1
  318. package/dist/services/conversation/conversation-admission-workflow.js +20 -18
  319. package/dist/services/conversation/conversation-admission-workflow.js.map +1 -1
  320. package/dist/services/conversation/conversation-decoder.d.ts.map +1 -1
  321. package/dist/services/conversation/conversation-decoder.js +6 -0
  322. package/dist/services/conversation/conversation-decoder.js.map +1 -1
  323. package/dist/services/conversation/conversation-events.d.ts +34 -1
  324. package/dist/services/conversation/conversation-events.d.ts.map +1 -1
  325. package/dist/services/conversation/conversation-message-projection.d.ts.map +1 -1
  326. package/dist/services/conversation/conversation-message-projection.js +7 -3
  327. package/dist/services/conversation/conversation-message-projection.js.map +1 -1
  328. package/dist/services/conversation/conversation-orchestrator.d.ts +2 -0
  329. package/dist/services/conversation/conversation-orchestrator.d.ts.map +1 -1
  330. package/dist/services/conversation/conversation-orchestrator.js +113 -1
  331. package/dist/services/conversation/conversation-orchestrator.js.map +1 -1
  332. package/dist/services/conversation/conversation-orchestrator.types.d.ts +3 -1
  333. package/dist/services/conversation/conversation-orchestrator.types.d.ts.map +1 -1
  334. package/dist/services/conversation/conversation-replay.d.ts.map +1 -1
  335. package/dist/services/conversation/conversation-replay.js +45 -0
  336. package/dist/services/conversation/conversation-replay.js.map +1 -1
  337. package/dist/services/conversation/conversation-result-builder.d.ts.map +1 -1
  338. package/dist/services/conversation/conversation-result-builder.js +14 -2
  339. package/dist/services/conversation/conversation-result-builder.js.map +1 -1
  340. package/dist/services/conversation/conversation-service.d.ts +1 -0
  341. package/dist/services/conversation/conversation-service.d.ts.map +1 -1
  342. package/dist/services/conversation/conversation-service.js +74 -0
  343. package/dist/services/conversation/conversation-service.js.map +1 -1
  344. package/dist/services/conversation/conversation-state-projector.d.ts +7 -1
  345. package/dist/services/conversation/conversation-state-projector.d.ts.map +1 -1
  346. package/dist/services/conversation/conversation-state-projector.js +20 -3
  347. package/dist/services/conversation/conversation-state-projector.js.map +1 -1
  348. package/dist/services/conversation/conversation-state-schema.d.ts +8 -4
  349. package/dist/services/conversation/conversation-state-schema.d.ts.map +1 -1
  350. package/dist/services/conversation/conversation-state-schema.js +24 -2
  351. package/dist/services/conversation/conversation-state-schema.js.map +1 -1
  352. package/dist/services/conversation/conversation-store.d.ts +11 -0
  353. package/dist/services/conversation/conversation-store.d.ts.map +1 -1
  354. package/dist/services/conversation/conversation-store.js +23 -3
  355. package/dist/services/conversation/conversation-store.js.map +1 -1
  356. package/dist/services/conversation-agent-client.d.ts +9 -0
  357. package/dist/services/conversation-agent-client.d.ts.map +1 -1
  358. package/dist/services/cost/model-cost.d.ts +13 -2
  359. package/dist/services/cost/model-cost.d.ts.map +1 -1
  360. package/dist/services/cost/model-cost.js +1 -0
  361. package/dist/services/cost/model-cost.js.map +1 -1
  362. package/dist/services/cost/pricing.d.ts.map +1 -1
  363. package/dist/services/cost/pricing.js +26 -20
  364. package/dist/services/cost/pricing.js.map +1 -1
  365. package/dist/services/execution-context.d.ts +31 -0
  366. package/dist/services/execution-context.d.ts.map +1 -1
  367. package/dist/services/execution-context.js +59 -0
  368. package/dist/services/execution-context.js.map +1 -1
  369. package/dist/services/file-service.d.ts.map +1 -1
  370. package/dist/services/file-service.js +12 -3
  371. package/dist/services/file-service.js.map +1 -1
  372. package/dist/services/large-uncached-input-guard.d.ts +26 -1
  373. package/dist/services/large-uncached-input-guard.d.ts.map +1 -1
  374. package/dist/services/large-uncached-input-guard.js +73 -38
  375. package/dist/services/large-uncached-input-guard.js.map +1 -1
  376. package/dist/services/logging/conversation-log-events.d.ts +15 -2
  377. package/dist/services/logging/conversation-log-events.d.ts.map +1 -1
  378. package/dist/services/logging/conversation-log-events.js.map +1 -1
  379. package/dist/services/logging/conversation-logger.d.ts.map +1 -1
  380. package/dist/services/logging/conversation-logger.js +11 -0
  381. package/dist/services/logging/conversation-logger.js.map +1 -1
  382. package/dist/services/logging/logging-contract.d.ts.map +1 -1
  383. package/dist/services/logging/logging-contract.js +4 -0
  384. package/dist/services/logging/logging-contract.js.map +1 -1
  385. package/dist/services/logging/provider-traffic.d.ts +1 -1
  386. package/dist/services/logging/provider-traffic.d.ts.map +1 -1
  387. package/dist/services/logging/provider-traffic.js +10 -3
  388. package/dist/services/logging/provider-traffic.js.map +1 -1
  389. package/dist/services/model-service.d.ts +7 -0
  390. package/dist/services/model-service.d.ts.map +1 -1
  391. package/dist/services/model-service.js +21 -0
  392. package/dist/services/model-service.js.map +1 -1
  393. package/dist/services/models/model-catalog-session.d.ts +2 -0
  394. package/dist/services/models/model-catalog-session.d.ts.map +1 -1
  395. package/dist/services/models/model-catalog-session.js +9 -2
  396. package/dist/services/models/model-catalog-session.js.map +1 -1
  397. package/dist/services/provider-continuity.d.ts +15 -0
  398. package/dist/services/provider-continuity.d.ts.map +1 -1
  399. package/dist/services/provider-continuity.js +33 -0
  400. package/dist/services/provider-continuity.js.map +1 -1
  401. package/dist/services/retry/recovery-executor.d.ts.map +1 -1
  402. package/dist/services/retry/recovery-executor.js +12 -5
  403. package/dist/services/retry/recovery-executor.js.map +1 -1
  404. package/dist/services/retry/retry-classifier.d.ts.map +1 -1
  405. package/dist/services/retry/retry-classifier.js +2 -1
  406. package/dist/services/retry/retry-classifier.js.map +1 -1
  407. package/dist/services/retry/retry-error-classification.d.ts +19 -0
  408. package/dist/services/retry/retry-error-classification.d.ts.map +1 -1
  409. package/dist/services/retry/retry-error-classification.js +54 -0
  410. package/dist/services/retry/retry-error-classification.js.map +1 -1
  411. package/dist/services/service-interfaces.d.ts +15 -0
  412. package/dist/services/service-interfaces.d.ts.map +1 -1
  413. package/dist/services/session/background-task-control.d.ts +7 -2
  414. package/dist/services/session/background-task-control.d.ts.map +1 -1
  415. package/dist/services/session/background-task-control.js +43 -9
  416. package/dist/services/session/background-task-control.js.map +1 -1
  417. package/dist/services/session/background-task-liveness.d.ts +24 -0
  418. package/dist/services/session/background-task-liveness.d.ts.map +1 -0
  419. package/dist/services/session/background-task-liveness.js +23 -0
  420. package/dist/services/session/background-task-liveness.js.map +1 -0
  421. package/dist/services/session/session-access-state.d.ts.map +1 -1
  422. package/dist/services/session/session-access-state.js +5 -4
  423. package/dist/services/session/session-access-state.js.map +1 -1
  424. package/dist/services/session/session-client-factory.d.ts +11 -1
  425. package/dist/services/session/session-client-factory.d.ts.map +1 -1
  426. package/dist/services/session/session-client-factory.js +28 -1
  427. package/dist/services/session/session-client-factory.js.map +1 -1
  428. package/dist/services/session/session-composition.d.ts +7 -0
  429. package/dist/services/session/session-composition.d.ts.map +1 -1
  430. package/dist/services/session/session-composition.js +80 -0
  431. package/dist/services/session/session-composition.js.map +1 -1
  432. package/dist/services/session/session-input-planner.d.ts +16 -0
  433. package/dist/services/session/session-input-planner.d.ts.map +1 -1
  434. package/dist/services/session/session-input-planner.js +117 -10
  435. package/dist/services/session/session-input-planner.js.map +1 -1
  436. package/dist/services/session/session-manager.d.ts +3 -0
  437. package/dist/services/session/session-manager.d.ts.map +1 -1
  438. package/dist/services/session/session-manager.js +6 -0
  439. package/dist/services/session/session-manager.js.map +1 -1
  440. package/dist/services/session/session-stream-processor.d.ts +1 -0
  441. package/dist/services/session/session-stream-processor.d.ts.map +1 -1
  442. package/dist/services/session/session-stream-processor.js +16 -1
  443. package/dist/services/session/session-stream-processor.js.map +1 -1
  444. package/dist/services/session/session-tool-tracker.d.ts +21 -4
  445. package/dist/services/session/session-tool-tracker.d.ts.map +1 -1
  446. package/dist/services/session/session-tool-tracker.js +26 -5
  447. package/dist/services/session/session-tool-tracker.js.map +1 -1
  448. package/dist/services/session/terminal-result-collector.d.ts.map +1 -1
  449. package/dist/services/session/terminal-result-collector.js +12 -0
  450. package/dist/services/session/terminal-result-collector.js.map +1 -1
  451. package/dist/services/session/turn-workflow.d.ts.map +1 -1
  452. package/dist/services/session/turn-workflow.js +4 -0
  453. package/dist/services/session/turn-workflow.js.map +1 -1
  454. package/dist/services/settings/settings-path.d.ts +6 -0
  455. package/dist/services/settings/settings-path.d.ts.map +1 -0
  456. package/dist/services/settings/settings-path.js +15 -0
  457. package/dist/services/settings/settings-path.js.map +1 -0
  458. package/dist/services/settings/settings-schema.d.ts +59 -1
  459. package/dist/services/settings/settings-schema.d.ts.map +1 -1
  460. package/dist/services/settings/settings-schema.js +44 -3
  461. package/dist/services/settings/settings-schema.js.map +1 -1
  462. package/dist/services/settings/settings-service.d.ts +8 -0
  463. package/dist/services/settings/settings-service.d.ts.map +1 -1
  464. package/dist/services/settings/settings-service.js +82 -4
  465. package/dist/services/settings/settings-service.js.map +1 -1
  466. package/dist/services/settings/settings-sources.d.ts.map +1 -1
  467. package/dist/services/settings/settings-sources.js +3 -0
  468. package/dist/services/settings/settings-sources.js.map +1 -1
  469. package/dist/services/shell/background-shell-output-store.d.ts +90 -0
  470. package/dist/services/shell/background-shell-output-store.d.ts.map +1 -0
  471. package/dist/services/shell/background-shell-output-store.js +207 -0
  472. package/dist/services/shell/background-shell-output-store.js.map +1 -0
  473. package/dist/services/shell/background-shell-registry.d.ts +18 -0
  474. package/dist/services/shell/background-shell-registry.d.ts.map +1 -1
  475. package/dist/services/shell/background-shell-registry.js +17 -2
  476. package/dist/services/shell/background-shell-registry.js.map +1 -1
  477. package/dist/services/shell/background-shell-watches.d.ts +141 -0
  478. package/dist/services/shell/background-shell-watches.d.ts.map +1 -0
  479. package/dist/services/shell/background-shell-watches.js +245 -0
  480. package/dist/services/shell/background-shell-watches.js.map +1 -0
  481. package/dist/services/stream-event-processor.d.ts.map +1 -1
  482. package/dist/services/stream-event-processor.js +31 -1
  483. package/dist/services/stream-event-processor.js.map +1 -1
  484. package/dist/services/subagents/execution-runner.d.ts.map +1 -1
  485. package/dist/services/subagents/execution-runner.js +73 -4
  486. package/dist/services/subagents/execution-runner.js.map +1 -1
  487. package/dist/services/subagents/mentor-runner.d.ts.map +1 -1
  488. package/dist/services/subagents/mentor-runner.js +120 -15
  489. package/dist/services/subagents/mentor-runner.js.map +1 -1
  490. package/dist/services/subagents/nested-runner.d.ts.map +1 -1
  491. package/dist/services/subagents/nested-runner.js +106 -29
  492. package/dist/services/subagents/nested-runner.js.map +1 -1
  493. package/dist/services/subagents/role-loader.d.ts +6 -0
  494. package/dist/services/subagents/role-loader.d.ts.map +1 -1
  495. package/dist/services/subagents/role-loader.js +6 -1
  496. package/dist/services/subagents/role-loader.js.map +1 -1
  497. package/dist/services/subagents/subagent-async-registry.d.ts.map +1 -1
  498. package/dist/services/subagents/subagent-async-registry.js +39 -5
  499. package/dist/services/subagents/subagent-async-registry.js.map +1 -1
  500. package/dist/services/subagents/subagent-notification-store.d.ts +20 -1
  501. package/dist/services/subagents/subagent-notification-store.d.ts.map +1 -1
  502. package/dist/services/subagents/subagent-notification-store.js +22 -0
  503. package/dist/services/subagents/subagent-notification-store.js.map +1 -1
  504. package/dist/services/subagents/test-helpers/subagent-manager-fixtures.js +6 -5
  505. package/dist/services/subagents/test-helpers/subagent-manager-fixtures.js.map +1 -1
  506. package/dist/services/subagents/tool-policy.d.ts +3 -1
  507. package/dist/services/subagents/tool-policy.d.ts.map +1 -1
  508. package/dist/services/subagents/tool-policy.js +16 -12
  509. package/dist/services/subagents/tool-policy.js.map +1 -1
  510. package/dist/services/subagents/types.d.ts +15 -0
  511. package/dist/services/subagents/types.d.ts.map +1 -1
  512. package/dist/services/subagents/utils.d.ts +17 -0
  513. package/dist/services/subagents/utils.d.ts.map +1 -1
  514. package/dist/services/subagents/utils.js +39 -0
  515. package/dist/services/subagents/utils.js.map +1 -1
  516. package/dist/services/subagents/worker-worktree.d.ts +25 -0
  517. package/dist/services/subagents/worker-worktree.d.ts.map +1 -0
  518. package/dist/services/subagents/worker-worktree.js +74 -0
  519. package/dist/services/subagents/worker-worktree.js.map +1 -0
  520. package/dist/services/tool-execution-ledger.d.ts +26 -1
  521. package/dist/services/tool-execution-ledger.d.ts.map +1 -1
  522. package/dist/services/tool-execution-ledger.js +103 -33
  523. package/dist/services/tool-execution-ledger.js.map +1 -1
  524. package/dist/services/workspace/active-workspace-root.d.ts +5 -0
  525. package/dist/services/workspace/active-workspace-root.d.ts.map +1 -0
  526. package/dist/services/workspace/active-workspace-root.js +24 -0
  527. package/dist/services/workspace/active-workspace-root.js.map +1 -0
  528. package/dist/services/workspace/parse-worktree-list.d.ts +24 -0
  529. package/dist/services/workspace/parse-worktree-list.d.ts.map +1 -0
  530. package/dist/services/workspace/parse-worktree-list.js +59 -0
  531. package/dist/services/workspace/parse-worktree-list.js.map +1 -0
  532. package/dist/services/workspace/worktree-inventory.d.ts +10 -0
  533. package/dist/services/workspace/worktree-inventory.d.ts.map +1 -0
  534. package/dist/services/workspace/worktree-inventory.js +28 -0
  535. package/dist/services/workspace/worktree-inventory.js.map +1 -0
  536. package/dist/services/workspace/worktree-transition.d.ts +85 -0
  537. package/dist/services/workspace/worktree-transition.d.ts.map +1 -0
  538. package/dist/services/workspace/worktree-transition.js +70 -0
  539. package/dist/services/workspace/worktree-transition.js.map +1 -0
  540. package/dist/tools/agent/activate-skill.d.ts.map +1 -1
  541. package/dist/tools/agent/activate-skill.js +1 -0
  542. package/dist/tools/agent/activate-skill.js.map +1 -1
  543. package/dist/tools/agent/ask-mentor.d.ts.map +1 -1
  544. package/dist/tools/agent/ask-mentor.js +5 -1
  545. package/dist/tools/agent/ask-mentor.js.map +1 -1
  546. package/dist/tools/agent/run-subagent-async.d.ts +1 -1
  547. package/dist/tools/agent/run-subagent-async.d.ts.map +1 -1
  548. package/dist/tools/agent/run-subagent-async.js +21 -4
  549. package/dist/tools/agent/run-subagent-async.js.map +1 -1
  550. package/dist/tools/agent/run-subagent.d.ts +3 -1
  551. package/dist/tools/agent/run-subagent.d.ts.map +1 -1
  552. package/dist/tools/agent/run-subagent.js +34 -7
  553. package/dist/tools/agent/run-subagent.js.map +1 -1
  554. package/dist/tools/file/apply-patch.d.ts.map +1 -1
  555. package/dist/tools/file/apply-patch.js +6 -3
  556. package/dist/tools/file/apply-patch.js.map +1 -1
  557. package/dist/tools/file/code-context.d.ts.map +1 -1
  558. package/dist/tools/file/code-context.js +2 -0
  559. package/dist/tools/file/code-context.js.map +1 -1
  560. package/dist/tools/file/glob.d.ts.map +1 -1
  561. package/dist/tools/file/glob.js +1 -0
  562. package/dist/tools/file/glob.js.map +1 -1
  563. package/dist/tools/file/grep.d.ts.map +1 -1
  564. package/dist/tools/file/grep.js +1 -0
  565. package/dist/tools/file/grep.js.map +1 -1
  566. package/dist/tools/file/read-file.d.ts +2 -0
  567. package/dist/tools/file/read-file.d.ts.map +1 -1
  568. package/dist/tools/file/read-file.js +36 -15
  569. package/dist/tools/file/read-file.js.map +1 -1
  570. package/dist/tools/system/shell.d.ts +42 -1
  571. package/dist/tools/system/shell.d.ts.map +1 -1
  572. package/dist/tools/system/shell.js +285 -10
  573. package/dist/tools/system/shell.js.map +1 -1
  574. package/dist/tools/system/worktree.d.ts +22 -0
  575. package/dist/tools/system/worktree.d.ts.map +1 -0
  576. package/dist/tools/system/worktree.js +138 -0
  577. package/dist/tools/system/worktree.js.map +1 -0
  578. package/dist/tools/types.d.ts +5 -0
  579. package/dist/tools/types.d.ts.map +1 -1
  580. package/dist/tools/types.js.map +1 -1
  581. package/dist/tools/utils.d.ts.map +1 -1
  582. package/dist/tools/utils.js +3 -2
  583. package/dist/tools/utils.js.map +1 -1
  584. package/dist/tools/web/web-fetch.d.ts.map +1 -1
  585. package/dist/tools/web/web-fetch.js +10 -12
  586. package/dist/tools/web/web-fetch.js.map +1 -1
  587. package/dist/tools/web/web-search.d.ts.map +1 -1
  588. package/dist/tools/web/web-search.js +1 -0
  589. package/dist/tools/web/web-search.js.map +1 -1
  590. package/dist/utils/ai/provider-credentials.d.ts +31 -2
  591. package/dist/utils/ai/provider-credentials.d.ts.map +1 -1
  592. package/dist/utils/ai/provider-credentials.js +119 -11
  593. package/dist/utils/ai/provider-credentials.js.map +1 -1
  594. package/dist/utils/conversation/conversation-event-handler.d.ts.map +1 -1
  595. package/dist/utils/conversation/conversation-event-handler.js +13 -1
  596. package/dist/utils/conversation/conversation-event-handler.js.map +1 -1
  597. package/dist/utils/conversation/message-utils.d.ts +8 -2
  598. package/dist/utils/conversation/message-utils.d.ts.map +1 -1
  599. package/dist/utils/conversation/message-utils.js +38 -21
  600. package/dist/utils/conversation/message-utils.js.map +1 -1
  601. package/dist/utils/copy-selections.d.ts +8 -0
  602. package/dist/utils/copy-selections.d.ts.map +1 -0
  603. package/dist/utils/copy-selections.js +42 -0
  604. package/dist/utils/copy-selections.js.map +1 -0
  605. package/dist/utils/output/bound-tool-result.d.ts +42 -0
  606. package/dist/utils/output/bound-tool-result.d.ts.map +1 -0
  607. package/dist/utils/output/bound-tool-result.js +81 -0
  608. package/dist/utils/output/bound-tool-result.js.map +1 -0
  609. package/dist/utils/settings-command.d.ts.map +1 -1
  610. package/dist/utils/settings-command.js +22 -2
  611. package/dist/utils/settings-command.js.map +1 -1
  612. package/dist/utils/shell/command-safety/path-analysis.d.ts.map +1 -1
  613. package/dist/utils/shell/command-safety/path-analysis.js +5 -1
  614. package/dist/utils/shell/command-safety/path-analysis.js.map +1 -1
  615. package/dist/utils/shell/execute-shell.d.ts +25 -0
  616. package/dist/utils/shell/execute-shell.d.ts.map +1 -1
  617. package/dist/utils/shell/execute-shell.js +22 -5
  618. package/dist/utils/shell/execute-shell.js.map +1 -1
  619. package/dist/utils/shell/sandbox/sandbox-env.d.ts.map +1 -1
  620. package/dist/utils/shell/sandbox/sandbox-env.js +2 -1
  621. package/dist/utils/shell/sandbox/sandbox-env.js.map +1 -1
  622. package/dist/utils/shell/sandbox/sandbox-network-store.d.ts.map +1 -1
  623. package/dist/utils/shell/sandbox/sandbox-network-store.js +3 -2
  624. package/dist/utils/shell/sandbox/sandbox-network-store.js.map +1 -1
  625. package/dist/utils/shell/sandbox/sandbox-policy.d.ts.map +1 -1
  626. package/dist/utils/shell/sandbox/sandbox-policy.js +2 -1
  627. package/dist/utils/shell/sandbox/sandbox-policy.js.map +1 -1
  628. package/dist/utils/shell/shell-output.d.ts +11 -0
  629. package/dist/utils/shell/shell-output.d.ts.map +1 -1
  630. package/dist/utils/shell/shell-output.js +18 -8
  631. package/dist/utils/shell/shell-output.js.map +1 -1
  632. package/dist/utils/value-suggestions.d.ts.map +1 -1
  633. package/dist/utils/value-suggestions.js +6 -0
  634. package/dist/utils/value-suggestions.js.map +1 -1
  635. package/package.json +1 -1
@@ -55,6 +55,18 @@ class EventQueue {
55
55
  return new Promise((resolve, reject) => this.#waiters.push({ resolve, reject }));
56
56
  }
57
57
  }
58
+ /**
59
+ * Process-wide monotonic counter for model-request cost ids.
60
+ *
61
+ * Request ids must be unique across every run in the process: root runs,
62
+ * subagent runs, and approval continuations all feed the same session
63
+ * accumulator, which dedups by id to make event + terminal double-delivery
64
+ * safe. A run-local sequence (as in a per-run counter) would collide across
65
+ * turns and silently drop later turns' records.
66
+ */
67
+ let nextCostRequestSeq = 0;
68
+ let nextToolBatchSeq = 0;
69
+ const DEFAULT_MAX_PARALLEL_TOOL_CALLS = 4;
58
70
  /**
59
71
  * Small provider-neutral agent loop. It owns model-turn sequencing and tool
60
72
  * execution; providers only implement `StreamedModelTurn`.
@@ -62,8 +74,10 @@ class EventQueue {
62
74
  export class ApplicationRunLoop {
63
75
  #deps;
64
76
  #contextCompactionSessionState;
77
+ #maxParallelToolCalls;
65
78
  #activeAbortController = null;
66
79
  #runInFlight = false;
80
+ #segmentGeneration = 0;
67
81
  /**
68
82
  * Set when a segment ends holding approvals, meaning the turn is pausing
69
83
  * rather than finishing. Injections offered during the pause wait here for
@@ -86,6 +100,7 @@ export class ApplicationRunLoop {
86
100
  constructor(deps) {
87
101
  this.#deps = deps;
88
102
  this.#contextCompactionSessionState = deps.contextCompactionSessionState ?? { disabled: false };
103
+ this.#maxParallelToolCalls = Math.max(1, Math.floor(deps.maxParallelToolCalls ?? DEFAULT_MAX_PARALLEL_TOOL_CALLS));
89
104
  }
90
105
  /**
91
106
  * Declare a turn open, making it steerable before its first run exists.
@@ -257,6 +272,7 @@ export class ApplicationRunLoop {
257
272
  approvals: options.approvals ?? new ApprovalLedger(),
258
273
  turnCount: 0,
259
274
  maxTurns: options.maxTurns,
275
+ automaticCompactionsThisRun: 0,
260
276
  };
261
277
  state.approve = (interruption) => {
262
278
  state.approvalDecision = 'approved';
@@ -336,6 +352,7 @@ export class ApplicationRunLoop {
336
352
  }
337
353
  #run(state, options) {
338
354
  const queue = new EventQueue();
355
+ const segmentGeneration = ++this.#segmentGeneration;
339
356
  this.abortSegment();
340
357
  const controller = new AbortController();
341
358
  this.#activeAbortController = controller;
@@ -387,6 +404,8 @@ export class ApplicationRunLoop {
387
404
  throw error;
388
405
  })
389
406
  .finally(() => {
407
+ if (segmentGeneration !== this.#segmentGeneration)
408
+ return;
390
409
  if (this.#activeAbortController === controller)
391
410
  this.#activeAbortController = null;
392
411
  this.#runInFlight = false;
@@ -435,27 +454,20 @@ export class ApplicationRunLoop {
435
454
  else {
436
455
  state.approvals.rejectTool({ toolName: pending.toolName, callId: pending.callId }, { message: state.approvalMessage });
437
456
  }
438
- const rawResult = approved
439
- ? await this.#invokeTool(pending.definition, pending.params, toolContext, pending.callId, state)
440
- : state.approvalMessage ?? 'rejected';
441
- const result = typeof rawResult === 'string' ? rawResult : JSON.stringify(rawResult);
442
- const resultItem = {
443
- type: 'function_call_result',
444
- callId: pending.callId,
445
- name: pending.toolName,
446
- output: result,
447
- };
448
- state.history.push(resultItem);
449
- state.input.push({ type: 'tool_result', id: pending.callId, output: result });
450
- outputPush(stream, queue, { type: 'item', item: resultItem });
457
+ pending.plan.status = 'ready';
458
+ if (!approved)
459
+ pending.plan.output = state.approvalMessage ?? 'rejected';
451
460
  state.pendingApprovals.splice(pendingIndex, 1);
452
461
  state.pendingApproval = state.pendingApprovals[0];
453
462
  state.approvalDecision = undefined;
454
463
  state.approvalDecisionCallId = undefined;
455
464
  state.approvalMessage = undefined;
465
+ await this.#settleToolPlan(state, stream, queue, toolContext);
456
466
  stream.interruptions = state.pendingApprovals.map((item) => item.interruption);
457
- if (state.pendingApprovals.length > 0)
467
+ if (state.pendingApprovals.length > 0) {
468
+ this.#turnPaused = true;
458
469
  return finish(stream, state, queue);
470
+ }
459
471
  // Nothing is outstanding, so this segment is terminal — see
460
472
  // `stopAfterApprovalResolution`. Stopping here rather than at the
461
473
  // request boundary below is what keeps the just-recorded tool result
@@ -467,17 +479,57 @@ export class ApplicationRunLoop {
467
479
  // history, and the next request has not been built. A user message
468
480
  // admitted here reaches the model in sequence, mid-turn.
469
481
  this.#admitPendingSteers(state, stream, queue);
482
+ if (options.boundaryCompaction) {
483
+ const compactionStartedAt = Date.now();
484
+ const compaction = await options.boundaryCompaction.compact({
485
+ history: state.history,
486
+ automaticCompactionsThisRun: state.automaticCompactionsThisRun ?? 0,
487
+ signal: options.signal,
488
+ onStarted: (provider) => outputPush(stream, queue, { type: 'context_compaction_started', provider, strategy: 'local' }),
489
+ });
490
+ if (compaction.kind === 'compacted') {
491
+ state.history.splice(0, state.history.length, ...compaction.history);
492
+ state.input.splice(0, state.input.length, ...normalizeApplicationInput(compaction.modelInput));
493
+ state.responseId = undefined;
494
+ state.responseProviderId = undefined;
495
+ if (compaction.costRecords?.length) {
496
+ state.costRecords ??= [];
497
+ state.costRecords.push(...compaction.costRecords);
498
+ }
499
+ state.automaticCompactionsThisRun = (state.automaticCompactionsThisRun ?? 0) + 1;
500
+ outputPush(stream, queue, {
501
+ type: 'context_compaction_completed',
502
+ provider: state.currentProviderId ?? 'unknown',
503
+ strategy: 'local',
504
+ durationMs: Math.max(0, Date.now() - compactionStartedAt),
505
+ });
506
+ }
507
+ else if (compaction.kind === 'failed') {
508
+ outputPush(stream, queue, {
509
+ type: 'context_compaction_failed',
510
+ provider: compaction.provider,
511
+ strategy: 'local',
512
+ durationMs: Math.max(0, Date.now() - compactionStartedAt),
513
+ });
514
+ }
515
+ // Summarization is an asynchronous part of this same request
516
+ // boundary. Admit anything that arrived while it was in flight after
517
+ // applying a replacement, so the steer cannot be overwritten by the
518
+ // checkpoint or miss a terminal model request.
519
+ this.#admitPendingSteers(state, stream, queue);
520
+ }
470
521
  state.turnCount += 1;
471
522
  if (state.maxTurns !== undefined && state.turnCount > state.maxTurns) {
472
523
  throw new MaxTurnsExceededError(state.maxTurns);
473
524
  }
474
525
  const model = await this.#deps.resolveModel(state.agent.model);
475
526
  let sawToolCall = false;
527
+ const streamedToolCalls = [];
476
528
  let completion;
477
529
  let pendingNativeReasoning;
478
- // Stable run-local request id, allocated immediately before dispatch so a
479
- // cost record can be settled exactly once (success or failure).
480
- const requestId = this.#nextRequestId(state);
530
+ // Stable process-unique request id, allocated immediately before dispatch
531
+ // so a cost record can be settled exactly once (success or failure).
532
+ const requestId = this.#nextRequestId();
481
533
  const request = {
482
534
  instructions: state.agent.instructions,
483
535
  ...(state.supportsConversationChaining &&
@@ -517,7 +569,7 @@ export class ApplicationRunLoop {
517
569
  ...options.generationGuard,
518
570
  });
519
571
  const consume = async () => {
520
- const deadline = new GenerationDeadline(generationGuard.requestDeadlineMs, () => requestAbortController.abort());
572
+ const deadline = new GenerationDeadline(generationGuard.requestDeadlineMs, () => requestAbortController.abort(), () => generationGuard.progress);
521
573
  let iterator;
522
574
  let iteratorFinished = false;
523
575
  try {
@@ -562,7 +614,7 @@ export class ApplicationRunLoop {
562
614
  generationGuard.observeToolCall(event.arguments);
563
615
  pendingNativeReasoning = commitPendingNativeReasoning(state, stream, queue, pendingNativeReasoning);
564
616
  sawToolCall = true;
565
- await this.#handleToolCall(state, stream, queue, event, toolContext);
617
+ streamedToolCalls.push(event);
566
618
  }
567
619
  }
568
620
  }
@@ -589,17 +641,35 @@ export class ApplicationRunLoop {
589
641
  // unpriced marker so the summary stays honest (partial) rather than
590
642
  // appearing exact. Observational only: the error still propagates.
591
643
  const cancelled = error instanceof Error && error.name === 'AbortError';
592
- this.#appendCostRecord(state, {
644
+ const record = this.#appendCostRecord(state, {
593
645
  requestId,
594
646
  provider: state.currentProviderId,
595
647
  model: state.agent.model,
596
648
  tier: resolveServiceTier(request),
597
649
  outcome: cancelled ? 'cancelled' : 'failed',
598
650
  });
651
+ // Only the live queue sees cost records: `output`/`newItems` feed
652
+ // persistence and replay, and a cost event must never become a
653
+ // restored history item.
654
+ queue.push({ type: 'cost_update', record });
599
655
  throw error;
600
656
  }
601
- if (!completion)
602
- throw new Error('Application model turn ended without completion');
657
+ if (!completion) {
658
+ // A few application-owned model fixtures (and legacy adapters) end a
659
+ // tool-call stream immediately after the call and use the next request
660
+ // as the continuation boundary. Preserve that contract while routing
661
+ // the calls through the same ordered dispatcher. An empty stream still
662
+ // fails closed as an incomplete model turn.
663
+ if (streamedToolCalls.length === 0)
664
+ throw new Error('Application model turn ended without completion');
665
+ await this.#dispatchToolCalls(state, stream, queue, streamedToolCalls, toolContext);
666
+ if (state.pendingApprovals && state.pendingApprovals.length > 0) {
667
+ stream.interruptions = state.pendingApprovals.map((item) => item.interruption);
668
+ this.#turnPaused = true;
669
+ return finish(stream, state, queue);
670
+ }
671
+ continue;
672
+ }
603
673
  // Commit the authoritative terminal state before handling terminal-only
604
674
  // tool calls. Approval may pause immediately after this point, and the
605
675
  // continuation must still carry the response that produced the calls.
@@ -645,7 +715,13 @@ export class ApplicationRunLoop {
645
715
  normalizedCompletionUsage = undefined;
646
716
  }
647
717
  // Attribute cost while the dispatched request's identity is still known.
648
- this.#appendCostRecord(state, {
718
+ // Emit it immediately so the UI can show this request's cost before the
719
+ // run ends; the terminal result re-delivers the cumulative record list
720
+ // and the session accumulator ignores the duplicates by request id.
721
+ // Only the live queue sees the event: `output`/`newItems` feed
722
+ // persistence and replay, and a cost event must never become a restored
723
+ // history item.
724
+ const record = this.#appendCostRecord(state, {
649
725
  requestId,
650
726
  provider: state.currentProviderId,
651
727
  model: state.agent.model,
@@ -654,11 +730,13 @@ export class ApplicationRunLoop {
654
730
  usage: normalizedCompletionUsage,
655
731
  providerUsd: completion.costUsd,
656
732
  });
733
+ queue.push({ type: 'cost_update', record });
657
734
  stream.lastResponseId = completion.responseId;
658
735
  stream.rawResponses?.push(completion);
659
736
  // Some provider adapters report function calls only in the terminal
660
737
  // completion rather than as separate stream events. Their reasoning may
661
738
  // likewise be terminal-only, so associate it before replaying calls.
739
+ const toolCalls = [...streamedToolCalls];
662
740
  if (!sawToolCall) {
663
741
  for (const item of completion.output) {
664
742
  if (item.type === 'reasoning')
@@ -669,9 +747,11 @@ export class ApplicationRunLoop {
669
747
  continue;
670
748
  pendingNativeReasoning = commitPendingNativeReasoning(state, stream, queue, pendingNativeReasoning);
671
749
  sawToolCall = true;
672
- await this.#handleToolCall(state, stream, queue, item, toolContext);
750
+ toolCalls.push(item);
673
751
  }
674
752
  }
753
+ if (toolCalls.length > 0)
754
+ await this.#dispatchToolCalls(state, stream, queue, toolCalls, toolContext);
675
755
  // A native reasoning item belongs to the completed assistant turn even
676
756
  // when no tool call follows it. Commit it before assistant text so both
677
757
  // stateless continuation and persisted canonical history retain the
@@ -711,105 +791,154 @@ export class ApplicationRunLoop {
711
791
  }
712
792
  if (state.pendingApprovals.length > 0) {
713
793
  stream.interruptions = state.pendingApprovals.map((item) => item.interruption);
794
+ this.#turnPaused = true;
714
795
  return finish(stream, state, queue);
715
796
  }
716
797
  if (!sawToolCall)
717
798
  return finish(stream, state, queue);
718
799
  }
719
800
  }
720
- async #handleToolCall(state, stream, queue, event, toolContext) {
721
- const definition = state.agent.tools.find((tool) => tool.name === event.name);
722
- const args = parseArguments(event.arguments);
723
- const callItem = {
724
- type: 'function_call',
725
- callId: event.id,
726
- name: event.name,
727
- arguments: event.arguments,
728
- };
729
- state.history.push(callItem);
730
- state.input.push({ type: 'tool_call', id: event.id, name: event.name, arguments: event.arguments });
731
- outputPush(stream, queue, { type: 'item', item: callItem });
732
- if (!definition) {
733
- const output = `Unknown tool: ${event.name}`;
734
- const resultItem = {
735
- type: 'function_call_result',
801
+ async #dispatchToolCalls(state, stream, queue, events, toolContext) {
802
+ const plan = events.map((event) => {
803
+ const definition = state.agent.tools.find((tool) => tool.name === event.name);
804
+ const callItem = {
805
+ type: 'function_call',
736
806
  callId: event.id,
737
807
  name: event.name,
738
- output,
808
+ arguments: event.arguments,
739
809
  };
740
- state.history.push(resultItem);
741
- state.input.push({ type: 'tool_result', id: event.id, output });
742
- outputPush(stream, queue, { type: 'item', item: resultItem });
743
- return;
744
- }
745
- // Keep the raw-model invocation contract: normalization repairs the
746
- // accepted object shape but intentionally does not Zod-parse it, which
747
- // would apply schema defaults before execute. web_fetch relies on its
748
- // executor fallbacks on the strict JSON-schema path.
749
- const params = normalizeToolParameters(args, definition.parameters);
750
- // Consult this run's ledger before prompting: a decision already taken
751
- // (in the parent run and replayed in, or earlier in this run) must not
752
- // prompt again. This is what makes approval replay observable.
753
- const alreadyDecided = state.approvals.isToolApproved({ toolName: event.name, callId: event.id });
754
- if (alreadyDecided === false) {
755
- const message = state.approvals.getRejectionMessage(event.name, event.id) ?? 'Tool execution was not approved.';
756
- const resultItem = {
757
- type: 'function_call_result',
758
- callId: event.id,
759
- name: event.name,
760
- output: message,
761
- };
762
- state.history.push(resultItem);
763
- state.input.push({ type: 'tool_result', id: event.id, output: message });
764
- outputPush(stream, queue, { type: 'item', item: resultItem });
765
- return;
766
- }
767
- if (alreadyDecided === true) {
768
- const result = await this.#invokeTool(definition, params, toolContext, event.id, state);
769
- const output = typeof result === 'string' ? result : JSON.stringify(result);
770
- const resultItem = {
771
- type: 'function_call_result',
772
- callId: event.id,
773
- name: event.name,
774
- output,
775
- };
776
- state.history.push(resultItem);
777
- state.input.push({ type: 'tool_result', id: event.id, output });
778
- outputPush(stream, queue, { type: 'item', item: resultItem });
779
- return;
780
- }
781
- if (await definition.needsApproval(params, toolContext)) {
782
- const pending = {
783
- callId: event.id,
784
- toolName: event.name,
785
- argumentsText: event.arguments,
786
- interruption: {
787
- type: 'tool_approval_item',
788
- rawItem: { type: 'function_call', callId: event.id, name: event.name, arguments: event.arguments },
789
- callId: event.id,
790
- name: event.name,
791
- arguments: event.arguments,
792
- },
810
+ state.history.push(callItem);
811
+ state.input.push({ type: 'tool_call', id: event.id, name: event.name, arguments: event.arguments });
812
+ outputPush(stream, queue, { type: 'item', item: callItem });
813
+ return {
814
+ event,
793
815
  definition,
794
- params,
816
+ parallelSafe: false,
817
+ status: 'ready',
795
818
  };
796
- state.pendingApprovals ??= [];
797
- if (!state.pendingApproval)
798
- state.pendingApproval = pending;
799
- state.pendingApprovals.push(pending);
800
- stream.interruptions = state.pendingApprovals.map((item) => item.interruption);
819
+ });
820
+ state.toolPlan = plan;
821
+ for (const entry of plan) {
822
+ const { event, definition } = entry;
823
+ if (!definition) {
824
+ entry.output = `Unknown tool: ${event.name}`;
825
+ continue;
826
+ }
827
+ // Keep the raw-model invocation contract: normalization repairs the
828
+ // accepted object shape but intentionally does not Zod-parse it, which
829
+ // would apply schema defaults before execute. web_fetch relies on its
830
+ // executor fallbacks on the strict JSON-schema path.
831
+ entry.params = normalizeToolParameters(parseArguments(event.arguments), definition.parameters);
832
+ // Consult this run's ledger before prompting: a decision already taken
833
+ // (in the parent run and replayed in, or earlier in this run) must not
834
+ // prompt again. This is what makes approval replay observable.
835
+ const alreadyDecided = state.approvals.isToolApproved({ toolName: event.name, callId: event.id });
836
+ if (alreadyDecided === false) {
837
+ entry.output = state.approvals.getRejectionMessage(event.name, event.id) ?? 'Tool execution was not approved.';
838
+ continue;
839
+ }
840
+ if (alreadyDecided !== true && (await definition.needsApproval(entry.params, toolContext))) {
841
+ entry.status = 'approval_pending';
842
+ const pending = {
843
+ callId: event.id,
844
+ toolName: event.name,
845
+ argumentsText: event.arguments,
846
+ interruption: {
847
+ type: 'tool_approval_item',
848
+ rawItem: { type: 'function_call', callId: event.id, name: event.name, arguments: event.arguments },
849
+ callId: event.id,
850
+ name: event.name,
851
+ arguments: event.arguments,
852
+ },
853
+ definition,
854
+ params: entry.params,
855
+ plan: entry,
856
+ };
857
+ state.pendingApprovals ??= [];
858
+ state.pendingApprovals.push(pending);
859
+ continue;
860
+ }
861
+ entry.parallelSafe = await isParallelSafe(definition, entry.params, toolContext);
862
+ }
863
+ state.pendingApproval = state.pendingApprovals?.[0];
864
+ stream.interruptions = (state.pendingApprovals ?? []).map((item) => item.interruption);
865
+ this.#deps.logDiagnostic?.('tool parallel eligibility', {
866
+ decisions: plan.map((entry) => ({
867
+ callId: entry.event.id,
868
+ toolName: entry.event.name,
869
+ parallelSafe: entry.parallelSafe,
870
+ approvalPending: entry.status === 'approval_pending',
871
+ })),
872
+ });
873
+ await this.#settleToolPlan(state, stream, queue, toolContext);
874
+ }
875
+ async #settleToolPlan(state, stream, queue, toolContext) {
876
+ const plan = state.toolPlan;
877
+ if (!plan)
801
878
  return;
879
+ while (true) {
880
+ const firstPending = plan.find((entry) => entry.status !== 'completed');
881
+ if (!firstPending) {
882
+ state.toolPlan = undefined;
883
+ return;
884
+ }
885
+ if (firstPending.status === 'approval_pending')
886
+ return;
887
+ const group = [];
888
+ for (const entry of plan) {
889
+ if (entry.status === 'completed')
890
+ continue;
891
+ if (entry.status === 'approval_pending')
892
+ break;
893
+ if (group.length > 0 &&
894
+ (!entry.parallelSafe || !group[0].parallelSafe || group.length >= this.#maxParallelToolCalls))
895
+ break;
896
+ group.push(entry);
897
+ if (!entry.parallelSafe)
898
+ break;
899
+ }
900
+ const batchId = `tool-batch-${++nextToolBatchSeq}`;
901
+ this.#deps.logDiagnostic?.('tool batch dispatched', {
902
+ batchId,
903
+ callIds: group.map((entry) => entry.event.id),
904
+ parallel: group.length > 1,
905
+ dispatchOrder: group.map((entry) => entry.event.id),
906
+ });
907
+ if (group.length > 1) {
908
+ const results = await Promise.allSettled(group.map((entry) => this.#invokePlannedTool(entry, toolContext, state)));
909
+ const rejected = results.find((result) => result.status === 'rejected');
910
+ if (rejected)
911
+ throw rejected.reason;
912
+ for (const [index, result] of results.entries()) {
913
+ this.#appendToolResult(state, stream, queue, group[index], result.value);
914
+ }
915
+ }
916
+ else {
917
+ const result = await this.#invokePlannedTool(group[0], toolContext, state);
918
+ this.#appendToolResult(state, stream, queue, group[0], result);
919
+ }
920
+ this.#deps.logDiagnostic?.('tool batch settled', {
921
+ batchId,
922
+ settlementOrder: group.map((entry) => entry.event.id),
923
+ });
802
924
  }
803
- const result = await this.#invokeTool(definition, params, toolContext, event.id, state);
925
+ }
926
+ async #invokePlannedTool(entry, toolContext, state) {
927
+ entry.status = 'completed';
928
+ if (entry.output !== undefined)
929
+ return entry.output;
930
+ return this.#invokeTool(entry.definition, entry.params, toolContext, entry.event.id, state);
931
+ }
932
+ #appendToolResult(state, stream, queue, entry, result) {
804
933
  const output = typeof result === 'string' ? result : JSON.stringify(result);
805
934
  const resultItem = {
806
935
  type: 'function_call_result',
807
- callId: event.id,
808
- name: event.name,
936
+ callId: entry.event.id,
937
+ name: entry.event.name,
809
938
  output,
810
939
  };
811
940
  state.history.push(resultItem);
812
- state.input.push({ type: 'tool_result', id: event.id, output });
941
+ state.input.push({ type: 'tool_result', id: entry.event.id, output });
813
942
  outputPush(stream, queue, { type: 'item', item: resultItem });
814
943
  }
815
944
  /**
@@ -843,6 +972,9 @@ export class ApplicationRunLoop {
843
972
  attempt,
844
973
  scope: state?.hookScope ?? 'root',
845
974
  };
975
+ // Dispatch mark must run before execute so a mid-tool stream failure can
976
+ // settle the ledger as unknown rather than aborted.
977
+ this.#deps.getOnToolDispatch?.()?.(callId);
846
978
  await this.#notifyToolLifecycle(() => this.#deps.toolLifecycle?.before(lifecycleContext));
847
979
  try {
848
980
  const result = await definition.execute(params, toolContext, { toolCall: { callId } });
@@ -869,9 +1001,9 @@ export class ApplicationRunLoop {
869
1001
  return result;
870
1002
  }
871
1003
  }
872
- #nextRequestId(state) {
873
- state.costRequestSeq = (state.costRequestSeq ?? 0) + 1;
874
- return `req-${state.turnCount}-${state.costRequestSeq}`;
1004
+ #nextRequestId() {
1005
+ nextCostRequestSeq += 1;
1006
+ return `req-${nextCostRequestSeq}`;
875
1007
  }
876
1008
  #appendCostRecord(state, input) {
877
1009
  const record = computeModelCost({
@@ -886,6 +1018,7 @@ export class ApplicationRunLoop {
886
1018
  pricingVersion: getCatalogPricingVersion(),
887
1019
  });
888
1020
  state.costRecords = [...(state.costRecords ?? []), record];
1021
+ return record;
889
1022
  }
890
1023
  async #notifyToolLifecycle(operation) {
891
1024
  if (!operation)
@@ -1021,6 +1154,17 @@ function parseArguments(value) {
1021
1154
  return {};
1022
1155
  }
1023
1156
  }
1157
+ async function isParallelSafe(definition, params, context) {
1158
+ if (typeof definition.parallelSafe === 'function') {
1159
+ try {
1160
+ return await definition.parallelSafe(params, context);
1161
+ }
1162
+ catch {
1163
+ return false;
1164
+ }
1165
+ }
1166
+ return definition.parallelSafe === true;
1167
+ }
1024
1168
  function getInterruptionCallId(value) {
1025
1169
  if (typeof value !== 'object' || value === null)
1026
1170
  return undefined;