@namzu/sdk 51.1.0 → 52.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 (395) hide show
  1. package/CHANGELOG.md +119 -0
  2. package/dist/agents/QueryAgent.d.ts.map +1 -1
  3. package/dist/agents/QueryAgent.js +2 -0
  4. package/dist/agents/QueryAgent.js.map +1 -1
  5. package/dist/agents/SupervisorAgent.d.ts +1 -1
  6. package/dist/agents/SupervisorAgent.d.ts.map +1 -1
  7. package/dist/agents/SupervisorAgent.js.map +1 -1
  8. package/dist/agents/examples/SupervisorAgent.d.ts +42 -0
  9. package/dist/agents/examples/SupervisorAgent.d.ts.map +1 -1
  10. package/dist/agents/examples/SupervisorAgent.js +80 -4
  11. package/dist/agents/examples/SupervisorAgent.js.map +1 -1
  12. package/dist/agents/index.d.ts +1 -1
  13. package/dist/agents/index.d.ts.map +1 -1
  14. package/dist/agents/index.js.map +1 -1
  15. package/dist/authorization/protected-paths.d.ts +36 -0
  16. package/dist/authorization/protected-paths.d.ts.map +1 -0
  17. package/dist/authorization/protected-paths.js +107 -0
  18. package/dist/authorization/protected-paths.js.map +1 -0
  19. package/dist/authorization/readonly-commands.d.ts +39 -0
  20. package/dist/authorization/readonly-commands.d.ts.map +1 -0
  21. package/dist/authorization/readonly-commands.js +797 -0
  22. package/dist/authorization/readonly-commands.js.map +1 -0
  23. package/dist/authorization/readonly-flags.d.ts +19 -0
  24. package/dist/authorization/readonly-flags.d.ts.map +1 -0
  25. package/dist/authorization/readonly-flags.js +178 -0
  26. package/dist/authorization/readonly-flags.js.map +1 -0
  27. package/dist/authorization/removal.d.ts +52 -0
  28. package/dist/authorization/removal.d.ts.map +1 -0
  29. package/dist/authorization/removal.js +283 -0
  30. package/dist/authorization/removal.js.map +1 -0
  31. package/dist/authorization/shell-paths.d.ts +66 -0
  32. package/dist/authorization/shell-paths.d.ts.map +1 -0
  33. package/dist/authorization/shell-paths.js +697 -0
  34. package/dist/authorization/shell-paths.js.map +1 -0
  35. package/dist/bridge/acp/update.d.ts.map +1 -1
  36. package/dist/bridge/acp/update.js +1 -0
  37. package/dist/bridge/acp/update.js.map +1 -1
  38. package/dist/compaction/context-window.d.ts +24 -0
  39. package/dist/compaction/context-window.d.ts.map +1 -1
  40. package/dist/compaction/context-window.js +34 -0
  41. package/dist/compaction/context-window.js.map +1 -1
  42. package/dist/compaction/manual.d.ts.map +1 -1
  43. package/dist/compaction/manual.js +10 -2
  44. package/dist/compaction/manual.js.map +1 -1
  45. package/dist/compaction/plan.d.ts +4 -0
  46. package/dist/compaction/plan.d.ts.map +1 -1
  47. package/dist/compaction/plan.js +6 -2
  48. package/dist/compaction/plan.js.map +1 -1
  49. package/dist/compaction/verifier.d.ts +11 -1
  50. package/dist/compaction/verifier.d.ts.map +1 -1
  51. package/dist/compaction/verifier.js +75 -23
  52. package/dist/compaction/verifier.js.map +1 -1
  53. package/dist/config/runtime.d.ts +55 -7
  54. package/dist/config/runtime.d.ts.map +1 -1
  55. package/dist/config/runtime.js +23 -2
  56. package/dist/config/runtime.js.map +1 -1
  57. package/dist/connector/web/guarded-fetch.d.ts.map +1 -1
  58. package/dist/connector/web/guarded-fetch.js +24 -0
  59. package/dist/connector/web/guarded-fetch.js.map +1 -1
  60. package/dist/connector/web/index.d.ts +1 -1
  61. package/dist/connector/web/index.d.ts.map +1 -1
  62. package/dist/connector/web/page.d.ts +59 -0
  63. package/dist/connector/web/page.d.ts.map +1 -0
  64. package/dist/connector/web/page.js +112 -0
  65. package/dist/connector/web/page.js.map +1 -0
  66. package/dist/connector/web/types.d.ts +47 -0
  67. package/dist/connector/web/types.d.ts.map +1 -1
  68. package/dist/connector/web/types.js.map +1 -1
  69. package/dist/constants/continuation.d.ts +8 -0
  70. package/dist/constants/continuation.d.ts.map +1 -1
  71. package/dist/constants/continuation.js +8 -0
  72. package/dist/constants/continuation.js.map +1 -1
  73. package/dist/constants/plugin/index.d.ts +1 -1
  74. package/dist/constants/plugin/index.d.ts.map +1 -1
  75. package/dist/constants/plugin/index.js +1 -1
  76. package/dist/constants/plugin/index.js.map +1 -1
  77. package/dist/contracts/a2a.d.ts +2 -2
  78. package/dist/manager/agent/lifecycle.d.ts +7 -0
  79. package/dist/manager/agent/lifecycle.d.ts.map +1 -1
  80. package/dist/manager/agent/lifecycle.js +11 -2
  81. package/dist/manager/agent/lifecycle.js.map +1 -1
  82. package/dist/manager/session/turn-recorder.d.ts.map +1 -1
  83. package/dist/manager/session/turn-recorder.js +4 -2
  84. package/dist/manager/session/turn-recorder.js.map +1 -1
  85. package/dist/plugin/index.d.ts +1 -1
  86. package/dist/plugin/index.d.ts.map +1 -1
  87. package/dist/plugin/index.js +1 -1
  88. package/dist/plugin/index.js.map +1 -1
  89. package/dist/plugin/lifecycle.d.ts +6 -0
  90. package/dist/plugin/lifecycle.d.ts.map +1 -1
  91. package/dist/plugin/lifecycle.js +98 -114
  92. package/dist/plugin/lifecycle.js.map +1 -1
  93. package/dist/plugin/shell-hook.d.ts +90 -22
  94. package/dist/plugin/shell-hook.d.ts.map +1 -1
  95. package/dist/plugin/shell-hook.js +434 -41
  96. package/dist/plugin/shell-hook.js.map +1 -1
  97. package/dist/provider/capabilities.d.ts +9 -0
  98. package/dist/provider/capabilities.d.ts.map +1 -1
  99. package/dist/provider/capabilities.js +15 -0
  100. package/dist/provider/capabilities.js.map +1 -1
  101. package/dist/provider/errors.d.ts.map +1 -1
  102. package/dist/provider/errors.js +13 -0
  103. package/dist/provider/errors.js.map +1 -1
  104. package/dist/provider/fallback.d.ts.map +1 -1
  105. package/dist/provider/fallback.js +10 -0
  106. package/dist/provider/fallback.js.map +1 -1
  107. package/dist/provider/idle-timeout.d.ts.map +1 -1
  108. package/dist/provider/idle-timeout.js +5 -0
  109. package/dist/provider/idle-timeout.js.map +1 -1
  110. package/dist/provider/image-input-refusal.d.ts +9 -0
  111. package/dist/provider/image-input-refusal.d.ts.map +1 -0
  112. package/dist/provider/image-input-refusal.js +54 -0
  113. package/dist/provider/image-input-refusal.js.map +1 -0
  114. package/dist/provider/index.d.ts +2 -1
  115. package/dist/provider/index.d.ts.map +1 -1
  116. package/dist/provider/index.js +2 -1
  117. package/dist/provider/index.js.map +1 -1
  118. package/dist/provider/retry.d.ts +7 -2
  119. package/dist/provider/retry.d.ts.map +1 -1
  120. package/dist/provider/retry.js +38 -4
  121. package/dist/provider/retry.js.map +1 -1
  122. package/dist/public-runtime.d.ts +5 -2
  123. package/dist/public-runtime.d.ts.map +1 -1
  124. package/dist/public-runtime.js +5 -2
  125. package/dist/public-runtime.js.map +1 -1
  126. package/dist/public-types.d.ts +2 -2
  127. package/dist/public-types.d.ts.map +1 -1
  128. package/dist/runtime/jobs/registry.d.ts +21 -0
  129. package/dist/runtime/jobs/registry.d.ts.map +1 -1
  130. package/dist/runtime/jobs/registry.js +15 -2
  131. package/dist/runtime/jobs/registry.js.map +1 -1
  132. package/dist/runtime/query/deferred-sandbox.d.ts +54 -0
  133. package/dist/runtime/query/deferred-sandbox.d.ts.map +1 -0
  134. package/dist/runtime/query/deferred-sandbox.js +75 -0
  135. package/dist/runtime/query/deferred-sandbox.js.map +1 -0
  136. package/dist/runtime/query/executor/tool-call-admission.d.ts +10 -0
  137. package/dist/runtime/query/executor/tool-call-admission.d.ts.map +1 -1
  138. package/dist/runtime/query/executor/tool-call-admission.js +74 -13
  139. package/dist/runtime/query/executor/tool-call-admission.js.map +1 -1
  140. package/dist/runtime/query/executor.d.ts +51 -2
  141. package/dist/runtime/query/executor.d.ts.map +1 -1
  142. package/dist/runtime/query/executor.js +214 -9
  143. package/dist/runtime/query/executor.js.map +1 -1
  144. package/dist/runtime/query/finalize-turn.d.ts +6 -0
  145. package/dist/runtime/query/finalize-turn.d.ts.map +1 -1
  146. package/dist/runtime/query/finalize-turn.js +1 -1
  147. package/dist/runtime/query/finalize-turn.js.map +1 -1
  148. package/dist/runtime/query/index.d.ts +29 -0
  149. package/dist/runtime/query/index.d.ts.map +1 -1
  150. package/dist/runtime/query/index.js +108 -28
  151. package/dist/runtime/query/index.js.map +1 -1
  152. package/dist/runtime/query/iteration/index.d.ts +57 -0
  153. package/dist/runtime/query/iteration/index.d.ts.map +1 -1
  154. package/dist/runtime/query/iteration/index.js +380 -28
  155. package/dist/runtime/query/iteration/index.js.map +1 -1
  156. package/dist/runtime/query/iteration/phases/compaction-breaker.d.ts +61 -0
  157. package/dist/runtime/query/iteration/phases/compaction-breaker.d.ts.map +1 -0
  158. package/dist/runtime/query/iteration/phases/compaction-breaker.js +94 -0
  159. package/dist/runtime/query/iteration/phases/compaction-breaker.js.map +1 -0
  160. package/dist/runtime/query/iteration/phases/compaction.d.ts +42 -1
  161. package/dist/runtime/query/iteration/phases/compaction.d.ts.map +1 -1
  162. package/dist/runtime/query/iteration/phases/compaction.js +203 -23
  163. package/dist/runtime/query/iteration/phases/compaction.js.map +1 -1
  164. package/dist/runtime/query/iteration/phases/context.d.ts +10 -0
  165. package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
  166. package/dist/runtime/query/iteration/phases/context.js.map +1 -1
  167. package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
  168. package/dist/runtime/query/iteration/phases/tool-review.js +165 -2
  169. package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
  170. package/dist/runtime/query/iteration/provider-rejected-image.d.ts +21 -1
  171. package/dist/runtime/query/iteration/provider-rejected-image.d.ts.map +1 -1
  172. package/dist/runtime/query/iteration/provider-rejected-image.js +53 -7
  173. package/dist/runtime/query/iteration/provider-rejected-image.js.map +1 -1
  174. package/dist/runtime/query/iteration/request-repair.d.ts +108 -0
  175. package/dist/runtime/query/iteration/request-repair.d.ts.map +1 -0
  176. package/dist/runtime/query/iteration/request-repair.js +593 -0
  177. package/dist/runtime/query/iteration/request-repair.js.map +1 -0
  178. package/dist/runtime/query/iteration/stream-turn.d.ts +6 -0
  179. package/dist/runtime/query/iteration/stream-turn.d.ts.map +1 -1
  180. package/dist/runtime/query/iteration/stream-turn.js +2 -2
  181. package/dist/runtime/query/iteration/stream-turn.js.map +1 -1
  182. package/dist/runtime/query/path-escalation.d.ts +36 -0
  183. package/dist/runtime/query/path-escalation.d.ts.map +1 -0
  184. package/dist/runtime/query/path-escalation.js +184 -0
  185. package/dist/runtime/query/path-escalation.js.map +1 -0
  186. package/dist/runtime/query/plugin-hooks.d.ts.map +1 -1
  187. package/dist/runtime/query/plugin-hooks.js +8 -0
  188. package/dist/runtime/query/plugin-hooks.js.map +1 -1
  189. package/dist/runtime/query/reminders.d.ts +35 -0
  190. package/dist/runtime/query/reminders.d.ts.map +1 -0
  191. package/dist/runtime/query/reminders.js +7 -0
  192. package/dist/runtime/query/reminders.js.map +1 -0
  193. package/dist/runtime/query/request-rich-content.d.ts +5 -1
  194. package/dist/runtime/query/request-rich-content.d.ts.map +1 -1
  195. package/dist/runtime/query/request-rich-content.js +67 -25
  196. package/dist/runtime/query/request-rich-content.js.map +1 -1
  197. package/dist/runtime/query/resume-pending.d.ts.map +1 -1
  198. package/dist/runtime/query/resume-pending.js +26 -0
  199. package/dist/runtime/query/resume-pending.js.map +1 -1
  200. package/dist/runtime/query/review-policy.d.ts +26 -0
  201. package/dist/runtime/query/review-policy.d.ts.map +1 -1
  202. package/dist/runtime/query/review-policy.js +79 -5
  203. package/dist/runtime/query/review-policy.js.map +1 -1
  204. package/dist/runtime/query/tool-output-budget.d.ts +46 -0
  205. package/dist/runtime/query/tool-output-budget.d.ts.map +1 -1
  206. package/dist/runtime/query/tool-output-budget.js +85 -1
  207. package/dist/runtime/query/tool-output-budget.js.map +1 -1
  208. package/dist/runtime/query/tooling.d.ts +1 -0
  209. package/dist/runtime/query/tooling.d.ts.map +1 -1
  210. package/dist/runtime/query/tooling.js +5 -0
  211. package/dist/runtime/query/tooling.js.map +1 -1
  212. package/dist/session/paths.d.ts +5 -1
  213. package/dist/session/paths.d.ts.map +1 -1
  214. package/dist/session/paths.js +8 -0
  215. package/dist/session/paths.js.map +1 -1
  216. package/dist/store/memory/disk.d.ts.map +1 -1
  217. package/dist/store/memory/disk.js +2 -2
  218. package/dist/store/memory/disk.js.map +1 -1
  219. package/dist/store/memory/markdown.d.ts.map +1 -1
  220. package/dist/store/memory/markdown.js +2 -2
  221. package/dist/store/memory/markdown.js.map +1 -1
  222. package/dist/store/memory/naming.d.ts +9 -0
  223. package/dist/store/memory/naming.d.ts.map +1 -1
  224. package/dist/store/memory/naming.js +12 -0
  225. package/dist/store/memory/naming.js.map +1 -1
  226. package/dist/tools/builtins/bash.d.ts +30 -1
  227. package/dist/tools/builtins/bash.d.ts.map +1 -1
  228. package/dist/tools/builtins/bash.js +170 -26
  229. package/dist/tools/builtins/bash.js.map +1 -1
  230. package/dist/tools/builtins/computer-use.d.ts +1 -1
  231. package/dist/tools/builtins/computer-use.d.ts.map +1 -1
  232. package/dist/tools/builtins/computer-use.js +12 -5
  233. package/dist/tools/builtins/computer-use.js.map +1 -1
  234. package/dist/tools/builtins/content-fingerprint.d.ts +2 -0
  235. package/dist/tools/builtins/content-fingerprint.d.ts.map +1 -1
  236. package/dist/tools/builtins/content-fingerprint.js +4 -0
  237. package/dist/tools/builtins/content-fingerprint.js.map +1 -1
  238. package/dist/tools/builtins/edit.d.ts.map +1 -1
  239. package/dist/tools/builtins/edit.js +60 -18
  240. package/dist/tools/builtins/edit.js.map +1 -1
  241. package/dist/tools/builtins/grep.d.ts +8 -1
  242. package/dist/tools/builtins/grep.d.ts.map +1 -1
  243. package/dist/tools/builtins/grep.js +152 -33
  244. package/dist/tools/builtins/grep.js.map +1 -1
  245. package/dist/tools/builtins/read-file.d.ts +1 -0
  246. package/dist/tools/builtins/read-file.d.ts.map +1 -1
  247. package/dist/tools/builtins/read-file.js +44 -5
  248. package/dist/tools/builtins/read-file.js.map +1 -1
  249. package/dist/tools/builtins/read-render.d.ts +52 -0
  250. package/dist/tools/builtins/read-render.d.ts.map +1 -1
  251. package/dist/tools/builtins/read-render.js +143 -0
  252. package/dist/tools/builtins/read-render.js.map +1 -1
  253. package/dist/tools/builtins/web.d.ts +13 -2
  254. package/dist/tools/builtins/web.d.ts.map +1 -1
  255. package/dist/tools/builtins/web.js +225 -32
  256. package/dist/tools/builtins/web.js.map +1 -1
  257. package/dist/tools/coordinator/ask-user-question.d.ts +2 -0
  258. package/dist/tools/coordinator/ask-user-question.d.ts.map +1 -1
  259. package/dist/tools/coordinator/ask-user-question.js +256 -92
  260. package/dist/tools/coordinator/ask-user-question.js.map +1 -1
  261. package/dist/tools/coordinator/question-options.d.ts +1 -0
  262. package/dist/tools/coordinator/question-options.d.ts.map +1 -1
  263. package/dist/tools/coordinator/question-options.js +6 -1
  264. package/dist/tools/coordinator/question-options.js.map +1 -1
  265. package/dist/tools/defineTool.d.ts +4 -1
  266. package/dist/tools/defineTool.d.ts.map +1 -1
  267. package/dist/tools/defineTool.js +6 -1
  268. package/dist/tools/defineTool.js.map +1 -1
  269. package/dist/tools/paths.d.ts +6 -0
  270. package/dist/tools/paths.d.ts.map +1 -1
  271. package/dist/tools/paths.js +1 -1
  272. package/dist/tools/paths.js.map +1 -1
  273. package/dist/types/agent/query.d.ts +3 -0
  274. package/dist/types/agent/query.d.ts.map +1 -1
  275. package/dist/types/errors/catalog.js +1 -1
  276. package/dist/types/errors/catalog.js.map +1 -1
  277. package/dist/types/hitl/index.d.ts +104 -0
  278. package/dist/types/hitl/index.d.ts.map +1 -1
  279. package/dist/types/hitl/index.js.map +1 -1
  280. package/dist/types/message/index.d.ts +1 -1
  281. package/dist/types/message/index.d.ts.map +1 -1
  282. package/dist/types/message/index.js +2 -0
  283. package/dist/types/message/index.js.map +1 -1
  284. package/dist/types/plugin/index.d.ts +93 -19
  285. package/dist/types/plugin/index.d.ts.map +1 -1
  286. package/dist/types/plugin/index.js +3 -0
  287. package/dist/types/plugin/index.js.map +1 -1
  288. package/dist/types/provider/errors.d.ts +19 -0
  289. package/dist/types/provider/errors.d.ts.map +1 -1
  290. package/dist/types/provider/errors.js +54 -5
  291. package/dist/types/provider/errors.js.map +1 -1
  292. package/dist/types/provider/interface.d.ts +12 -0
  293. package/dist/types/provider/interface.d.ts.map +1 -1
  294. package/dist/types/provider/stream.d.ts +1 -1
  295. package/dist/types/session/config.d.ts +14 -0
  296. package/dist/types/session/config.d.ts.map +1 -1
  297. package/dist/types/session/events.d.ts +27 -4
  298. package/dist/types/session/events.d.ts.map +1 -1
  299. package/dist/types/session/events.js.map +1 -1
  300. package/dist/types/session/records.d.ts +9 -9
  301. package/dist/types/session/records.d.ts.map +1 -1
  302. package/dist/types/session/records.js +1 -0
  303. package/dist/types/session/records.js.map +1 -1
  304. package/dist/types/session/stop-reason.d.ts +5 -0
  305. package/dist/types/session/stop-reason.d.ts.map +1 -1
  306. package/dist/types/tool/index.d.ts +52 -0
  307. package/dist/types/tool/index.d.ts.map +1 -1
  308. package/dist/types/tool/index.js.map +1 -1
  309. package/package.json +4 -2
  310. package/src/agents/QueryAgent.ts +5 -1
  311. package/src/agents/SupervisorAgent.ts +1 -1
  312. package/src/agents/examples/SupervisorAgent.ts +217 -106
  313. package/src/agents/index.ts +1 -1
  314. package/src/authorization/protected-paths.ts +110 -0
  315. package/src/authorization/readonly-commands.ts +771 -0
  316. package/src/authorization/readonly-flags.ts +196 -0
  317. package/src/authorization/removal.ts +326 -0
  318. package/src/authorization/shell-paths.ts +927 -0
  319. package/src/bridge/acp/update.ts +1 -0
  320. package/src/compaction/context-window.ts +41 -0
  321. package/src/compaction/manual.ts +10 -2
  322. package/src/compaction/plan.ts +11 -2
  323. package/src/compaction/verifier.ts +84 -22
  324. package/src/config/runtime.ts +23 -2
  325. package/src/connector/web/guarded-fetch.ts +26 -0
  326. package/src/connector/web/index.ts +3 -0
  327. package/src/connector/web/page.ts +130 -0
  328. package/src/connector/web/types.ts +47 -0
  329. package/src/constants/continuation.ts +10 -0
  330. package/src/constants/plugin/index.ts +1 -1
  331. package/src/manager/agent/lifecycle.ts +12 -4
  332. package/src/manager/session/turn-recorder.ts +10 -2
  333. package/src/plugin/index.ts +1 -0
  334. package/src/plugin/lifecycle.ts +107 -119
  335. package/src/plugin/shell-hook.ts +477 -43
  336. package/src/provider/capabilities.ts +17 -0
  337. package/src/provider/errors.ts +13 -0
  338. package/src/provider/fallback.ts +10 -0
  339. package/src/provider/idle-timeout.ts +5 -0
  340. package/src/provider/image-input-refusal.ts +54 -0
  341. package/src/provider/index.ts +2 -0
  342. package/src/provider/retry.ts +42 -4
  343. package/src/public-runtime.ts +11 -0
  344. package/src/public-types.ts +4 -0
  345. package/src/runtime/jobs/registry.ts +39 -2
  346. package/src/runtime/query/deferred-sandbox.ts +110 -0
  347. package/src/runtime/query/executor/tool-call-admission.ts +79 -13
  348. package/src/runtime/query/executor.ts +267 -11
  349. package/src/runtime/query/finalize-turn.ts +7 -1
  350. package/src/runtime/query/index.ts +169 -52
  351. package/src/runtime/query/iteration/index.ts +439 -35
  352. package/src/runtime/query/iteration/phases/compaction-breaker.ts +108 -0
  353. package/src/runtime/query/iteration/phases/compaction.ts +241 -38
  354. package/src/runtime/query/iteration/phases/context.ts +11 -0
  355. package/src/runtime/query/iteration/phases/tool-review.ts +177 -2
  356. package/src/runtime/query/iteration/provider-rejected-image.ts +71 -5
  357. package/src/runtime/query/iteration/request-repair.ts +743 -0
  358. package/src/runtime/query/iteration/stream-turn.ts +11 -1
  359. package/src/runtime/query/path-escalation.ts +204 -0
  360. package/src/runtime/query/plugin-hooks.ts +8 -0
  361. package/src/runtime/query/reminders.ts +45 -0
  362. package/src/runtime/query/request-rich-content.ts +77 -27
  363. package/src/runtime/query/resume-pending.ts +27 -0
  364. package/src/runtime/query/review-policy.ts +106 -5
  365. package/src/runtime/query/tool-output-budget.ts +115 -1
  366. package/src/runtime/query/tooling.ts +6 -0
  367. package/src/session/paths.ts +11 -1
  368. package/src/store/memory/disk.ts +2 -1
  369. package/src/store/memory/markdown.ts +2 -1
  370. package/src/store/memory/naming.ts +13 -0
  371. package/src/tools/builtins/bash.ts +203 -34
  372. package/src/tools/builtins/computer-use.ts +13 -4
  373. package/src/tools/builtins/content-fingerprint.ts +5 -0
  374. package/src/tools/builtins/edit.ts +69 -19
  375. package/src/tools/builtins/grep.ts +159 -38
  376. package/src/tools/builtins/read-file.ts +48 -5
  377. package/src/tools/builtins/read-render.ts +193 -0
  378. package/src/tools/builtins/web.ts +258 -33
  379. package/src/tools/coordinator/ask-user-question.ts +309 -103
  380. package/src/tools/coordinator/question-options.ts +8 -1
  381. package/src/tools/defineTool.ts +11 -2
  382. package/src/tools/paths.ts +1 -1
  383. package/src/types/agent/query.ts +3 -0
  384. package/src/types/errors/catalog.ts +1 -1
  385. package/src/types/hitl/index.ts +104 -0
  386. package/src/types/message/index.ts +2 -0
  387. package/src/types/plugin/index.ts +101 -18
  388. package/src/types/provider/errors.ts +66 -5
  389. package/src/types/provider/interface.ts +13 -0
  390. package/src/types/provider/stream.ts +1 -1
  391. package/src/types/session/config.ts +14 -0
  392. package/src/types/session/events.ts +32 -4
  393. package/src/types/session/records.ts +1 -0
  394. package/src/types/session/stop-reason.ts +5 -0
  395. package/src/types/tool/index.ts +53 -2
@@ -55,6 +55,14 @@ export type HITLResumeDecision =
55
55
  * listed here for an unmarked call is ignored rather than trusted.
56
56
  */
57
57
  skillGranted?: readonly string[]
58
+ /**
59
+ * Ids of calls approved on the strength of a `pre_tool_use` hook's
60
+ * `allow` ({@link ToolCallSummary.hookGrant}), with nobody asked.
61
+ *
62
+ * Audited like `skillGranted`, and ignored for any id whose call did
63
+ * not carry the mark.
64
+ */
65
+ hookGranted?: readonly string[]
58
66
  }
59
67
  | {
60
68
  action: 'modify_tools'
@@ -77,6 +85,15 @@ export type HITLResumeDecision =
77
85
  action: 'answer_question'
78
86
  selectedOptionIds: string[]
79
87
  freeText?: string
88
+ /**
89
+ * One answer per question of a batch (`UserQuestionData.questions`).
90
+ * When present it is the answer; `selectedOptionIds`/`freeText`
91
+ * then carry nothing the tool reads (send `[]`). Absent on a
92
+ * single-question park, and on a batch from a host that only
93
+ * knows one question — then `selectedOptionIds`/`freeText`
94
+ * answer the first question and the rest are unanswered.
95
+ */
96
+ answers?: readonly UserQuestionAnswer[]
80
97
  /**
81
98
  * Echo of `UserQuestionData.questionId` — the misdirection
82
99
  * guard. The park/resolve registry on hosts is typically
@@ -176,6 +193,28 @@ export interface ToolCallSummary {
176
193
  * and `strict`. A host's own handler may ignore it.
177
194
  */
178
195
  skillGrant?: { readonly skill: string }
196
+ /**
197
+ * What a `pre_tool_use` hook answered about approving this call, as the
198
+ * hooks reported it. `ask` is acted on by the kernel (it makes the call an
199
+ * explicit review); `allow` is acted on only through {@link hookGrant}.
200
+ */
201
+ hookPermission?: {
202
+ readonly decision: 'allow' | 'ask'
203
+ readonly reason?: string
204
+ }
205
+ /**
206
+ * Present when a `pre_tool_use` hook said `allow` and nothing stronger
207
+ * stands in the way.
208
+ *
209
+ * Marked on the same terms as {@link skillGrant}: only a call the
210
+ * operator's policy left to review (no `deny`, no explicit `ask` rule, no
211
+ * hook `ask`), that is not destructive, carries no {@link escalation} and
212
+ * is not one the tool always asks about. A sandbox escape, a path outside
213
+ * the roots, a tool's own `requiresApproval`, a rule's review and the
214
+ * dangerous-pattern floor therefore all still reach a person, or refuse.
215
+ * `plan` and `strict` refuse a marked call exactly as they refuse any other.
216
+ */
217
+ hookGrant?: { readonly reason?: string }
179
218
  }
180
219
 
181
220
  /** See {@link ToolCallSummary.escalation}. */
@@ -218,6 +257,27 @@ export interface ToolCallEscalation {
218
257
  * where a program name is actually decided.
219
258
  */
220
259
  unknownProgram?: string
260
+ /**
261
+ * Absolute paths this call writes that are protected in every mode: git
262
+ * hooks and config, shell rc files, editor and tool configuration, the
263
+ * project's own `.namzu` directory (see `authorization/protected-paths.ts`
264
+ * for the list). A write there plants something that runs later, outside
265
+ * the turn, so it is asked about every time and refused when nobody can be
266
+ * asked; no rule, mode or remembered approval covers it. Set for the file
267
+ * tools' declared path and for the visible write targets of a shell line:
268
+ * output redirections, and the operands of `cp`, `mv`, `tee`, `touch`,
269
+ * `mkdir`, `rm`, `rmdir` and `sed -i`.
270
+ */
271
+ protectedPaths?: readonly string[]
272
+ /**
273
+ * Why a shell line removes something it must not: the file system root, a
274
+ * top-level directory, the home directory, the working directory or one of
275
+ * its parents, a glob that crosses directories, or a target a variable or
276
+ * substitution may empty. The flags do not matter, only the targets. Asked
277
+ * about every time and refused when nobody can be asked. Present only for a
278
+ * tool that declares `commandArgument`.
279
+ */
280
+ dangerousRemoval?: string
221
281
  }
222
282
 
223
283
  export interface ToolModification {
@@ -250,6 +310,12 @@ export interface UserQuestionOption {
250
310
  * Absent, not `false`, on every other option.
251
311
  */
252
312
  recommended?: boolean
313
+ /**
314
+ * Plain text or markdown a host may show beside the option list while this
315
+ * option is focused (a snippet, a mock-up, a side-by-side). Optional and
316
+ * never required to answer; a host that has nowhere to show it ignores it.
317
+ */
318
+ preview?: string
253
319
  }
254
320
 
255
321
  /**
@@ -267,6 +333,44 @@ export interface UserQuestionData {
267
333
  options: UserQuestionOption[]
268
334
  multiSelect: boolean
269
335
  allowFreeText: boolean
336
+ /**
337
+ * Present when one `ask_user_question` call carries several related
338
+ * questions (two to four; a single question leaves this out). The
339
+ * top-level `question`, `header`, `options`, `multiSelect` and
340
+ * `allowFreeText` then mirror the FIRST entry, so a host that does not
341
+ * know this field still shows a coherent question and answers it; the
342
+ * rest read as unanswered.
343
+ *
344
+ * A host shows all of them together, collects every answer, and returns
345
+ * one {@link UserQuestionAnswer} per question it has an answer for through
346
+ * `answer_question.answers`.
347
+ */
348
+ questions?: readonly UserQuestionItem[]
349
+ }
350
+
351
+ /**
352
+ * One question of a batch. `id` is stable: the asking `tool_use_id`, `#`, and
353
+ * the question's zero-based position, so an answer names the question it
354
+ * belongs to even when a host shows them in another order.
355
+ */
356
+ export interface UserQuestionItem {
357
+ id: string
358
+ question: string
359
+ header?: string
360
+ options: UserQuestionOption[]
361
+ multiSelect: boolean
362
+ allowFreeText: boolean
363
+ }
364
+
365
+ /**
366
+ * The answer to one question of a batch. A question with no entry was not
367
+ * answered; an entry with no selection and no text counts the same.
368
+ */
369
+ export interface UserQuestionAnswer {
370
+ /** {@link UserQuestionItem.id}. */
371
+ questionId: string
372
+ selectedOptionIds: string[]
373
+ freeText?: string
270
374
  }
271
375
 
272
376
  export interface PlanApprovalData {
@@ -352,11 +352,13 @@ export const RUNTIME_CONTEXT_MESSAGE_KINDS = [
352
352
  'answer-review',
353
353
  'auto-continuation',
354
354
  'channel-message',
355
+ 'hook-feedback',
355
356
  'host-observation',
356
357
  'job-exit',
357
358
  'limit-finalization',
358
359
  'peer-message',
359
360
  'peer-notice',
361
+ 'reminder',
360
362
  'repeat-call',
361
363
  'steering',
362
364
  'step-context',
@@ -107,6 +107,24 @@ export type PluginHookEvent =
107
107
  | 'turn_interrupt'
108
108
  | 'pre_tool_use'
109
109
  | 'post_tool_use'
110
+ /**
111
+ * A tool call ended in failure. Fired after `post_tool_use` for the same
112
+ * call, only when the result is a failure. Carries `toolName`, `toolInput`
113
+ * and `toolResult`.
114
+ */
115
+ | 'post_tool_use_failure'
116
+ /**
117
+ * A person is about to be asked whether a tool call may run. Carries
118
+ * `toolName` and `toolInput`. A hook may answer before the question is
119
+ * shown: `continue` with `permission: { decision: 'allow' }` approves the
120
+ * call (never one that is always asked about), `skip` refuses it.
121
+ */
122
+ | 'permission_request'
123
+ /**
124
+ * The host wants the operator's attention: a review is waiting, or a turn
125
+ * settled. Carries `notification` (`type` and `message`). Observational.
126
+ */
127
+ | 'notification'
110
128
  | 'pre_llm_call'
111
129
  | 'post_llm_call'
112
130
  | 'iteration_start'
@@ -139,6 +157,9 @@ export function assertPluginHookEvent(event: PluginHookEvent): void {
139
157
  case 'turn_interrupt':
140
158
  case 'pre_tool_use':
141
159
  case 'post_tool_use':
160
+ case 'post_tool_use_failure':
161
+ case 'permission_request':
162
+ case 'notification':
142
163
  case 'pre_llm_call':
143
164
  case 'post_llm_call':
144
165
  case 'iteration_start':
@@ -196,6 +217,16 @@ export interface PluginCompactionInfo {
196
217
  readonly contextWindowTokens: number
197
218
  }
198
219
 
220
+ /** What a `notification` hook is shown. */
221
+ export interface PluginNotificationInfo {
222
+ /**
223
+ * `approval_required` (a review is waiting), `turn_settled` (a turn ended) or
224
+ * `idle_prompt` (the host has waited for the operator for a while).
225
+ */
226
+ readonly type: 'approval_required' | 'turn_settled' | 'idle_prompt'
227
+ readonly message: string
228
+ }
229
+
199
230
  export interface PluginHookContext {
200
231
  /** The turn the hook fired in. Absent on `session_start` and `session_end`. */
201
232
  readonly turnId?: TurnId
@@ -214,6 +245,15 @@ export interface PluginHookContext {
214
245
  readonly toolName?: string
215
246
  readonly toolInput?: unknown
216
247
  readonly toolResult?: ToolResult
248
+ /** What the host is telling the operator, on `notification`. */
249
+ readonly notification?: PluginNotificationInfo
250
+ /**
251
+ * On `turn_end` and `subagent_stop` when an earlier answer to the same
252
+ * event kept the turn going: the hook is being asked again about a turn it
253
+ * already refused to let end. A hook that always refuses would otherwise
254
+ * keep the model working until the turn's own limits stop it.
255
+ */
256
+ readonly stopHookActive?: boolean
217
257
  readonly iteration?: number
218
258
  /**
219
259
  * Why the turn was stopped, on `turn_interrupt`.
@@ -267,8 +307,41 @@ export interface PluginHookContext {
267
307
  readonly signal?: AbortSignal
268
308
  }
269
309
 
310
+ /**
311
+ * What a hook may say about a tool call beyond letting it run or not. Only
312
+ * `allow` and `ask` exist here: a refusal is `skip`, which always wins.
313
+ *
314
+ * `allow` stands in for the person's yes ONLY on a call that would have been
315
+ * asked about for no reason beyond "it changes something". It never covers a
316
+ * sandbox escape, a path outside the roots, a call the tool declares it always
317
+ * needs approval for, a call a rule sent to review explicitly, or one the tool
318
+ * declares destructive; and it never reopens what a rule denied.
319
+ * `ask` makes the call go to a person even where a rule or the tool's own
320
+ * read-only declaration would have let it through.
321
+ */
322
+ export interface PluginHookPermission {
323
+ readonly decision: 'allow' | 'ask'
324
+ readonly reason?: string
325
+ }
326
+
327
+ /** Extra facts a hook may attach to the verdicts that let the work go on. */
328
+ export interface PluginHookNotes {
329
+ /**
330
+ * Text for the model. On a tool event it is appended to what the model
331
+ * reads of that call; on `user_prompt_submit` it joins the turn's context.
332
+ */
333
+ readonly context?: string
334
+ /** Stop the turn once the current step is done. `reason` is shown to the operator. */
335
+ readonly halt?: { readonly reason: string }
336
+ /** A warning for the operator, reported through the logger. */
337
+ readonly notice?: string
338
+ }
339
+
270
340
  export type PluginHookResult =
271
- | { action: 'continue' }
341
+ | ({
342
+ action: 'continue'
343
+ permission?: PluginHookPermission
344
+ } & PluginHookNotes)
272
345
  /**
273
346
  * Add to what the model is told, without changing anything else.
274
347
  *
@@ -278,8 +351,12 @@ export type PluginHookResult =
278
351
  * it is rejected, because a tool result is not a place for context.
279
352
  */
280
353
  | { action: 'annotate'; text: string }
281
- | { action: 'skip'; reason: string }
282
- | { action: 'modify'; input: unknown }
354
+ | ({ action: 'skip'; reason: string } & PluginHookNotes)
355
+ | ({
356
+ action: 'modify'
357
+ input: unknown
358
+ permission?: PluginHookPermission
359
+ } & PluginHookNotes)
283
360
  | { action: 'error'; message: string }
284
361
  | { action: 'retry' }
285
362
  /**
@@ -333,9 +410,15 @@ export type PluginHookResultFor<E extends PluginHookEvent> = E extends 'user_pro
333
410
  ? Extract<PluginHookResult, { action: 'continue' | 'skip' | 'modify' | 'error' }>
334
411
  : E extends 'post_tool_use'
335
412
  ? Extract<PluginHookResult, { action: 'continue' | 'replace' | 'retry' | 'error' }>
336
- : E extends 'turn_interrupt' | 'session_start' | 'session_end'
337
- ? Extract<PluginHookResult, { action: 'continue' }>
338
- : Extract<PluginHookResult, { action: 'continue' | 'error' }>
413
+ : E extends 'post_tool_use_failure'
414
+ ? Extract<PluginHookResult, { action: 'continue' | 'error' }>
415
+ : E extends 'permission_request'
416
+ ? Extract<PluginHookResult, { action: 'continue' | 'skip' }>
417
+ : E extends 'turn_end' | 'subagent_stop' | 'pre_compact'
418
+ ? Extract<PluginHookResult, { action: 'continue' | 'skip' | 'error' }>
419
+ : E extends 'turn_interrupt' | 'session_start' | 'session_end' | 'notification'
420
+ ? Extract<PluginHookResult, { action: 'continue' }>
421
+ : Extract<PluginHookResult, { action: 'continue' | 'error' }>
339
422
 
340
423
  /** The event and its handler verdict stay correlated, including in hook arrays. */
341
424
  export type PluginHookDefinition<E extends PluginHookEvent = PluginHookEvent> =
@@ -344,21 +427,21 @@ export type PluginHookDefinition<E extends PluginHookEvent = PluginHookEvent> =
344
427
  readonly event: E
345
428
  readonly handler: (context: PluginHookContext) => Promise<PluginHookResultFor<E>>
346
429
  /**
347
- * Lower runs first. Default 100.
430
+ * Lower comes first in the answers. Default 100.
348
431
  *
349
- * Order was install order, which is neither declared nor stable — it
350
- * depends on when each plugin happened to be installed. That is fine
351
- * for hooks that only observe, and wrong for the ones that decide:
352
- * `executeHooks` SHORT-CIRCUITS on `skip` and `error`, so a hook that
353
- * denies a dangerous command only gets to deny it if it runs before
354
- * whatever else stops the chain. A guard that fires depending on
355
- * installation history is not a guard.
356
- *
357
- * Ties keep registration order, so plugins that never set a priority
358
- * behave exactly as before. Convention: guards below 100, observers
359
- * above.
432
+ * The hooks of one event start together and none waits for another, so
433
+ * priority no longer says who runs first; it says whose answer is read
434
+ * first. The first refusal in that order is the one the model is told,
435
+ * and of several rewrites the last in that order wins. Ties keep
436
+ * registration order. Convention: guards below 100, observers above.
360
437
  */
361
438
  readonly priority?: number
439
+ /**
440
+ * Text for the operator's status line while this hook runs. Carried on
441
+ * the `plugin_hook_executing` event; a host that draws no status line
442
+ * ignores it.
443
+ */
444
+ readonly statusMessage?: string
362
445
  }
363
446
  : never
364
447
 
@@ -237,6 +237,47 @@ function chainMessages(err: unknown): string[] {
237
237
  return out
238
238
  }
239
239
 
240
+ /**
241
+ * What a provider said when prompt plus requested output together passed the
242
+ * window: the prompt size, the output cap that was asked for, and the window.
243
+ */
244
+ export interface OutputOverflowFigures {
245
+ readonly inputTokens: number
246
+ readonly maxTokens: number
247
+ readonly contextLimit: number
248
+ }
249
+
250
+ /**
251
+ * Read the "input length and `max_tokens` exceed context limit: A + B > C"
252
+ * wording from a failure, anywhere on its cause chain.
253
+ *
254
+ * Different from a prompt that is too long on its own: here the prompt fits
255
+ * and only the requested output does not, so the remedy is a smaller
256
+ * `max_tokens`, not a smaller history. `undefined` means the failure does not
257
+ * carry those figures.
258
+ */
259
+ export function readOutputOverflow(err: unknown): OutputOverflowFigures | undefined {
260
+ const pattern = /input length and `?max_tokens`? exceed context limit: (\d+) \+ (\d+) > (\d+)/i
261
+ for (const message of chainMessages(err)) {
262
+ const match = pattern.exec(message)
263
+ if (!match) continue
264
+ const inputTokens = Number.parseInt(match[1] ?? '', 10)
265
+ const maxTokens = Number.parseInt(match[2] ?? '', 10)
266
+ const contextLimit = Number.parseInt(match[3] ?? '', 10)
267
+ if (![inputTokens, maxTokens, contextLimit].every(Number.isFinite)) continue
268
+ return { inputTokens, maxTokens, contextLimit }
269
+ }
270
+ return undefined
271
+ }
272
+
273
+ /** Undici's `TypeError: terminated` anywhere on the chain: the body stream was cut. */
274
+ function isUndiciTermination(err: unknown): boolean {
275
+ for (const link of causeChain(err)) {
276
+ if ((link as unknown) instanceof TypeError && link.message === 'terminated') return true
277
+ }
278
+ return false
279
+ }
280
+
240
281
  /** Node/undici transport failures that mean "never reached the model". */
241
282
  const NETWORK_ERRNOS: ReadonlySet<string> = new Set([
242
283
  'ECONNRESET',
@@ -271,12 +312,19 @@ function codeFromStatus(status: number): ProviderErrorCode {
271
312
  return 'unknown'
272
313
  }
273
314
 
315
+ function overflowWordingAllowed(status: number | undefined): boolean {
316
+ return status === undefined || status === 400 || status === 413
317
+ }
318
+
319
+ const CONTEXT_WINDOW_OVERFLOW =
320
+ /(?:exceed\w*|too (?:long|large|big)|larger than|longer than|over the|beyond|maximum|overflow\w*)\b[^.]{0,60}context window|context window[^.]{0,60}\b(?:exceed\w*|too (?:long|large|big)|larger than|longer than|over the|beyond|maximum|overflow\w*)/i
321
+
274
322
  /**
275
323
  * Message sniffing is the LAST resort, used only when there is no status
276
324
  * and no errno. Vendors that tunnel a 400 through a 200 body (several
277
325
  * gateways do) are only reachable this way.
278
326
  */
279
- function codeFromMessage(message: string): ProviderErrorCode | undefined {
327
+ function codeFromMessage(message: string, status?: number): ProviderErrorCode | undefined {
280
328
  const m = message.toLowerCase()
281
329
  if (
282
330
  m.includes('context length') ||
@@ -289,6 +337,13 @@ function codeFromMessage(message: string): ProviderErrorCode | undefined {
289
337
  // overflow rescue tests for by exact equality. The turn died holding
290
338
  // the remedy.
291
339
  m.includes('too long for') ||
340
+ // The reference terminal's own wordings (its `context window` and
341
+ // `input length and max_tokens exceed context limit` matchers).
342
+ // Only where the status cannot say otherwise: a 429, 5xx or 401 that
343
+ // mentions the window is still a rate limit, a server fault or an auth
344
+ // failure, and must keep its retry and fallback behaviour.
345
+ (overflowWordingAllowed(status) &&
346
+ (CONTEXT_WINDOW_OVERFLOW.test(message) || m.includes('exceed context limit'))) ||
292
347
  m.includes('maximum length') ||
293
348
  m.includes('exceeds the maximum') ||
294
349
  m.includes('input is too large') ||
@@ -465,7 +520,9 @@ export function classifyProviderError(
465
520
  // usually generic ("request failed") — so matching only the outer text
466
521
  // looks at the one string least likely to say anything.
467
522
  const messages = chainMessages(err)
468
- const fromMessage = messages.map(codeFromMessage).find((code) => code !== undefined)
523
+ const fromMessage = messages
524
+ .map((m) => codeFromMessage(m, status))
525
+ .find((code) => code !== undefined)
469
526
  // A first-hand statement from whoever produced the failure, if there
470
527
  // is one. It outranks the code's inference, not the code itself: the
471
528
  // classification still says WHAT went wrong.
@@ -489,7 +546,7 @@ export function classifyProviderError(
489
546
 
490
547
  // A 400 that is really a window overflow must not be filed as a plain
491
548
  // invalid_request: the caller can recover from one and not the other.
492
- if (messages.some((m) => codeFromMessage(m) === 'context_length_exceeded')) {
549
+ if (messages.some((m) => codeFromMessage(m, status) === 'context_length_exceeded')) {
493
550
  return new ProviderError({
494
551
  code: 'context_length_exceeded',
495
552
  message,
@@ -533,8 +590,12 @@ export function classifyProviderError(
533
590
  }
534
591
  }
535
592
 
536
- // `fetch` rejects with a bare TypeError on transport failure.
537
- if (err instanceof TypeError && /fetch|network/i.test(message)) {
593
+ // `fetch` rejects with a bare TypeError on transport failure, and undici
594
+ // ends a response body the peer cut mid-stream with `TypeError:
595
+ // terminated`. Its socket error normally rides along as the cause and the
596
+ // errno walk above catches it, but a vendor SDK that re-wraps the stream
597
+ // error can drop that cause and leave only the bare word.
598
+ if ((err instanceof TypeError && /fetch|network/i.test(message)) || isUndiciTermination(err)) {
538
599
  return new ProviderError({
539
600
  code: 'network',
540
601
  message,
@@ -22,6 +22,19 @@ export interface LLMProvider {
22
22
  /** Refine hosted search support for a model and mode. Absent uses the driver-wide declaration. */
23
23
  supportsHostedWebSearchFor?(model: string, mode: 'live' | 'cached'): boolean
24
24
 
25
+ /**
26
+ * Whether `model` reads images. `capabilities.supportsVision` is a statement
27
+ * about the DRIVER (does it map image parts onto the wire); this is about the
28
+ * MODEL behind it, which only the driver's catalogue can know: one driver
29
+ * serves vision and text-only models side by side, and a text-only model
30
+ * refuses the whole request when it finds an image in it.
31
+ *
32
+ * Answer `false` only when the model is known to be text-only. Absent, or
33
+ * `true`, means "send images": the runtime also recovers from a refusal, so a
34
+ * driver with no catalogue loses nothing by omitting this.
35
+ */
36
+ supportsImageInputFor?(model: string): boolean
37
+
25
38
  /**
26
39
  * Retry behaviour this DRIVER wants, when the generic default is wrong
27
40
  * for the vendor behind it.
@@ -174,7 +174,7 @@ export interface ProviderRetryNotice {
174
174
  /** The delay came from the server's own `Retry-After`, not backoff. */
175
175
  readonly serverDirected: boolean
176
176
  /**
177
- * The failed attempt had already streamed text or reasoning, and the request
177
+ * The failed attempt had already streamed text or reasoning (reasoning alone is retried without any option), and the request
178
178
  * is being sent again from the start. Whatever that attempt produced is void
179
179
  * and the consumer must drop it before the next chunk.
180
180
  */
@@ -88,6 +88,20 @@ export interface TurnConfig {
88
88
  * behaviour every sandboxed turn had before this existed.
89
89
  */
90
90
  workspace?: 'ephemeral' | 'working-directory'
91
+ /**
92
+ * When the turn acquires its sandbox. Absent means `'eager'`: acquired,
93
+ * and waited for, before the input guardrails and the first model
94
+ * request.
95
+ *
96
+ * `'concurrent'` starts at the same point but lets the first model
97
+ * request go out while the provider allocates; the first tool call
98
+ * waits for the handle. `'on-first-use'` does not start until the first
99
+ * tool call. Either way `sandbox_created` is emitted when the handle
100
+ * arrives, and a failure or timeout ends the turn with the stop reason
101
+ * an eager acquisition would have produced, at the first tool call or
102
+ * at turn end, whichever comes first.
103
+ */
104
+ acquire?: 'eager' | 'concurrent' | 'on-first-use'
91
105
  }
92
106
 
93
107
  /**
@@ -279,11 +279,20 @@ type CoreSessionEvent =
279
279
  * `tool_result`, so it was refused wholesale rather than sent to
280
280
  * a provider that rejects the pairing. A reducer bug, and one
281
281
  * `findSafeTrimIndex` exists to prevent.
282
+ * - `breaker_open` — only with `compactionConfig.circuitBreaker`:
283
+ * three passes in a row failed, so proactive compaction is off for
284
+ * the rest of the turn; a context overflow the provider reports
285
+ * still runs the reactive relief. Sent once, without `error`: it is
286
+ * for a host's records, not a line for the person. `messages` is
287
+ * the live count.
288
+ * - `refilling` — only with `compactionConfig.circuitBreaker`: the
289
+ * context filled back up within three iterations of a compaction,
290
+ * three times in a row, and the turn is stopping. Sent once.
282
291
  */
283
- cause: 'reducer_threw' | 'shed_nothing' | 'split_tool_pair'
292
+ cause: 'reducer_threw' | 'shed_nothing' | 'split_tool_pair' | 'breaker_open' | 'refilling'
284
293
  /** Unchanged, and stated so a reader need not infer it. */
285
294
  messages: number
286
- /** Present only for `reducer_threw`. */
295
+ /** For `reducer_threw`, the reducer's message; for `refilling`, the one line to show. */
287
296
  error?: string
288
297
  }
289
298
  | {
@@ -708,9 +717,26 @@ type CoreSessionEvent =
708
717
  sessionId: SessionId
709
718
  turnId?: TurnId
710
719
  capability: 'tools' | 'vision' | 'documents'
711
- /** Present when the mismatch was produced after a tool executed. */
712
- contentSource?: 'tool-result'
720
+ /**
721
+ * Present when the mismatch was not about the user's own message:
722
+ * `'tool-result'` after a tool executed; `'history'` when the model
723
+ * itself turned out not to read images (see `model`) and the images
724
+ * already in the conversation were left out of the request;
725
+ * `'media-removed'` when the provider rejected an image or document
726
+ * and it was left out of the request that then went through;
727
+ * `'media-removed-current'` when that included a file attached to the
728
+ * latest user message; `'media-limit'` when the oldest files were left
729
+ * out only to fit a count the provider accepts.
730
+ */
731
+ contentSource?:
732
+ | 'tool-result'
733
+ | 'history'
734
+ | 'media-removed'
735
+ | 'media-removed-current'
736
+ | 'media-limit'
713
737
  providerId: string
738
+ /** The model that cannot read images, when the warning is about one model rather than the driver. */
739
+ model?: string
714
740
  message: string
715
741
  }
716
742
  /**
@@ -992,6 +1018,8 @@ type CoreSessionEvent =
992
1018
  turnId?: TurnId
993
1019
  pluginId: PluginId
994
1020
  hookEvent: PluginHookEvent
1021
+ /** The hook's own text for a status line while it runs, when it declared one. */
1022
+ statusMessage?: string
995
1023
  }
996
1024
  | {
997
1025
  type: 'plugin_hook_completed'
@@ -235,6 +235,7 @@ const stopReason = z.enum([
235
235
  'stop_condition',
236
236
  'step_refused',
237
237
  'structured_output_failed',
238
+ 'output_limit',
238
239
  'answer_rejected',
239
240
  'input_guardrail',
240
241
  'output_guardrail',
@@ -38,6 +38,11 @@ export type StopReason =
38
38
  | 'step_refused'
39
39
  /** The model never produced a valid structured output within its retries. */
40
40
  | 'structured_output_failed'
41
+ /**
42
+ * The model's reply was cut off at its output limit more times in a row
43
+ * than `maxOutputContinuations` allows. Only with that option set.
44
+ */
45
+ | 'output_limit'
41
46
  /**
42
47
  * A host reviewer kept rejecting the answer and the turn ran out of
43
48
  * attempts.
@@ -1,3 +1,4 @@
1
+ import type { ChildProcess } from 'node:child_process'
1
2
  import type { z } from 'zod'
2
3
  import type { CodeNavigationProvider } from '../code-navigation/index.js'
3
4
  // Type-only, and circular by design: a tool-result guardrail is described in
@@ -118,7 +119,24 @@ export interface BackgroundJobRegistryRef {
118
119
  id: string
119
120
  status: string
120
121
  }
121
- get(id: string): { id: string; status: string; exitCode?: number; error?: string }
122
+ get(id: string): {
123
+ id: string
124
+ status: string
125
+ exitCode?: number
126
+ error?: string
127
+ }
128
+ /**
129
+ * Take over a process the caller already started and is waiting on, so a
130
+ * foreground command that outran its timeout can keep running as a job
131
+ * instead of being killed. Optional: a host without it (or a sandboxed
132
+ * turn) keeps the kill. Throws when the owner is at its job cap.
133
+ */
134
+ adopt?(params: {
135
+ command: string
136
+ child: ChildProcess
137
+ workingDirectory?: string
138
+ initialOutput?: readonly { readonly stream: 'stdout' | 'stderr'; readonly text: string }[]
139
+ }): { id: string; status: string }
122
140
  /**
123
141
  * Resolves once the process exists or failed to start (`error` says why).
124
142
  * Optional: a host that cannot tell may omit it, and `bash` then replies
@@ -483,15 +501,39 @@ export interface ToolContext {
483
501
  */
484
502
  web?: {
485
503
  readonly fetch?: {
486
- fetch(request: { url: string; signal?: AbortSignal }): Promise<{
504
+ fetch(request: {
505
+ url: string
506
+ signal?: AbortSignal
507
+ /** `same-host` asks for a redirect to another site to be handed back, not followed. */
508
+ redirects?: 'follow' | 'same-host'
509
+ headers?: Readonly<Record<string, string>>
510
+ }): Promise<{
487
511
  url: string
488
512
  status: number
489
513
  contentType?: string
490
514
  body: string
491
515
  truncated: boolean
492
516
  redirects: readonly string[]
517
+ /** A redirect that was not followed; `body` is then empty. */
518
+ redirect?: { url: string; status: number }
493
519
  }>
494
520
  }
521
+ /**
522
+ * Answers a prompt from a page with a small model. Optional: without
523
+ * it `web_fetch` returns the page as markdown instead of an answer.
524
+ */
525
+ readonly extract?: {
526
+ extract(request: {
527
+ url: string
528
+ prompt: string
529
+ content: string
530
+ instruction: string
531
+ body: string
532
+ signal?: AbortSignal
533
+ sessionId: string
534
+ turnId: string
535
+ }): Promise<string | undefined>
536
+ }
495
537
  readonly search?: {
496
538
  search(request: {
497
539
  query: string
@@ -1103,6 +1145,15 @@ export interface ToolDefinition<TInput = unknown> extends ToolPresentation<TInpu
1103
1145
  * their external effects have stopped, and does not imply success.
1104
1146
  */
1105
1147
  executionBarrier?: boolean
1148
+ /**
1149
+ * The tool bounds its own output (a paged read, say), so the turn's default
1150
+ * per-result cap does not apply to it and its result is never replaced to
1151
+ * fit the per-message budget.
1152
+ *
1153
+ * Only the DEFAULT is lifted. A host that sets `maxToolOutputChars`
1154
+ * explicitly still bounds this tool's result by it.
1155
+ */
1156
+ selfLimitingOutput?: boolean
1106
1157
  }
1107
1158
 
1108
1159
  /**