@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
@@ -12,6 +12,7 @@ import {
12
12
  replaceProjectInstructionSnapshot,
13
13
  } from '../../project-instructions.js'
14
14
  import { attachRepeatNotice } from '../../repeat-call.js'
15
+ import { isReviewExempt } from '../../review-policy.js'
15
16
  import { attachNotice, attachSteering, formatJobNote } from '../../steering.js'
16
17
  import { type IterationContext, awaitDecisionDurably } from './context.js'
17
18
 
@@ -25,11 +26,23 @@ function escalationReason(escalation: ToolCallSummary['escalation']): string {
25
26
  return `this call's program cannot be verified ahead of time (${escalation.unknownProgram})`
26
27
  }
27
28
  if (escalation?.sandboxEscape) return "this call asks to run outside the turn's sandbox"
29
+ if (escalation?.dangerousRemoval !== undefined) {
30
+ return `this call removes something catastrophic (${escalation.dangerousRemoval})`
31
+ }
32
+ if (escalation?.protectedPaths?.length) {
33
+ return `this call writes a protected ${escalation.protectedPaths.length === 1 ? 'path' : 'paths'} (${escalation.protectedPaths.join(', ')})`
34
+ }
28
35
  if (escalation?.outsidePaths?.length)
29
36
  return `this call reaches ${escalation.outsidePaths.length === 1 ? 'a path' : 'paths'} outside the turn's boundary`
30
37
  return "this call reaches past the turn's boundary, which a rule cannot approve on its own"
31
38
  }
32
39
 
40
+ function hookAskedReason(reason: string | undefined): string {
41
+ return reason
42
+ ? `a hook asked that a person approve this call: ${reason}`
43
+ : 'a hook asked that a person approve this call'
44
+ }
45
+
33
46
  export type ToolReviewDecision = 'executed' | 'rejected' | 'stop'
34
47
 
35
48
  /**
@@ -124,15 +137,27 @@ export async function* runToolReview(
124
137
  const isDestructive = tool?.isDestructive ? tool.isDestructive(tc.input) : false
125
138
  const requiresApproval = tool?.requiresApproval ? tool.requiresApproval(tc.input) : false
126
139
  const escalation = 'escalation' in tc ? tc.escalation : undefined
140
+ const hookPermission = 'hookPermission' in tc ? tc.hookPermission : undefined
127
141
 
128
142
  return {
129
143
  id: tc.id,
130
144
  name: tc.name,
131
145
  input: tc.input,
132
146
  isDestructive,
133
- authorization: { decision: 'review' },
147
+ // A hook that asked for a person is an explicit review: a call the
148
+ // tool declares read-only, or one a rule would allow, is still put
149
+ // to one.
150
+ authorization:
151
+ hookPermission?.decision === 'ask'
152
+ ? {
153
+ decision: 'review' as const,
154
+ reason: hookAskedReason(hookPermission.reason),
155
+ explicitReview: true as const,
156
+ }
157
+ : { decision: 'review' as const },
134
158
  ...(requiresApproval ? { requiresApproval: true as const } : {}),
135
159
  ...(escalation ? { escalation } : {}),
160
+ ...(hookPermission ? { hookPermission } : {}),
136
161
  }
137
162
  })
138
163
  }
@@ -355,6 +380,24 @@ export async function* runToolReview(
355
380
  reason,
356
381
  })
357
382
  }
383
+ for (const path of tc.escalation?.protectedPaths ?? []) {
384
+ await ctx.recorder.recordAudit({
385
+ what: { action: 'protected_path_write', tool: tc.name, resource: path },
386
+ outcome: 'refused',
387
+ reason,
388
+ })
389
+ }
390
+ if (tc.escalation?.dangerousRemoval !== undefined) {
391
+ await ctx.recorder.recordAudit({
392
+ what: {
393
+ action: 'dangerous_removal',
394
+ tool: tc.name,
395
+ resource: tc.escalation.dangerousRemoval,
396
+ },
397
+ outcome: 'refused',
398
+ reason,
399
+ })
400
+ }
358
401
  }
359
402
 
360
403
  // Gate-denied ids survive the whole function: a later human approval
@@ -419,11 +462,21 @@ export async function* runToolReview(
419
462
  reason: `${gr.gateResult.reason}; but the tool itself declares this call always needs a person's approval, which a rule cannot waive`,
420
463
  }
421
464
  }
465
+ // A hook that asked for a person can only ADD a review, like the two
466
+ // overrides above: a `deny` stays a denial.
467
+ const hookAsked = gr.toolCall.hookPermission?.decision === 'ask'
468
+ if (hookAsked && gr.gateResult.decision === 'allow') {
469
+ gr.gateResult = {
470
+ decision: 'review',
471
+ matchedRule: gr.gateResult.matchedRule,
472
+ reason: `${gr.gateResult.reason}; but ${hookAskedReason(gr.toolCall.hookPermission?.reason)}`,
473
+ }
474
+ }
422
475
  const { toolCall, gateResult } = gr
423
476
  toolCall.authorization = {
424
477
  decision: gateResult.decision,
425
478
  ...(gateResult.reason ? { reason: gateResult.reason } : {}),
426
- ...(gateResult.decision === 'review' && gateResult.matchedRule
479
+ ...(gateResult.decision === 'review' && (gateResult.matchedRule || hookAsked)
427
480
  ? { explicitReview: true as const }
428
481
  : {}),
429
482
  }
@@ -498,6 +551,27 @@ export async function* runToolReview(
498
551
  }
499
552
  }
500
553
 
554
+ // A `pre_tool_use` hook's `allow`, marked on the calls it covers on the
555
+ // same terms as a skill's grant above and honoured by the review policy,
556
+ // never decided here. A deny, an explicit review (a rule's, or a hook's own
557
+ // `ask`), a destructive call, a path outside the roots, a sandbox escape and
558
+ // a tool's own `requiresApproval` all leave the call unmarked, so it is
559
+ // reviewed as though no hook had spoken.
560
+ /** Whether a hook's `allow` may stand in for a person on this call. */
561
+ const hookMayAllow = (tc: ToolCallSummary): boolean =>
562
+ !gateDenied.has(tc.id) &&
563
+ tc.authorization?.decision !== 'deny' &&
564
+ !tc.authorization?.explicitReview &&
565
+ !tc.isDestructive &&
566
+ tc.escalation === undefined &&
567
+ !tc.requiresApproval
568
+ for (const tc of toolCallSummaries) {
569
+ if (tc.hookPermission?.decision !== 'allow' || !hookMayAllow(tc)) continue
570
+ tc.hookGrant = {
571
+ ...(tc.hookPermission.reason ? { reason: tc.hookPermission.reason } : {}),
572
+ }
573
+ }
574
+
501
575
  // Already approved, at a scope the approver chose — and nothing the
502
576
  // operator's policy denied, because `gateDenied` is checked first.
503
577
  // Re-asking about a call somebody has already said yes to is how an
@@ -525,6 +599,76 @@ export async function* runToolReview(
525
599
  return finish('executed')
526
600
  }
527
601
 
602
+ // A person is about to be asked. `permission_request` hooks may answer
603
+ // first, per call: `skip` refuses it (and always wins), `allow` approves it
604
+ // on the same terms as a `pre_tool_use` allow. A read the review policy
605
+ // would not have asked about is not a question and is not offered.
606
+ if (ctx.pluginManager) {
607
+ const questions = toolCallSummaries.filter(
608
+ (tc) =>
609
+ !gateDenied.has(tc.id) &&
610
+ tc.authorization?.decision !== 'deny' &&
611
+ tc.authorization?.decision !== 'allow' &&
612
+ (tc.authorization?.explicitReview === true ||
613
+ tc.escalation !== undefined ||
614
+ tc.requiresApproval === true ||
615
+ tc.isDestructive ||
616
+ !isReviewExempt(ctx.tools, tc.name, tc.input)),
617
+ )
618
+ for (const tc of questions) {
619
+ const answers = await ctx.pluginManager.executeHooks(
620
+ 'permission_request',
621
+ {
622
+ sessionId: ctx.recorder.sessionId,
623
+ turnId: ctx.recorder.turnId,
624
+ toolName: tc.name,
625
+ toolInput: tc.input,
626
+ signal: ctx.abortController.signal,
627
+ },
628
+ ctx.emitEvent,
629
+ )
630
+ // The hooks answered side by side: a refusal from any of them stands,
631
+ // whatever the others allowed.
632
+ const refusal = answers.find((answer) => answer.action === 'skip')
633
+ for (const answer of answers) {
634
+ if ((answer.action === 'continue' || answer.action === 'skip') && answer.halt) {
635
+ ctx.toolExecutor.requestHalt?.(answer.halt.reason)
636
+ }
637
+ }
638
+ if (refusal?.action === 'skip') {
639
+ const reason = `Blocked by a permission_request hook: ${refusal.reason}`
640
+ gateDenied.set(tc.id, reason)
641
+ tc.authorization = { decision: 'deny', reason }
642
+ await ctx.recorder.recordAudit({
643
+ what: { action: 'tool_call', tool: tc.name },
644
+ outcome: 'refused',
645
+ reason,
646
+ })
647
+ continue
648
+ }
649
+ for (const answer of answers) {
650
+ if (
651
+ answer.action === 'continue' &&
652
+ answer.permission?.decision === 'allow' &&
653
+ hookMayAllow(tc)
654
+ ) {
655
+ tc.hookGrant = {
656
+ ...(answer.permission.reason ? { reason: answer.permission.reason } : {}),
657
+ }
658
+ }
659
+ }
660
+ }
661
+ if (toolCallSummaries.every((tc) => gateDenied.has(tc.id))) {
662
+ for (const tc of escalated()) {
663
+ const reason = gateDenied.get(tc.id)
664
+ if (reason !== undefined) await recordRefusedEscalation(tc, reason)
665
+ }
666
+ yield* settle(gateDenied)
667
+ yield* ctx.drainPending()
668
+ return finish('rejected')
669
+ }
670
+ }
671
+
528
672
  const reviewCheckpoint = await ctx.checkpointMgr.create(ctx.recorder, iterationNum)
529
673
 
530
674
  await ctx.emitEvent({
@@ -607,6 +751,24 @@ export async function* runToolReview(
607
751
  reason: "the turn's review approved this call",
608
752
  })
609
753
  }
754
+ for (const path of tc.escalation?.protectedPaths ?? []) {
755
+ await ctx.recorder.recordAudit({
756
+ what: { action: 'protected_path_write', tool: tc.name, resource: path },
757
+ outcome: 'approved',
758
+ reason: "the turn's review approved this call",
759
+ })
760
+ }
761
+ if (tc.escalation?.dangerousRemoval !== undefined) {
762
+ await ctx.recorder.recordAudit({
763
+ what: {
764
+ action: 'dangerous_removal',
765
+ tool: tc.name,
766
+ resource: tc.escalation.dangerousRemoval,
767
+ },
768
+ outcome: 'approved',
769
+ reason: "the turn's review approved this call",
770
+ })
771
+ }
610
772
  }
611
773
  }
612
774
 
@@ -762,6 +924,19 @@ export async function* runToolReview(
762
924
  }
763
925
  }
764
926
 
927
+ // The same for a call a hook's `allow` approved.
928
+ if (reviewDecision.action === 'approve_tools' && reviewDecision.hookGranted) {
929
+ const listed = new Set(reviewDecision.hookGranted)
930
+ for (const tc of toolCallSummaries) {
931
+ if (!listed.has(tc.id) || !tc.hookGrant || gateDenied.has(tc.id)) continue
932
+ await ctx.recorder.recordAudit({
933
+ what: { action: 'tool_call', tool: tc.name },
934
+ outcome: 'approved',
935
+ reason: `pre-approved by a pre_tool_use hook${tc.hookGrant.reason ? ` (${tc.hookGrant.reason})` : ''}; nobody was asked`,
936
+ })
937
+ }
938
+ }
939
+
765
940
  await ctx.emitEvent({
766
941
  type: 'tool_review_completed',
767
942
  turnId: ctx.recorder.turnId,
@@ -1,4 +1,5 @@
1
1
  import { isProviderRequestError } from '../../../provider/errors.js'
2
+ import { isImageInputRefusal } from '../../../provider/image-input-refusal.js'
2
3
  import type { Message } from '../../../types/message/index.js'
3
4
  import type {
4
5
  ChatCompletionParams,
@@ -8,8 +9,11 @@ import type {
8
9
  import {
9
10
  type RequestImageIdentity,
10
11
  findSingleRequestImage,
12
+ projectRequestRichContent,
11
13
  projectRequestWithoutImage,
14
+ requestHasImages,
12
15
  } from '../request-rich-content.js'
16
+ import type { RequestRepair } from './request-repair.js'
13
17
 
14
18
  const IMAGE_REJECTION_PATTERNS: readonly RegExp[] = [
15
19
  /\binvalid[_ -]?image\b/i,
@@ -52,6 +56,24 @@ function throwIfAborted(signal: AbortSignal | undefined): void {
52
56
  if (signal?.aborted) throw signal.reason
53
57
  }
54
58
 
59
+ /** The provider and model that refused a request for holding an image. */
60
+ export interface TextOnlyModelRefusal {
61
+ readonly providerId: string
62
+ readonly model: string | undefined
63
+ }
64
+
65
+ /** See {@link streamWithProviderRejectedImageRecovery}. */
66
+ export interface TextOnlyModelRecovery {
67
+ /**
68
+ * Who is serving the request. A fallback chain reports its head's id and
69
+ * moves between members, so without this the refusal would be filed against
70
+ * a model that never saw the request. Read when the refusal arrives.
71
+ */
72
+ readonly servedBy?: () => { readonly providerId: string; readonly model?: string }
73
+ /** The retry without images was accepted: `refused` cannot read images. */
74
+ readonly onAccepted: (refused: TextOnlyModelRefusal) => void | Promise<void>
75
+ }
76
+
55
77
  /**
56
78
  * Retry one provider-invalid request without its only distinct image.
57
79
  *
@@ -65,29 +87,73 @@ export async function* streamWithProviderRejectedImageRecovery(
65
87
  params: ChatCompletionParams,
66
88
  onAccepted: (identity: RequestImageIdentity) => Promise<void>,
67
89
  onRequest?: (messages: readonly Message[]) => void,
90
+ textOnly?: TextOnlyModelRecovery,
91
+ repair?: RequestRepair,
68
92
  ): AsyncIterable<StreamChunk> {
93
+ // Every send, including the retries below, goes through the request repair.
94
+ // They share one repair budget: the original request and its retries are
95
+ // one request to the person, and each resend is a paid call.
96
+ const session = repair?.session()
97
+ const send = (request: ChatCompletionParams): AsyncIterable<StreamChunk> =>
98
+ repair ? repair.stream(provider, request, session) : provider.chatStream(request)
69
99
  const candidate = findSingleRequestImage(params.messages)
70
100
  onRequest?.(params.messages)
71
- if (candidate === null) {
72
- yield* provider.chatStream(params)
101
+ if (candidate === null && !requestHasImages(params.messages)) {
102
+ yield* send(params)
73
103
  return
74
104
  }
75
105
 
76
106
  let produced = false
77
107
  let confidence: ImageRejectionConfidence | null = null
108
+ let refused: TextOnlyModelRefusal | null = null
78
109
  try {
79
- for await (const chunk of provider.chatStream(params)) {
110
+ for await (const chunk of send(params)) {
80
111
  if (isAcceptedChunk(chunk)) produced = true
81
112
  yield chunk
82
113
  }
83
114
  return
84
115
  } catch (error) {
85
116
  throwIfAborted(params.signal)
117
+ if (produced) throw error
118
+ // A fault in one image (the server's own `invalid_image`, or wording that
119
+ // says an image could not be decoded) is about that image, not about the
120
+ // model, and it wins: the model reads images, so it keeps the others.
86
121
  confidence = classifyProviderRejectedImageError(error)
87
- if (produced || confidence === null) throw error
122
+ if (confidence === null && isImageInputRefusal(error)) {
123
+ // A model that reads text only refuses the request however many images
124
+ // it holds, so every image goes. Named now, while the member that
125
+ // refused is still the one serving.
126
+ const served = textOnly?.servedBy?.()
127
+ refused = {
128
+ providerId: served?.providerId ?? provider.id,
129
+ model: served?.model ?? params.model,
130
+ }
131
+ } else if (confidence === null || candidate === null) {
132
+ throw error
133
+ }
88
134
  }
89
135
 
90
136
  throwIfAborted(params.signal)
137
+ if (refused !== null) {
138
+ // One retry, without any image. The stored conversation is untouched, so
139
+ // a model that does read images gets them again.
140
+ const messages = projectRequestRichContent(params.messages, 0, { imagesReadable: false })
141
+ onRequest?.(messages)
142
+ let accepted = false
143
+ let reportedError = false
144
+ for await (const chunk of send({ ...params, messages })) {
145
+ if (chunk.error !== undefined) reportedError = true
146
+ if (!accepted && isAcceptedChunk(chunk)) {
147
+ throwIfAborted(params.signal)
148
+ await textOnly?.onAccepted(refused)
149
+ accepted = true
150
+ }
151
+ yield chunk
152
+ }
153
+ if (!accepted && !reportedError) await textOnly?.onAccepted(refused)
154
+ return
155
+ }
156
+ if (candidate === null) return
91
157
  const retryParams: ChatCompletionParams = {
92
158
  ...params,
93
159
  messages: projectRequestWithoutImage(params.messages, candidate),
@@ -95,7 +161,7 @@ export async function* streamWithProviderRejectedImageRecovery(
95
161
  let accepted = false
96
162
  let retryReportedError = false
97
163
  onRequest?.(retryParams.messages)
98
- for await (const chunk of provider.chatStream(retryParams)) {
164
+ for await (const chunk of send(retryParams)) {
99
165
  if (chunk.error !== undefined) retryReportedError = true
100
166
  if (!accepted && isAcceptedChunk(chunk)) {
101
167
  throwIfAborted(params.signal)