@namzu/sdk 62.6.1 → 62.8.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 (344) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/dist/agents/QueryAgent.d.ts.map +1 -1
  3. package/dist/agents/QueryAgent.js +5 -0
  4. package/dist/agents/QueryAgent.js.map +1 -1
  5. package/dist/agents/examples/SupervisorAgent.d.ts.map +1 -1
  6. package/dist/agents/examples/SupervisorAgent.js +1 -0
  7. package/dist/agents/examples/SupervisorAgent.js.map +1 -1
  8. package/dist/agents/explore.d.ts.map +1 -1
  9. package/dist/agents/explore.js +2 -1
  10. package/dist/agents/explore.js.map +1 -1
  11. package/dist/compaction/index.d.ts +1 -1
  12. package/dist/compaction/index.d.ts.map +1 -1
  13. package/dist/compaction/index.js +1 -1
  14. package/dist/compaction/index.js.map +1 -1
  15. package/dist/compaction/model-summary.js +2 -2
  16. package/dist/compaction/model-summary.js.map +1 -1
  17. package/dist/compaction/summary.d.ts +16 -1
  18. package/dist/compaction/summary.d.ts.map +1 -1
  19. package/dist/compaction/summary.js +25 -2
  20. package/dist/compaction/summary.js.map +1 -1
  21. package/dist/config/runtime.d.ts +8 -0
  22. package/dist/config/runtime.d.ts.map +1 -1
  23. package/dist/config/runtime.js +15 -0
  24. package/dist/config/runtime.js.map +1 -1
  25. package/dist/execution/workflow/runtime.d.ts.map +1 -1
  26. package/dist/execution/workflow/runtime.js +3 -0
  27. package/dist/execution/workflow/runtime.js.map +1 -1
  28. package/dist/execution/workflow/types.d.ts +8 -0
  29. package/dist/execution/workflow/types.d.ts.map +1 -1
  30. package/dist/manager/agent/child-session.d.ts +12 -0
  31. package/dist/manager/agent/child-session.d.ts.map +1 -1
  32. package/dist/manager/agent/child-session.js +29 -0
  33. package/dist/manager/agent/child-session.js.map +1 -1
  34. package/dist/manager/agent/lifecycle.d.ts.map +1 -1
  35. package/dist/manager/agent/lifecycle.js +8 -0
  36. package/dist/manager/agent/lifecycle.js.map +1 -1
  37. package/dist/manager/session/turn-recorder.d.ts +13 -2
  38. package/dist/manager/session/turn-recorder.d.ts.map +1 -1
  39. package/dist/manager/session/turn-recorder.js +107 -29
  40. package/dist/manager/session/turn-recorder.js.map +1 -1
  41. package/dist/prompt/coding-agent-doctrine.d.ts +3 -3
  42. package/dist/prompt/coding-agent-doctrine.d.ts.map +1 -1
  43. package/dist/prompt/coding-agent-doctrine.js +5 -3
  44. package/dist/prompt/coding-agent-doctrine.js.map +1 -1
  45. package/dist/provider/fallback.d.ts.map +1 -1
  46. package/dist/provider/fallback.js +5 -1
  47. package/dist/provider/fallback.js.map +1 -1
  48. package/dist/provider/retry.d.ts +25 -0
  49. package/dist/provider/retry.d.ts.map +1 -1
  50. package/dist/provider/retry.js +28 -0
  51. package/dist/provider/retry.js.map +1 -1
  52. package/dist/public-runtime.d.ts +3 -3
  53. package/dist/public-runtime.d.ts.map +1 -1
  54. package/dist/public-runtime.js +3 -3
  55. package/dist/public-runtime.js.map +1 -1
  56. package/dist/public-tools.d.ts +4 -2
  57. package/dist/public-tools.d.ts.map +1 -1
  58. package/dist/public-tools.js +5 -2
  59. package/dist/public-tools.js.map +1 -1
  60. package/dist/runtime/query/auto-review/classifier.d.ts +7 -1
  61. package/dist/runtime/query/auto-review/classifier.d.ts.map +1 -1
  62. package/dist/runtime/query/auto-review/classifier.js +8 -4
  63. package/dist/runtime/query/auto-review/classifier.js.map +1 -1
  64. package/dist/runtime/query/auto-review/prompt.d.ts.map +1 -1
  65. package/dist/runtime/query/auto-review/prompt.js +2 -0
  66. package/dist/runtime/query/auto-review/prompt.js.map +1 -1
  67. package/dist/runtime/query/auto-review/script-evidence.d.ts +93 -0
  68. package/dist/runtime/query/auto-review/script-evidence.d.ts.map +1 -0
  69. package/dist/runtime/query/auto-review/script-evidence.js +566 -0
  70. package/dist/runtime/query/auto-review/script-evidence.js.map +1 -0
  71. package/dist/runtime/query/checkpoint.d.ts +13 -0
  72. package/dist/runtime/query/checkpoint.d.ts.map +1 -1
  73. package/dist/runtime/query/checkpoint.js +37 -0
  74. package/dist/runtime/query/checkpoint.js.map +1 -1
  75. package/dist/runtime/query/context.d.ts.map +1 -1
  76. package/dist/runtime/query/context.js +28 -2
  77. package/dist/runtime/query/context.js.map +1 -1
  78. package/dist/runtime/query/executor.d.ts +38 -1
  79. package/dist/runtime/query/executor.d.ts.map +1 -1
  80. package/dist/runtime/query/executor.js +154 -13
  81. package/dist/runtime/query/executor.js.map +1 -1
  82. package/dist/runtime/query/finalize-turn.d.ts +7 -1
  83. package/dist/runtime/query/finalize-turn.d.ts.map +1 -1
  84. package/dist/runtime/query/finalize-turn.js +2 -0
  85. package/dist/runtime/query/finalize-turn.js.map +1 -1
  86. package/dist/runtime/query/index.d.ts +8 -0
  87. package/dist/runtime/query/index.d.ts.map +1 -1
  88. package/dist/runtime/query/index.js +7 -0
  89. package/dist/runtime/query/index.js.map +1 -1
  90. package/dist/runtime/query/iteration/index.d.ts +32 -1
  91. package/dist/runtime/query/iteration/index.d.ts.map +1 -1
  92. package/dist/runtime/query/iteration/index.js +158 -10
  93. package/dist/runtime/query/iteration/index.js.map +1 -1
  94. package/dist/runtime/query/iteration/phases/compaction.d.ts +12 -0
  95. package/dist/runtime/query/iteration/phases/compaction.d.ts.map +1 -1
  96. package/dist/runtime/query/iteration/phases/compaction.js +48 -1
  97. package/dist/runtime/query/iteration/phases/compaction.js.map +1 -1
  98. package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
  99. package/dist/runtime/query/iteration/phases/context.js +5 -0
  100. package/dist/runtime/query/iteration/phases/context.js.map +1 -1
  101. package/dist/runtime/query/iteration/stream-turn.js +3 -3
  102. package/dist/runtime/query/iteration/stream-turn.js.map +1 -1
  103. package/dist/runtime/query/prelude-lease.d.ts.map +1 -1
  104. package/dist/runtime/query/prelude-lease.js +22 -0
  105. package/dist/runtime/query/prelude-lease.js.map +1 -1
  106. package/dist/runtime/query/prepare-turn.d.ts.map +1 -1
  107. package/dist/runtime/query/prepare-turn.js +30 -12
  108. package/dist/runtime/query/prepare-turn.js.map +1 -1
  109. package/dist/runtime/query/review-policy.d.ts.map +1 -1
  110. package/dist/runtime/query/review-policy.js +29 -0
  111. package/dist/runtime/query/review-policy.js.map +1 -1
  112. package/dist/runtime/query/session-storage.d.ts.map +1 -1
  113. package/dist/runtime/query/session-storage.js +44 -3
  114. package/dist/runtime/query/session-storage.js.map +1 -1
  115. package/dist/runtime/query/tooling.d.ts +2 -0
  116. package/dist/runtime/query/tooling.d.ts.map +1 -1
  117. package/dist/runtime/query/tooling.js +1 -0
  118. package/dist/runtime/query/tooling.js.map +1 -1
  119. package/dist/runtime/query/turn/completion-audit.d.ts +27 -1
  120. package/dist/runtime/query/turn/completion-audit.d.ts.map +1 -1
  121. package/dist/runtime/query/turn/completion-audit.js +71 -6
  122. package/dist/runtime/query/turn/completion-audit.js.map +1 -1
  123. package/dist/runtime/query/turn/outcome-ledger.d.ts +113 -0
  124. package/dist/runtime/query/turn/outcome-ledger.d.ts.map +1 -0
  125. package/dist/runtime/query/turn/outcome-ledger.js +578 -0
  126. package/dist/runtime/query/turn/outcome-ledger.js.map +1 -0
  127. package/dist/sandbox/file-walk.d.ts +7 -1
  128. package/dist/sandbox/file-walk.d.ts.map +1 -1
  129. package/dist/sandbox/file-walk.js +30 -4
  130. package/dist/sandbox/file-walk.js.map +1 -1
  131. package/dist/sandbox/glob-segment.d.ts +8 -1
  132. package/dist/sandbox/glob-segment.d.ts.map +1 -1
  133. package/dist/sandbox/glob-segment.js +28 -9
  134. package/dist/sandbox/glob-segment.js.map +1 -1
  135. package/dist/store/checkpoint/contract.d.ts +12 -0
  136. package/dist/store/checkpoint/contract.d.ts.map +1 -1
  137. package/dist/store/checkpoint/contract.js.map +1 -1
  138. package/dist/store/checkpoint/disk.d.ts.map +1 -1
  139. package/dist/store/checkpoint/disk.js +34 -2
  140. package/dist/store/checkpoint/disk.js.map +1 -1
  141. package/dist/store/checkpoint/prune.d.ts.map +1 -1
  142. package/dist/store/checkpoint/prune.js +6 -0
  143. package/dist/store/checkpoint/prune.js.map +1 -1
  144. package/dist/store/evidence/disk.js +40 -3
  145. package/dist/store/evidence/disk.js.map +1 -1
  146. package/dist/store/session-log/incremental.d.ts +23 -0
  147. package/dist/store/session-log/incremental.d.ts.map +1 -0
  148. package/dist/store/session-log/incremental.js +117 -0
  149. package/dist/store/session-log/incremental.js.map +1 -0
  150. package/dist/store/session-log/index.d.ts +1 -0
  151. package/dist/store/session-log/index.d.ts.map +1 -1
  152. package/dist/store/session-log/index.js +1 -0
  153. package/dist/store/session-log/index.js.map +1 -1
  154. package/dist/store/session-log/turn-outcome.d.ts +37 -0
  155. package/dist/store/session-log/turn-outcome.d.ts.map +1 -0
  156. package/dist/store/session-log/turn-outcome.js +77 -0
  157. package/dist/store/session-log/turn-outcome.js.map +1 -0
  158. package/dist/tools/admit-facts.d.ts.map +1 -1
  159. package/dist/tools/admit-facts.js +1 -0
  160. package/dist/tools/admit-facts.js.map +1 -1
  161. package/dist/tools/builtins/bash.d.ts.map +1 -1
  162. package/dist/tools/builtins/bash.js +11 -2
  163. package/dist/tools/builtins/bash.js.map +1 -1
  164. package/dist/tools/builtins/bounded-file-read.d.ts +19 -1
  165. package/dist/tools/builtins/bounded-file-read.d.ts.map +1 -1
  166. package/dist/tools/builtins/bounded-file-read.js +56 -3
  167. package/dist/tools/builtins/bounded-file-read.js.map +1 -1
  168. package/dist/tools/builtins/edit-apply.d.ts.map +1 -1
  169. package/dist/tools/builtins/edit-apply.js +24 -3
  170. package/dist/tools/builtins/edit-apply.js.map +1 -1
  171. package/dist/tools/builtins/edit.d.ts +31 -17
  172. package/dist/tools/builtins/edit.d.ts.map +1 -1
  173. package/dist/tools/builtins/edit.js +92 -27
  174. package/dist/tools/builtins/edit.js.map +1 -1
  175. package/dist/tools/builtins/glob.js +1 -1
  176. package/dist/tools/builtins/glob.js.map +1 -1
  177. package/dist/tools/builtins/grep.d.ts +8 -0
  178. package/dist/tools/builtins/grep.d.ts.map +1 -1
  179. package/dist/tools/builtins/grep.js +148 -21
  180. package/dist/tools/builtins/grep.js.map +1 -1
  181. package/dist/tools/builtins/notebook-guard.d.ts +19 -0
  182. package/dist/tools/builtins/notebook-guard.d.ts.map +1 -0
  183. package/dist/tools/builtins/notebook-guard.js +75 -0
  184. package/dist/tools/builtins/notebook-guard.js.map +1 -0
  185. package/dist/tools/builtins/read-render.d.ts.map +1 -1
  186. package/dist/tools/builtins/read-render.js +8 -2
  187. package/dist/tools/builtins/read-render.js.map +1 -1
  188. package/dist/tools/builtins/search-support.d.ts +8 -0
  189. package/dist/tools/builtins/search-support.d.ts.map +1 -1
  190. package/dist/tools/builtins/search-support.js +66 -0
  191. package/dist/tools/builtins/search-support.js.map +1 -1
  192. package/dist/tools/builtins/write-file.d.ts.map +1 -1
  193. package/dist/tools/builtins/write-file.js +14 -1
  194. package/dist/tools/builtins/write-file.js.map +1 -1
  195. package/dist/tools/coordinator/agent.d.ts.map +1 -1
  196. package/dist/tools/coordinator/agent.js +25 -6
  197. package/dist/tools/coordinator/agent.js.map +1 -1
  198. package/dist/tools/coordinator/index.d.ts.map +1 -1
  199. package/dist/tools/coordinator/index.js +6 -1
  200. package/dist/tools/coordinator/index.js.map +1 -1
  201. package/dist/tools/coordinator/outcome-record.d.ts +22 -0
  202. package/dist/tools/coordinator/outcome-record.d.ts.map +1 -0
  203. package/dist/tools/coordinator/outcome-record.js +91 -0
  204. package/dist/tools/coordinator/outcome-record.js.map +1 -0
  205. package/dist/tools/defineTool.d.ts +2 -0
  206. package/dist/tools/defineTool.d.ts.map +1 -1
  207. package/dist/tools/defineTool.js +1 -0
  208. package/dist/tools/defineTool.js.map +1 -1
  209. package/dist/tools/file-read-tracker.d.ts +23 -2
  210. package/dist/tools/file-read-tracker.d.ts.map +1 -1
  211. package/dist/tools/file-read-tracker.js +37 -2
  212. package/dist/tools/file-read-tracker.js.map +1 -1
  213. package/dist/tools/untrusted-envelope.d.ts +6 -0
  214. package/dist/tools/untrusted-envelope.d.ts.map +1 -1
  215. package/dist/tools/untrusted-envelope.js +22 -1
  216. package/dist/tools/untrusted-envelope.js.map +1 -1
  217. package/dist/toolsets/manager.d.ts.map +1 -1
  218. package/dist/toolsets/manager.js +3 -4
  219. package/dist/toolsets/manager.js.map +1 -1
  220. package/dist/toolsets/validation-issues.d.ts +27 -0
  221. package/dist/toolsets/validation-issues.d.ts.map +1 -0
  222. package/dist/toolsets/validation-issues.js +83 -0
  223. package/dist/toolsets/validation-issues.js.map +1 -0
  224. package/dist/turn/memory-recall.d.ts +13 -0
  225. package/dist/turn/memory-recall.d.ts.map +1 -1
  226. package/dist/turn/memory-recall.js +18 -0
  227. package/dist/turn/memory-recall.js.map +1 -1
  228. package/dist/types/agent/base.d.ts +19 -0
  229. package/dist/types/agent/base.d.ts.map +1 -1
  230. package/dist/types/agent/query.d.ts +2 -0
  231. package/dist/types/agent/query.d.ts.map +1 -1
  232. package/dist/types/common/index.d.ts +17 -0
  233. package/dist/types/common/index.d.ts.map +1 -1
  234. package/dist/types/common/index.js +8 -1
  235. package/dist/types/common/index.js.map +1 -1
  236. package/dist/types/hitl/index.d.ts +22 -0
  237. package/dist/types/hitl/index.d.ts.map +1 -1
  238. package/dist/types/hitl/index.js.map +1 -1
  239. package/dist/types/session/config.d.ts +20 -0
  240. package/dist/types/session/config.d.ts.map +1 -1
  241. package/dist/types/session/events.d.ts +3 -3
  242. package/dist/types/session/events.d.ts.map +1 -1
  243. package/dist/types/session/index.d.ts +1 -0
  244. package/dist/types/session/index.d.ts.map +1 -1
  245. package/dist/types/session/index.js +1 -0
  246. package/dist/types/session/index.js.map +1 -1
  247. package/dist/types/session/outcome.d.ts +95 -0
  248. package/dist/types/session/outcome.d.ts.map +1 -0
  249. package/dist/types/session/outcome.js +45 -0
  250. package/dist/types/session/outcome.js.map +1 -0
  251. package/dist/types/session/prepare-step.d.ts +2 -0
  252. package/dist/types/session/prepare-step.d.ts.map +1 -1
  253. package/dist/types/session/records.d.ts +167 -2
  254. package/dist/types/session/records.d.ts.map +1 -1
  255. package/dist/types/session/records.js +42 -0
  256. package/dist/types/session/records.js.map +1 -1
  257. package/dist/types/session/turn.d.ts +18 -0
  258. package/dist/types/session/turn.d.ts.map +1 -1
  259. package/dist/types/session/turn.js.map +1 -1
  260. package/dist/types/tool/index.d.ts +30 -0
  261. package/dist/types/tool/index.d.ts.map +1 -1
  262. package/dist/types/tool/index.js.map +1 -1
  263. package/dist/types/tool/presentation.d.ts +6 -0
  264. package/dist/types/tool/presentation.d.ts.map +1 -1
  265. package/package.json +1 -1
  266. package/src/agents/QueryAgent.ts +5 -0
  267. package/src/agents/examples/SupervisorAgent.ts +1 -0
  268. package/src/agents/explore.ts +2 -1
  269. package/src/compaction/index.ts +1 -0
  270. package/src/compaction/model-summary.ts +2 -2
  271. package/src/compaction/summary.ts +30 -2
  272. package/src/config/runtime.ts +15 -0
  273. package/src/execution/workflow/runtime.ts +4 -0
  274. package/src/execution/workflow/types.ts +9 -0
  275. package/src/manager/agent/child-session.ts +36 -0
  276. package/src/manager/agent/lifecycle.ts +9 -0
  277. package/src/manager/session/turn-recorder.ts +115 -30
  278. package/src/pricing/rates.source.json +1 -1
  279. package/src/prompt/coding-agent-doctrine.ts +5 -3
  280. package/src/provider/fallback.ts +6 -1
  281. package/src/provider/retry.ts +51 -0
  282. package/src/public-runtime.ts +10 -1
  283. package/src/public-tools.ts +6 -1
  284. package/src/runtime/query/auto-review/classifier.ts +21 -5
  285. package/src/runtime/query/auto-review/prompt.ts +2 -0
  286. package/src/runtime/query/auto-review/script-evidence.ts +618 -0
  287. package/src/runtime/query/checkpoint.ts +53 -1
  288. package/src/runtime/query/context.ts +33 -6
  289. package/src/runtime/query/executor.ts +183 -21
  290. package/src/runtime/query/finalize-turn.ts +8 -1
  291. package/src/runtime/query/index.ts +19 -0
  292. package/src/runtime/query/iteration/index.ts +167 -14
  293. package/src/runtime/query/iteration/phases/compaction.ts +53 -3
  294. package/src/runtime/query/iteration/phases/context.ts +6 -0
  295. package/src/runtime/query/iteration/stream-turn.ts +3 -3
  296. package/src/runtime/query/prelude-lease.ts +19 -0
  297. package/src/runtime/query/prepare-turn.ts +29 -12
  298. package/src/runtime/query/review-policy.ts +33 -0
  299. package/src/runtime/query/session-storage.ts +42 -3
  300. package/src/runtime/query/tooling.ts +3 -0
  301. package/src/runtime/query/turn/completion-audit.ts +76 -5
  302. package/src/runtime/query/turn/outcome-ledger.ts +633 -0
  303. package/src/sandbox/file-walk.ts +41 -4
  304. package/src/sandbox/glob-segment.ts +48 -24
  305. package/src/store/checkpoint/contract.ts +15 -0
  306. package/src/store/checkpoint/disk.ts +34 -2
  307. package/src/store/checkpoint/prune.ts +13 -0
  308. package/src/store/evidence/disk.ts +57 -2
  309. package/src/store/session-log/incremental.ts +147 -0
  310. package/src/store/session-log/index.ts +7 -0
  311. package/src/store/session-log/turn-outcome.ts +84 -0
  312. package/src/tools/admit-facts.ts +1 -0
  313. package/src/tools/builtins/bash.ts +12 -2
  314. package/src/tools/builtins/bounded-file-read.ts +59 -2
  315. package/src/tools/builtins/edit-apply.ts +26 -4
  316. package/src/tools/builtins/edit.ts +106 -41
  317. package/src/tools/builtins/glob.ts +1 -1
  318. package/src/tools/builtins/grep.ts +173 -27
  319. package/src/tools/builtins/notebook-guard.ts +76 -0
  320. package/src/tools/builtins/read-render.ts +12 -2
  321. package/src/tools/builtins/search-support.ts +62 -0
  322. package/src/tools/builtins/write-file.ts +12 -1
  323. package/src/tools/coordinator/agent.ts +31 -7
  324. package/src/tools/coordinator/index.ts +6 -1
  325. package/src/tools/coordinator/outcome-record.ts +93 -0
  326. package/src/tools/defineTool.ts +3 -0
  327. package/src/tools/file-read-tracker.ts +51 -2
  328. package/src/tools/untrusted-envelope.ts +23 -1
  329. package/src/toolsets/manager.ts +6 -10
  330. package/src/toolsets/validation-issues.ts +97 -0
  331. package/src/turn/memory-recall.ts +28 -0
  332. package/src/types/agent/base.ts +20 -0
  333. package/src/types/agent/query.ts +2 -0
  334. package/src/types/common/index.ts +25 -1
  335. package/src/types/hitl/index.ts +27 -0
  336. package/src/types/session/config.ts +20 -0
  337. package/src/types/session/events.ts +3 -3
  338. package/src/types/session/index.ts +1 -0
  339. package/src/types/session/outcome.ts +139 -0
  340. package/src/types/session/prepare-step.ts +2 -0
  341. package/src/types/session/records.ts +67 -1
  342. package/src/types/session/turn.ts +19 -0
  343. package/src/types/tool/index.ts +30 -0
  344. package/src/types/tool/presentation.ts +6 -0
@@ -27,6 +27,7 @@ import { compressShellOutput } from '../../utils/shell-compress.js';
27
27
  import { parseStructuredResultJson } from '../../utils/structured-result-json.js';
28
28
  import { ensureScratchpadDirectory } from '../../utils/temp.js';
29
29
  import { bindOwner } from '../jobs/registry.js';
30
+ import { analyzeLaunches, changedSinceRead, readLaunchedScripts, } from './auto-review/script-evidence.js';
30
31
  import { stillRunningResult } from './detached-calls.js';
31
32
  import { formatFailedToolOutput, hookNote, isUnregistered, prepareDirectCall, runPreToolHook, unknownToolMessage, } from './executor/tool-call-admission.js';
32
33
  import { describeVisibleFileEvidence, visibleFileEvidence, } from './file-evidence-context.js';
@@ -213,15 +214,37 @@ export const DECLINED_NOTE_MAX_CHARS = 4_000;
213
214
  * for administrator rights is named as that; everything else is a plain block.
214
215
  * Read from the call's own argument, never from the refusal's wording.
215
216
  */
216
- function refusalFacts(toolName, input) {
217
+ function refusalFacts(toolName, input, reason) {
217
218
  const command = input && typeof input === 'object' ? input.command : undefined;
218
219
  const elevated = typeof command === 'string' && /(^|[\s;&|(])(sudo|doas)\b/.test(command);
219
220
  return {
220
221
  kind: 'failure',
221
222
  reason: elevated ? 'needs_administrator' : 'blocked',
222
223
  subject: toolName,
224
+ ...(refusalNote(reason) ? { note: refusalNote(reason) } : {}),
223
225
  };
224
226
  }
227
+ const REFUSAL_NOTE_MAX = 200;
228
+ /**
229
+ * The refusal's own reason as one line for the person's view: the first
230
+ * non-empty line, the leading "Blocked:" label dropped, first letter up, bounded. The policy
231
+ * wrote it; nothing here reads the model's text.
232
+ */
233
+ function refusalNote(reason) {
234
+ const line = reason
235
+ ?.split(/\r?\n/)
236
+ .map((part) => part.trim())
237
+ .find(Boolean);
238
+ if (!line)
239
+ return undefined;
240
+ const plain = line.replace(/^Blocked(?: by [^:]{1,60})?:\s*/i, '').trim();
241
+ if (!plain)
242
+ return undefined;
243
+ const sentence = `${plain.charAt(0).toUpperCase()}${plain.slice(1)}`;
244
+ return sentence.length > REFUSAL_NOTE_MAX
245
+ ? `${sentence.slice(0, REFUSAL_NOTE_MAX - 1)}…`
246
+ : sentence;
247
+ }
225
248
  export function deniedToolOutput(toolName, reason) {
226
249
  return `Error: Tool "${toolName}" was not executed. ${reason}`;
227
250
  }
@@ -252,6 +275,9 @@ export class ToolExecutor {
252
275
  toolCallBudget;
253
276
  preparedBatches = new WeakSet();
254
277
  preparedBashDirectories = new WeakMap();
278
+ /** Script files a classifier read for a call, by call id, to be checked again when it runs. */
279
+ reviewedScripts = new Map();
280
+ startedAt = Date.now();
255
281
  /** Ephemeral proof of actual execution; restored messages do not acquire it. */
256
282
  recordedObservations = new Map();
257
283
  /** Set per turn by the orchestrator; see {@link setStepAllowedTools}. */
@@ -463,6 +489,44 @@ export class ToolExecutor {
463
489
  fileEvidenceEntries(messages) {
464
490
  return visibleFileEvidence(messages, this.fileReadTracker, this.config.workingDirectory, this.sandboxed);
465
491
  }
492
+ /**
493
+ * The script files a shell line launches that the agent wrote or that
494
+ * appeared during the session, read now for the auto-mode classifier.
495
+ * Remembers what was read for `callId`, so the file can be checked again
496
+ * just before the call runs.
497
+ */
498
+ async launchedScripts(callId, line, dialect) {
499
+ if (this.sandboxed) {
500
+ // A sandbox's files are not on this host's disk. Say so rather than
501
+ // letting a launch inside one look like a launch of nothing.
502
+ const analysis = analyzeLaunches(line, dialect);
503
+ const named = analysis.launches.map((l) => l.path);
504
+ return named.length === 0 && analysis.unresolved.length === 0
505
+ ? []
506
+ : [
507
+ {
508
+ path: named[0] ?? '(launch form not resolved)',
509
+ origin: 'unknown',
510
+ state: 'unreadable',
511
+ note: 'the command runs in a sandbox whose files are not read for this review, so what the script does is not known',
512
+ },
513
+ ];
514
+ }
515
+ const evidence = await readLaunchedScripts(line, dialect, {
516
+ cwd: effectiveBashWorkingDirectory(this.config.sessionId, this.config.workingDirectory, {
517
+ sandboxed: false,
518
+ }),
519
+ startedAt: this.fileReadTracker.startedAt ?? this.startedAt,
520
+ ...(this.fileReadTracker.authoredFingerprint
521
+ ? { authoredFingerprint: (key) => this.fileReadTracker.authoredFingerprint?.(key) }
522
+ : {}),
523
+ });
524
+ if (evidence.watch.length > 0)
525
+ this.reviewedScripts.set(callId, evidence.watch);
526
+ else
527
+ this.reviewedScripts.delete(callId);
528
+ return evidence.scripts;
529
+ }
466
530
  /** The whole of the evidence as one text, from the same ledger. No filesystem I/O. */
467
531
  describeFileEvidence(messages) {
468
532
  return describeVisibleFileEvidence(messages, this.fileReadTracker, this.config.workingDirectory, this.sandboxed);
@@ -655,12 +719,13 @@ export class ToolExecutor {
655
719
  const earlierPaths = [];
656
720
  for (const toolCall of response.message.toolCalls ?? []) {
657
721
  const prepared = await prepareDirectCall(this.admissionHost(), toolCall, !hostModifiedCallIds?.has(toolCall.id));
658
- const call = await this.refusedBeforeReview(prepared, earlierPaths);
722
+ const beforeReview = await this.refusedBeforeReview(prepared, earlierPaths);
659
723
  const path = inputPathOf(prepared);
660
724
  if (path !== undefined)
661
725
  earlierPaths.push(path);
726
+ this.admitScratchpad(beforeReview);
727
+ const call = await this.refusedOutsideRoot(beforeReview);
662
728
  calls.set(toolCall.id, call);
663
- this.admitScratchpad(call);
664
729
  const escalation = await this.escalationOrUnfinished(call);
665
730
  if (escalation)
666
731
  escalations.set(toolCall.id, escalation);
@@ -670,6 +735,52 @@ export class ToolExecutor {
670
735
  this.config.abortSignal.throwIfAborted();
671
736
  return this.publishPreparedBatch(calls, escalations, scratchpadWrites);
672
737
  }
738
+ /**
739
+ * A file tool's path outside the roots, refused with the host's own words
740
+ * (`QueryParams.outsideRootRefusal`) instead of the tool's generic one.
741
+ *
742
+ * It takes the place of the call like any refusal found while preparing it,
743
+ * so it holds in every permission mode and reaches no reviewer. Only a turn
744
+ * that refuses (`outsideRootAccess: 'refuse'`) and has no sandbox is looked
745
+ * at, and only a tool that declares `pathArgument`. The exemptions are the
746
+ * review's: the scratch folder is a root, and so is this session's retained
747
+ * output for `read`.
748
+ */
749
+ async refusedOutsideRoot(call) {
750
+ const note = this.config.outsideRootRefusal;
751
+ if (call.kind !== 'ready' || note === undefined)
752
+ return call;
753
+ if (this.config.outsideRootAccess !== 'refuse' || this.sandboxed)
754
+ return call;
755
+ const tool = this.config.tools.get(call.toolName);
756
+ if (tool?.pathArgument === undefined)
757
+ return call;
758
+ if (call.input === null || typeof call.input !== 'object')
759
+ return call;
760
+ const value = call.input[tool.pathArgument];
761
+ if (typeof value !== 'string')
762
+ return call;
763
+ try {
764
+ const retained = tool.name === 'read' && (await resolveRetainedOutput(this.outputDirectory(), value));
765
+ if (retained)
766
+ return call;
767
+ const outside = await pathOutsideRoots(this.rootsNow(), value);
768
+ if (outside === undefined)
769
+ return call;
770
+ return {
771
+ kind: 'synthetic',
772
+ toolCall: call.toolCall,
773
+ toolName: call.toolName,
774
+ input: call.input,
775
+ message: formatFailedToolOutput(undefined, `${outside} is outside the working directory. ${note}`),
776
+ isError: true,
777
+ };
778
+ }
779
+ catch {
780
+ this.config.abortSignal.throwIfAborted();
781
+ return call;
782
+ }
783
+ }
673
784
  /**
674
785
  * A ready call the tool already knows cannot run, answered now instead of
675
786
  * after a reviewer has been asked about it (`ToolDefinition.refuseBeforeReview`).
@@ -879,9 +990,10 @@ export class ToolExecutor {
879
990
  const earlierPaths = [];
880
991
  for (const toolCall of response.message.toolCalls ?? []) {
881
992
  if (changedCallIds.has(toolCall.id)) {
882
- const call = await this.refusedBeforeReview(await prepareDirectCall(this.admissionHost(), toolCall, false), earlierPaths);
993
+ const beforeReview = await this.refusedBeforeReview(await prepareDirectCall(this.admissionHost(), toolCall, false), earlierPaths);
994
+ this.admitScratchpad(beforeReview);
995
+ const call = await this.refusedOutsideRoot(beforeReview);
883
996
  calls.set(toolCall.id, call);
884
- this.admitScratchpad(call);
885
997
  const escalation = await this.escalationOrUnfinished(call);
886
998
  if (escalation)
887
999
  escalations.set(toolCall.id, escalation);
@@ -1123,7 +1235,18 @@ export class ToolExecutor {
1123
1235
  let outcome;
1124
1236
  started.add(toolCall.id);
1125
1237
  try {
1126
- outcome = await this.executeSingle(toolCall, ctx, recordObservation, () => progress.close(), preparedCall);
1238
+ const reviewedScripts = this.reviewedScripts.get(toolCall.id);
1239
+ this.reviewedScripts.delete(toolCall.id);
1240
+ const moved = reviewedScripts === undefined ? undefined : await changedSinceRead(reviewedScripts);
1241
+ outcome =
1242
+ moved !== undefined
1243
+ ? {
1244
+ toolCallId: toolCall.id,
1245
+ toolName: toolCall.function.name,
1246
+ output: `Error: ${moved} changed after the safety check read it, so the command was not run. Run it again and it will be checked against the new text.`,
1247
+ isError: true,
1248
+ }
1249
+ : await this.executeSingle(toolCall, ctx, recordObservation, () => progress.close(), preparedCall);
1127
1250
  }
1128
1251
  catch (error) {
1129
1252
  // A call already answered with the placeholder has no batch
@@ -1312,6 +1435,7 @@ export class ToolExecutor {
1312
1435
  failure ??= { error };
1313
1436
  }
1314
1437
  finally {
1438
+ this.reviewedScripts.delete(unit.toolCall.id);
1315
1439
  settledUnit();
1316
1440
  inFlight.delete(unit);
1317
1441
  pump();
@@ -1611,7 +1735,7 @@ export class ToolExecutor {
1611
1735
  toolName: name,
1612
1736
  toolUseId: nestedId,
1613
1737
  output: rawOutput,
1614
- maxChars: this.config.maxToolOutputChars ?? DEFAULT_MAX_TOOL_OUTPUT_CHARS,
1738
+ maxChars: this.toolOutputCap(this.config.tools.get(name), false),
1615
1739
  retainedPreviewChars: this.config.retainedToolPreviewChars,
1616
1740
  spillDir: this.outputDirectory(),
1617
1741
  recoveryRoutes: this.recoveryRoutes(),
@@ -2040,10 +2164,7 @@ export class ToolExecutor {
2040
2164
  ];
2041
2165
  }
2042
2166
  }
2043
- // A tool that bounds its own output is exempt from the DEFAULT per-result
2044
- // cap only; a host that set the cap explicitly still gets it.
2045
- const maxToolOutputChars = this.config.maxToolOutputChars ??
2046
- (executedDefinition?.selfLimitingOutput === true ? 0 : DEFAULT_MAX_TOOL_OUTPUT_CHARS);
2167
+ const maxToolOutputChars = this.toolOutputCap(executedDefinition, true);
2047
2168
  const sourceOutput = output;
2048
2169
  // This owner-bound channel follows the selected receipt after both result
2049
2170
  // screening and post-tool replacement. ToolResult.data and raw input can
@@ -2246,6 +2367,7 @@ export class ToolExecutor {
2246
2367
  ? { handoff: result.handoff }
2247
2368
  : {}),
2248
2369
  ...(revealedTools !== undefined ? { revealedTools } : {}),
2370
+ ...(result.facts !== undefined && !postOverride ? { facts: result.facts } : {}),
2249
2371
  };
2250
2372
  }
2251
2373
  /**
@@ -2683,6 +2805,8 @@ export class ToolExecutor {
2683
2805
  * `executing`, and records a failed activity for the trace.
2684
2806
  */
2685
2807
  async recordDenial(toolCall, reason, preparedCall, declined) {
2808
+ // A call that does not run has no use for what a review read of its scripts.
2809
+ this.reviewedScripts.delete(toolCall.id);
2686
2810
  const toolName = preparedCall?.toolName ?? toolCall.function.name;
2687
2811
  let input = preparedCall?.input ?? {};
2688
2812
  if (!preparedCall) {
@@ -2729,7 +2853,7 @@ export class ToolExecutor {
2729
2853
  ...(declined ? { presentation: this.declinedPresentation(toolName, input, declined) } : {}),
2730
2854
  // A refusal by policy says what kind it was; the person's own No is
2731
2855
  // already carried by the presentation above.
2732
- ...(declined ? {} : { facts: refusalFacts(toolName, input) }),
2856
+ ...(declined ? {} : { facts: refusalFacts(toolName, input, reason) }),
2733
2857
  isError: true,
2734
2858
  });
2735
2859
  return { toolCallId: toolCall.id, toolName, output, isError: true };
@@ -2816,6 +2940,7 @@ export class ToolExecutor {
2816
2940
  toolName,
2817
2941
  output: outcome.output,
2818
2942
  isError: outcome.kind === 'error',
2943
+ ...(outcome.facts ? { facts: outcome.facts } : {}),
2819
2944
  ...(outcome.inputFailure ? { inputFailure: outcome.inputFailure } : {}),
2820
2945
  ...(outcome.skipped ? { skipped: true } : {}),
2821
2946
  };
@@ -2829,6 +2954,22 @@ export class ToolExecutor {
2829
2954
  ...(call.skipped ? { skipped: true } : {}),
2830
2955
  });
2831
2956
  }
2957
+ /**
2958
+ * The per-result character cap for one tool: the turn's cap, tightened by
2959
+ * the tool's own `maxOutputChars`. A tool that bounds its own output is
2960
+ * exempt from the DEFAULT cap only (`exemptSelfLimiting`); a host that set
2961
+ * the cap explicitly still gets it. 0 means no cap.
2962
+ */
2963
+ toolOutputCap(definition, exemptSelfLimiting) {
2964
+ const turn = this.config.maxToolOutputChars ??
2965
+ (exemptSelfLimiting && definition?.selfLimitingOutput === true
2966
+ ? 0
2967
+ : DEFAULT_MAX_TOOL_OUTPUT_CHARS);
2968
+ const own = definition?.maxOutputChars;
2969
+ if (own === undefined || !Number.isFinite(own) || own <= 0)
2970
+ return turn;
2971
+ return turn > 0 ? Math.min(turn, Math.floor(own)) : Math.floor(own);
2972
+ }
2832
2973
  /**
2833
2974
  * The host preview and model text may differ; each gets its own text
2834
2975
  * budget. Rich bytes are measured separately and withheld whole when
@@ -2858,7 +2999,7 @@ export class ToolExecutor {
2858
2999
  toolName,
2859
3000
  toolUseId,
2860
3001
  output: text,
2861
- maxChars: this.config.maxToolOutputChars ?? DEFAULT_MAX_TOOL_OUTPUT_CHARS,
3002
+ maxChars: this.toolOutputCap(this.config.tools.get(toolName), false),
2862
3003
  ...(notice ? { notice } : {}),
2863
3004
  // A tool may return different host and model text. They must
2864
3005
  // never compete for the same exclusive spill filename.