@namzu/sdk 36.0.0 → 38.0.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 (412) hide show
  1. package/CHANGELOG.md +244 -0
  2. package/README.md +68 -41
  3. package/dist/bridge/a2a/mapper.d.ts.map +1 -1
  4. package/dist/bridge/a2a/mapper.js +4 -0
  5. package/dist/bridge/a2a/mapper.js.map +1 -1
  6. package/dist/bridge/sse/mapper.d.ts.map +1 -1
  7. package/dist/bridge/sse/mapper.js +16 -1
  8. package/dist/bridge/sse/mapper.js.map +1 -1
  9. package/dist/compaction/extractor.d.ts +1 -1
  10. package/dist/compaction/extractor.d.ts.map +1 -1
  11. package/dist/compaction/extractor.js +15 -7
  12. package/dist/compaction/extractor.js.map +1 -1
  13. package/dist/compaction/manager.d.ts +2 -0
  14. package/dist/compaction/manager.d.ts.map +1 -1
  15. package/dist/compaction/manager.js +12 -1
  16. package/dist/compaction/manager.js.map +1 -1
  17. package/dist/compaction/verifier.d.ts.map +1 -1
  18. package/dist/compaction/verifier.js +82 -15
  19. package/dist/compaction/verifier.js.map +1 -1
  20. package/dist/config/runtime.d.ts +16 -6
  21. package/dist/config/runtime.d.ts.map +1 -1
  22. package/dist/config/runtime.js +2 -0
  23. package/dist/config/runtime.js.map +1 -1
  24. package/dist/contracts/api.d.ts +1 -1
  25. package/dist/contracts/api.d.ts.map +1 -1
  26. package/dist/contracts/schemas.d.ts +10 -10
  27. package/dist/eval/harness-verification.d.ts +63 -0
  28. package/dist/eval/harness-verification.d.ts.map +1 -0
  29. package/dist/eval/harness-verification.js +165 -0
  30. package/dist/eval/harness-verification.js.map +1 -0
  31. package/dist/eval/index.d.ts +2 -0
  32. package/dist/eval/index.d.ts.map +1 -1
  33. package/dist/eval/index.js +1 -0
  34. package/dist/eval/index.js.map +1 -1
  35. package/dist/execution/code-runtime/json-value.d.ts +10 -0
  36. package/dist/execution/code-runtime/json-value.d.ts.map +1 -0
  37. package/dist/execution/code-runtime/json-value.js +89 -0
  38. package/dist/execution/code-runtime/json-value.js.map +1 -0
  39. package/dist/execution/code-runtime/worker-program.d.ts +8 -0
  40. package/dist/execution/code-runtime/worker-program.d.ts.map +1 -0
  41. package/dist/execution/code-runtime/worker-program.js +240 -0
  42. package/dist/execution/code-runtime/worker-program.js.map +1 -0
  43. package/dist/execution/code-runtime/worker.d.ts +22 -0
  44. package/dist/execution/code-runtime/worker.d.ts.map +1 -1
  45. package/dist/execution/code-runtime/worker.js +148 -111
  46. package/dist/execution/code-runtime/worker.js.map +1 -1
  47. package/dist/manager/agent/lifecycle.d.ts +12 -0
  48. package/dist/manager/agent/lifecycle.d.ts.map +1 -1
  49. package/dist/manager/agent/lifecycle.js +316 -46
  50. package/dist/manager/agent/lifecycle.js.map +1 -1
  51. package/dist/manager/run/persistence.d.ts +2 -0
  52. package/dist/manager/run/persistence.d.ts.map +1 -1
  53. package/dist/manager/run/persistence.js +6 -0
  54. package/dist/manager/run/persistence.js.map +1 -1
  55. package/dist/prompt/coding-agent-doctrine.d.ts +2 -2
  56. package/dist/prompt/coding-agent-doctrine.d.ts.map +1 -1
  57. package/dist/prompt/coding-agent-doctrine.js +11 -5
  58. package/dist/prompt/coding-agent-doctrine.js.map +1 -1
  59. package/dist/provider/capabilities.d.ts +5 -1
  60. package/dist/provider/capabilities.d.ts.map +1 -1
  61. package/dist/provider/capabilities.js +24 -0
  62. package/dist/provider/capabilities.js.map +1 -1
  63. package/dist/provider/fallback.d.ts.map +1 -1
  64. package/dist/provider/fallback.js +6 -2
  65. package/dist/provider/fallback.js.map +1 -1
  66. package/dist/public-runtime.d.ts +4 -1
  67. package/dist/public-runtime.d.ts.map +1 -1
  68. package/dist/public-runtime.js +3 -1
  69. package/dist/public-runtime.js.map +1 -1
  70. package/dist/public-tools.d.ts +2 -1
  71. package/dist/public-tools.d.ts.map +1 -1
  72. package/dist/public-tools.js +2 -1
  73. package/dist/public-tools.js.map +1 -1
  74. package/dist/public-types.d.ts +2 -0
  75. package/dist/public-types.d.ts.map +1 -1
  76. package/dist/registry/tool/execute.d.ts +3 -0
  77. package/dist/registry/tool/execute.d.ts.map +1 -1
  78. package/dist/registry/tool/execute.js +11 -80
  79. package/dist/registry/tool/execute.js.map +1 -1
  80. package/dist/run/command-gate.d.ts.map +1 -1
  81. package/dist/run/command-gate.js +65 -12
  82. package/dist/run/command-gate.js.map +1 -1
  83. package/dist/run/index.d.ts +2 -0
  84. package/dist/run/index.d.ts.map +1 -1
  85. package/dist/run/index.js +1 -0
  86. package/dist/run/index.js.map +1 -1
  87. package/dist/run/memory-promoter.d.ts +3 -35
  88. package/dist/run/memory-promoter.d.ts.map +1 -1
  89. package/dist/run/memory-promoter.js +32 -40
  90. package/dist/run/memory-promoter.js.map +1 -1
  91. package/dist/run/memory-recall.d.ts +25 -0
  92. package/dist/run/memory-recall.d.ts.map +1 -0
  93. package/dist/run/memory-recall.js +228 -0
  94. package/dist/run/memory-recall.js.map +1 -0
  95. package/dist/run/reporter.d.ts.map +1 -1
  96. package/dist/run/reporter.js +2 -0
  97. package/dist/run/reporter.js.map +1 -1
  98. package/dist/run/token-budget.d.ts +12 -4
  99. package/dist/run/token-budget.d.ts.map +1 -1
  100. package/dist/run/token-budget.js +49 -14
  101. package/dist/run/token-budget.js.map +1 -1
  102. package/dist/run/workspace-fingerprint.d.ts +10 -3
  103. package/dist/run/workspace-fingerprint.d.ts.map +1 -1
  104. package/dist/run/workspace-fingerprint.js +17 -8
  105. package/dist/run/workspace-fingerprint.js.map +1 -1
  106. package/dist/runtime/query/checkpoint.d.ts +14 -0
  107. package/dist/runtime/query/checkpoint.d.ts.map +1 -1
  108. package/dist/runtime/query/checkpoint.js +82 -1
  109. package/dist/runtime/query/checkpoint.js.map +1 -1
  110. package/dist/runtime/query/executor.d.ts +8 -3
  111. package/dist/runtime/query/executor.d.ts.map +1 -1
  112. package/dist/runtime/query/executor.js +94 -30
  113. package/dist/runtime/query/executor.js.map +1 -1
  114. package/dist/runtime/query/index.d.ts +7 -8
  115. package/dist/runtime/query/index.d.ts.map +1 -1
  116. package/dist/runtime/query/index.js +55 -7
  117. package/dist/runtime/query/index.js.map +1 -1
  118. package/dist/runtime/query/iteration/index.d.ts +12 -0
  119. package/dist/runtime/query/iteration/index.d.ts.map +1 -1
  120. package/dist/runtime/query/iteration/index.js +348 -38
  121. package/dist/runtime/query/iteration/index.js.map +1 -1
  122. package/dist/runtime/query/iteration/native-output.d.ts +10 -0
  123. package/dist/runtime/query/iteration/native-output.d.ts.map +1 -0
  124. package/dist/runtime/query/iteration/native-output.js +32 -0
  125. package/dist/runtime/query/iteration/native-output.js.map +1 -0
  126. package/dist/runtime/query/iteration/phases/advisory.d.ts.map +1 -1
  127. package/dist/runtime/query/iteration/phases/advisory.js +18 -13
  128. package/dist/runtime/query/iteration/phases/advisory.js.map +1 -1
  129. package/dist/runtime/query/iteration/phases/compaction.d.ts +2 -0
  130. package/dist/runtime/query/iteration/phases/compaction.d.ts.map +1 -1
  131. package/dist/runtime/query/iteration/phases/compaction.js +32 -11
  132. package/dist/runtime/query/iteration/phases/compaction.js.map +1 -1
  133. package/dist/runtime/query/iteration/phases/context.d.ts +9 -0
  134. package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
  135. package/dist/runtime/query/iteration/phases/context.js.map +1 -1
  136. package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
  137. package/dist/runtime/query/iteration/phases/tool-review.js +1 -1
  138. package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
  139. package/dist/runtime/query/iteration/phases/working-memory.d.ts +1 -1
  140. package/dist/runtime/query/iteration/phases/working-memory.d.ts.map +1 -1
  141. package/dist/runtime/query/iteration/phases/working-memory.js +23 -6
  142. package/dist/runtime/query/iteration/phases/working-memory.js.map +1 -1
  143. package/dist/runtime/query/iteration/stream-turn.d.ts.map +1 -1
  144. package/dist/runtime/query/iteration/stream-turn.js +12 -0
  145. package/dist/runtime/query/iteration/stream-turn.js.map +1 -1
  146. package/dist/runtime/query/observation-context.d.ts +10 -0
  147. package/dist/runtime/query/observation-context.d.ts.map +1 -0
  148. package/dist/runtime/query/observation-context.js +84 -0
  149. package/dist/runtime/query/observation-context.js.map +1 -0
  150. package/dist/runtime/query/request-context.d.ts +30 -0
  151. package/dist/runtime/query/request-context.d.ts.map +1 -0
  152. package/dist/runtime/query/request-context.js +76 -0
  153. package/dist/runtime/query/request-context.js.map +1 -0
  154. package/dist/runtime/query/request-rich-content.d.ts.map +1 -1
  155. package/dist/runtime/query/request-rich-content.js +6 -3
  156. package/dist/runtime/query/request-rich-content.js.map +1 -1
  157. package/dist/runtime/query/review-policy.d.ts +3 -0
  158. package/dist/runtime/query/review-policy.d.ts.map +1 -1
  159. package/dist/runtime/query/review-policy.js +4 -1
  160. package/dist/runtime/query/review-policy.js.map +1 -1
  161. package/dist/runtime/query/steering.d.ts +6 -2
  162. package/dist/runtime/query/steering.d.ts.map +1 -1
  163. package/dist/runtime/query/steering.js +17 -2
  164. package/dist/runtime/query/steering.js.map +1 -1
  165. package/dist/runtime/query/tool-call-budget.d.ts +19 -0
  166. package/dist/runtime/query/tool-call-budget.d.ts.map +1 -0
  167. package/dist/runtime/query/tool-call-budget.js +110 -0
  168. package/dist/runtime/query/tool-call-budget.js.map +1 -0
  169. package/dist/runtime/query/tooling.d.ts +3 -0
  170. package/dist/runtime/query/tooling.d.ts.map +1 -1
  171. package/dist/runtime/query/tooling.js +5 -0
  172. package/dist/runtime/query/tooling.js.map +1 -1
  173. package/dist/sandbox/file-walk-program.d.ts.map +1 -1
  174. package/dist/sandbox/file-walk-program.js +8 -0
  175. package/dist/sandbox/file-walk-program.js.map +1 -1
  176. package/dist/sandbox/file-walk.d.ts.map +1 -1
  177. package/dist/sandbox/file-walk.js +9 -0
  178. package/dist/sandbox/file-walk.js.map +1 -1
  179. package/dist/scheduler/completion-inbox.d.ts.map +1 -1
  180. package/dist/scheduler/completion-inbox.js +3 -0
  181. package/dist/scheduler/completion-inbox.js.map +1 -1
  182. package/dist/scheduler/local.d.ts.map +1 -1
  183. package/dist/scheduler/local.js +1 -0
  184. package/dist/scheduler/local.js.map +1 -1
  185. package/dist/session/handoff/capacity.d.ts +2 -2
  186. package/dist/session/handoff/capacity.d.ts.map +1 -1
  187. package/dist/session/handoff/capacity.js +3 -2
  188. package/dist/session/handoff/capacity.js.map +1 -1
  189. package/dist/store/memory/disk.d.ts +6 -2
  190. package/dist/store/memory/disk.d.ts.map +1 -1
  191. package/dist/store/memory/disk.js +42 -25
  192. package/dist/store/memory/disk.js.map +1 -1
  193. package/dist/store/memory/index.d.ts +4 -0
  194. package/dist/store/memory/index.d.ts.map +1 -1
  195. package/dist/store/memory/index.js +55 -19
  196. package/dist/store/memory/index.js.map +1 -1
  197. package/dist/store/memory/memory.d.ts +3 -2
  198. package/dist/store/memory/memory.d.ts.map +1 -1
  199. package/dist/store/memory/memory.js +11 -2
  200. package/dist/store/memory/memory.js.map +1 -1
  201. package/dist/store/memory/operation-lock.d.ts +11 -0
  202. package/dist/store/memory/operation-lock.d.ts.map +1 -0
  203. package/dist/store/memory/operation-lock.js +94 -0
  204. package/dist/store/memory/operation-lock.js.map +1 -0
  205. package/dist/store/run/token-budget-disk.js +3 -0
  206. package/dist/store/run/token-budget-disk.js.map +1 -1
  207. package/dist/tools/builtins/computer-use.d.ts.map +1 -1
  208. package/dist/tools/builtins/computer-use.js +60 -10
  209. package/dist/tools/builtins/computer-use.js.map +1 -1
  210. package/dist/tools/builtins/edit.d.ts.map +1 -1
  211. package/dist/tools/builtins/edit.js +12 -26
  212. package/dist/tools/builtins/edit.js.map +1 -1
  213. package/dist/tools/builtins/file-write-result.d.ts +4 -0
  214. package/dist/tools/builtins/file-write-result.d.ts.map +1 -0
  215. package/dist/tools/builtins/file-write-result.js +72 -0
  216. package/dist/tools/builtins/file-write-result.js.map +1 -0
  217. package/dist/tools/builtins/glob.d.ts.map +1 -1
  218. package/dist/tools/builtins/glob.js +8 -1
  219. package/dist/tools/builtins/glob.js.map +1 -1
  220. package/dist/tools/builtins/grep.d.ts.map +1 -1
  221. package/dist/tools/builtins/grep.js +10 -0
  222. package/dist/tools/builtins/grep.js.map +1 -1
  223. package/dist/tools/builtins/job.d.ts.map +1 -1
  224. package/dist/tools/builtins/job.js +6 -0
  225. package/dist/tools/builtins/job.js.map +1 -1
  226. package/dist/tools/builtins/read-file.d.ts.map +1 -1
  227. package/dist/tools/builtins/read-file.js +10 -0
  228. package/dist/tools/builtins/read-file.js.map +1 -1
  229. package/dist/tools/builtins/run-code.d.ts +6 -0
  230. package/dist/tools/builtins/run-code.d.ts.map +1 -1
  231. package/dist/tools/builtins/run-code.js +15 -4
  232. package/dist/tools/builtins/run-code.js.map +1 -1
  233. package/dist/tools/builtins/search-tools.d.ts.map +1 -1
  234. package/dist/tools/builtins/search-tools.js +14 -2
  235. package/dist/tools/builtins/search-tools.js.map +1 -1
  236. package/dist/tools/builtins/write-file.d.ts.map +1 -1
  237. package/dist/tools/builtins/write-file.js +30 -44
  238. package/dist/tools/builtins/write-file.js.map +1 -1
  239. package/dist/tools/defineTool.d.ts +2 -0
  240. package/dist/tools/defineTool.d.ts.map +1 -1
  241. package/dist/tools/defineTool.js +3 -0
  242. package/dist/tools/defineTool.js.map +1 -1
  243. package/dist/tools/file-read-tracker.d.ts +4 -0
  244. package/dist/tools/file-read-tracker.d.ts.map +1 -0
  245. package/dist/tools/file-read-tracker.js +16 -0
  246. package/dist/tools/file-read-tracker.js.map +1 -0
  247. package/dist/tools/memory/delete.d.ts +4 -0
  248. package/dist/tools/memory/delete.d.ts.map +1 -0
  249. package/dist/tools/memory/delete.js +26 -0
  250. package/dist/tools/memory/delete.js.map +1 -0
  251. package/dist/tools/memory/index.d.ts +2 -0
  252. package/dist/tools/memory/index.d.ts.map +1 -1
  253. package/dist/tools/memory/index.js +6 -0
  254. package/dist/tools/memory/index.js.map +1 -1
  255. package/dist/tools/memory/save.d.ts.map +1 -1
  256. package/dist/tools/memory/save.js +3 -2
  257. package/dist/tools/memory/save.js.map +1 -1
  258. package/dist/tools/memory/search.d.ts.map +1 -1
  259. package/dist/tools/memory/search.js +12 -5
  260. package/dist/tools/memory/search.js.map +1 -1
  261. package/dist/tools/memory/update.d.ts +4 -0
  262. package/dist/tools/memory/update.d.ts.map +1 -0
  263. package/dist/tools/memory/update.js +47 -0
  264. package/dist/tools/memory/update.js.map +1 -0
  265. package/dist/tools/task/list.js +2 -2
  266. package/dist/tools/task/list.js.map +1 -1
  267. package/dist/types/agent/scheduler.d.ts +5 -0
  268. package/dist/types/agent/scheduler.d.ts.map +1 -1
  269. package/dist/types/agent/task.d.ts +10 -0
  270. package/dist/types/agent/task.d.ts.map +1 -1
  271. package/dist/types/computer-use/index.d.ts +6 -0
  272. package/dist/types/computer-use/index.d.ts.map +1 -1
  273. package/dist/types/computer-use/index.js.map +1 -1
  274. package/dist/types/errors/catalog.js +1 -1
  275. package/dist/types/errors/catalog.js.map +1 -1
  276. package/dist/types/hitl/index.d.ts +11 -1
  277. package/dist/types/hitl/index.d.ts.map +1 -1
  278. package/dist/types/hitl/index.js.map +1 -1
  279. package/dist/types/memory/index.d.ts +14 -1
  280. package/dist/types/memory/index.d.ts.map +1 -1
  281. package/dist/types/plugin/index.d.ts +7 -0
  282. package/dist/types/plugin/index.d.ts.map +1 -1
  283. package/dist/types/plugin/index.js.map +1 -1
  284. package/dist/types/project/entity.d.ts +1 -0
  285. package/dist/types/project/entity.d.ts.map +1 -1
  286. package/dist/types/provider/chat.d.ts +4 -0
  287. package/dist/types/provider/chat.d.ts.map +1 -1
  288. package/dist/types/provider/config.d.ts +4 -0
  289. package/dist/types/provider/config.d.ts.map +1 -1
  290. package/dist/types/provider/model.d.ts +4 -0
  291. package/dist/types/provider/model.d.ts.map +1 -1
  292. package/dist/types/provider/stream.d.ts +6 -0
  293. package/dist/types/provider/stream.d.ts.map +1 -1
  294. package/dist/types/run/answer-review.d.ts +2 -0
  295. package/dist/types/run/answer-review.d.ts.map +1 -1
  296. package/dist/types/run/config.d.ts +2 -0
  297. package/dist/types/run/config.d.ts.map +1 -1
  298. package/dist/types/run/events.d.ts +19 -0
  299. package/dist/types/run/events.d.ts.map +1 -1
  300. package/dist/types/run/events.js.map +1 -1
  301. package/dist/types/run/prepare-step.d.ts +19 -1
  302. package/dist/types/run/prepare-step.d.ts.map +1 -1
  303. package/dist/types/sandbox/index.d.ts +1 -0
  304. package/dist/types/sandbox/index.d.ts.map +1 -1
  305. package/dist/types/sandbox/index.js.map +1 -1
  306. package/dist/types/structured-output/index.d.ts +8 -2
  307. package/dist/types/structured-output/index.d.ts.map +1 -1
  308. package/dist/types/tool/index.d.ts +15 -0
  309. package/dist/types/tool/index.d.ts.map +1 -1
  310. package/dist/types/tool/index.js.map +1 -1
  311. package/dist/types/tool/presentation.d.ts +4 -0
  312. package/dist/types/tool/presentation.d.ts.map +1 -1
  313. package/dist/utils/json-snapshot.d.ts +3 -0
  314. package/dist/utils/json-snapshot.d.ts.map +1 -0
  315. package/dist/utils/json-snapshot.js +79 -0
  316. package/dist/utils/json-snapshot.js.map +1 -0
  317. package/package.json +4 -2
  318. package/src/bridge/a2a/mapper.ts +4 -0
  319. package/src/bridge/sse/mapper.ts +16 -1
  320. package/src/compaction/extractor.ts +21 -8
  321. package/src/compaction/manager.ts +11 -1
  322. package/src/compaction/verifier.ts +80 -18
  323. package/src/config/runtime.ts +2 -0
  324. package/src/contracts/api.ts +1 -0
  325. package/src/eval/harness-verification.ts +270 -0
  326. package/src/eval/index.ts +10 -0
  327. package/src/execution/code-runtime/json-value.ts +82 -0
  328. package/src/execution/code-runtime/worker-program.ts +239 -0
  329. package/src/execution/code-runtime/worker.ts +164 -111
  330. package/src/manager/agent/lifecycle.ts +352 -54
  331. package/src/manager/run/persistence.ts +7 -0
  332. package/src/prompt/coding-agent-doctrine.ts +11 -5
  333. package/src/provider/capabilities.ts +41 -1
  334. package/src/provider/fallback.ts +9 -2
  335. package/src/public-runtime.ts +6 -0
  336. package/src/public-tools.ts +7 -1
  337. package/src/public-types.ts +7 -0
  338. package/src/registry/tool/execute.ts +17 -79
  339. package/src/run/command-gate.ts +61 -13
  340. package/src/run/index.ts +2 -0
  341. package/src/run/memory-promoter.ts +32 -40
  342. package/src/run/memory-recall.ts +254 -0
  343. package/src/run/reporter.ts +2 -0
  344. package/src/run/token-budget.ts +55 -14
  345. package/src/run/workspace-fingerprint.ts +17 -8
  346. package/src/runtime/query/checkpoint.ts +96 -2
  347. package/src/runtime/query/executor.ts +100 -29
  348. package/src/runtime/query/index.ts +76 -16
  349. package/src/runtime/query/iteration/index.ts +405 -46
  350. package/src/runtime/query/iteration/native-output.ts +35 -0
  351. package/src/runtime/query/iteration/phases/advisory.ts +21 -11
  352. package/src/runtime/query/iteration/phases/compaction.ts +36 -14
  353. package/src/runtime/query/iteration/phases/context.ts +9 -0
  354. package/src/runtime/query/iteration/phases/tool-review.ts +5 -1
  355. package/src/runtime/query/iteration/phases/working-memory.ts +23 -5
  356. package/src/runtime/query/iteration/stream-turn.ts +15 -0
  357. package/src/runtime/query/observation-context.ts +86 -0
  358. package/src/runtime/query/request-context.ts +103 -0
  359. package/src/runtime/query/request-rich-content.ts +8 -3
  360. package/src/runtime/query/review-policy.ts +7 -1
  361. package/src/runtime/query/steering.ts +19 -2
  362. package/src/runtime/query/tool-call-budget.ts +115 -0
  363. package/src/runtime/query/tooling.ts +8 -0
  364. package/src/sandbox/file-walk-program.ts +8 -0
  365. package/src/sandbox/file-walk.ts +9 -0
  366. package/src/scheduler/completion-inbox.ts +3 -0
  367. package/src/scheduler/local.ts +1 -0
  368. package/src/session/handoff/capacity.ts +7 -3
  369. package/src/store/memory/disk.ts +52 -30
  370. package/src/store/memory/index.ts +75 -27
  371. package/src/store/memory/memory.ts +18 -6
  372. package/src/store/memory/operation-lock.ts +99 -0
  373. package/src/store/run/token-budget-disk.ts +3 -0
  374. package/src/tools/builtins/computer-use.ts +61 -7
  375. package/src/tools/builtins/edit.ts +12 -27
  376. package/src/tools/builtins/file-write-result.ts +84 -0
  377. package/src/tools/builtins/glob.ts +7 -1
  378. package/src/tools/builtins/grep.ts +10 -0
  379. package/src/tools/builtins/job.ts +8 -0
  380. package/src/tools/builtins/read-file.ts +10 -0
  381. package/src/tools/builtins/run-code.ts +24 -5
  382. package/src/tools/builtins/search-tools.ts +18 -3
  383. package/src/tools/builtins/write-file.ts +39 -44
  384. package/src/tools/defineTool.ts +5 -0
  385. package/src/tools/file-read-tracker.ts +16 -0
  386. package/src/tools/memory/delete.ts +29 -0
  387. package/src/tools/memory/index.ts +6 -0
  388. package/src/tools/memory/save.ts +4 -2
  389. package/src/tools/memory/search.ts +12 -5
  390. package/src/tools/memory/update.ts +50 -0
  391. package/src/tools/task/list.ts +2 -2
  392. package/src/types/agent/scheduler.ts +6 -0
  393. package/src/types/agent/task.ts +13 -0
  394. package/src/types/computer-use/index.ts +6 -0
  395. package/src/types/errors/catalog.ts +1 -1
  396. package/src/types/hitl/index.ts +11 -1
  397. package/src/types/memory/index.ts +16 -1
  398. package/src/types/plugin/index.ts +10 -0
  399. package/src/types/project/entity.ts +1 -0
  400. package/src/types/provider/chat.ts +2 -0
  401. package/src/types/provider/config.ts +4 -0
  402. package/src/types/provider/model.ts +4 -0
  403. package/src/types/provider/stream.ts +7 -0
  404. package/src/types/run/answer-review.ts +2 -0
  405. package/src/types/run/config.ts +2 -0
  406. package/src/types/run/events.ts +20 -0
  407. package/src/types/run/prepare-step.ts +19 -1
  408. package/src/types/sandbox/index.ts +1 -0
  409. package/src/types/structured-output/index.ts +15 -2
  410. package/src/types/tool/index.ts +16 -0
  411. package/src/types/tool/presentation.ts +4 -0
  412. package/src/utils/json-snapshot.ts +76 -0
@@ -11,8 +11,8 @@ import { probe as defaultProbeRegistry } from '../../probe/registry.js'
11
11
  import type { ProbeEnforcement } from '../../probe/registry.js'
12
12
  import { renderToolSchema } from '../../registry/tool/schema.js'
13
13
  import type { ActivityStore } from '../../store/activity/memory.js'
14
- import { fingerprintContent } from '../../tools/builtins/content-fingerprint.js'
15
14
  import { SKILL_TOOL_NAME } from '../../tools/builtins/skill.js'
15
+ import { createFileReadTracker } from '../../tools/file-read-tracker.js'
16
16
  import type { RunId, ToolUseId } from '../../types/ids/index.js'
17
17
  import type { InvocationState } from '../../types/invocation/index.js'
18
18
  import {
@@ -50,6 +50,7 @@ import type { Logger } from '../../utils/logger.js'
50
50
  import { compressShellOutput } from '../../utils/shell-compress.js'
51
51
  import { type BackgroundJobRegistry, type JobProcess, bindOwner } from '../jobs/registry.js'
52
52
  import type { ToolResultObservation } from './project-instructions.js'
53
+ import { ToolCallBudget, assertMaxToolCalls } from './tool-call-budget.js'
53
54
  import {
54
55
  DEFAULT_MAX_TOOL_OUTPUT_CHARS,
55
56
  type ToolOutputBudgetResult,
@@ -289,6 +290,7 @@ function parseArguments(raw: string): unknown {
289
290
  }
290
291
 
291
292
  export interface ToolExecutorConfig {
293
+ fileReadTracker?: FileReadTracker
292
294
  tools: ToolRegistryContract
293
295
  runId: RunId
294
296
  workingDirectory: string
@@ -356,6 +358,10 @@ export interface ToolExecutorConfig {
356
358
  toolRetryBackoff?: Partial<BackoffPolicy>
357
359
  /** Max concurrently-executing concurrency-safe tools. */
358
360
  maxToolConcurrency?: number
361
+ /** Per-run cumulative attempt admission limit; unset is unlimited. */
362
+ maxToolCalls?: number
363
+ /** Complete strict event replay for restoring a configured call budget. */
364
+ readToolCallBudgetEvents?: () => Promise<readonly RunEvent[]>
359
365
 
360
366
  /**
361
367
  * Builds the durable-pause seam handed to one tool call.
@@ -492,23 +498,11 @@ export class ToolExecutor {
492
498
  private workingStateManager?: WorkingStateManager
493
499
  private probes: ProbeEnforcement
494
500
  private parentSpan?: Span
501
+ private readonly toolCallBudget?: ToolCallBudget
495
502
  private readonly preparedBatches = new WeakSet<PreparedToolBatch>()
496
503
  /** Set per turn by the orchestrator; see {@link setStepAllowedTools}. */
497
504
  private stepAllowedTools?: readonly string[]
498
- private readonly readPaths: Set<string> = new Set()
499
- private readonly readFingerprints: Map<string, string> = new Map()
500
- private readonly fileReadTracker: FileReadTracker = {
501
- recordRead: (key: string, content?: string) => {
502
- this.readPaths.add(key)
503
- // Only when the reader had the body. A tool that records a read
504
- // without one leaves the previous fingerprint alone rather than
505
- // clearing it, so a later write is still checked against the last
506
- // body anyone actually saw.
507
- if (content !== undefined) this.readFingerprints.set(key, fingerprintContent(content))
508
- },
509
- hasRead: (key: string) => this.readPaths.has(key),
510
- fingerprint: (key: string) => this.readFingerprints.get(key),
511
- }
505
+ private readonly fileReadTracker: FileReadTracker
512
506
 
513
507
  constructor(
514
508
  config: ToolExecutorConfig,
@@ -517,6 +511,16 @@ export class ToolExecutor {
517
511
  log: Logger,
518
512
  probes: ProbeEnforcement = defaultProbeRegistry,
519
513
  ) {
514
+ assertMaxToolCalls(config.maxToolCalls)
515
+ if (config.maxToolCalls !== undefined) {
516
+ this.toolCallBudget = new ToolCallBudget(
517
+ config.maxToolCalls,
518
+ config.runId,
519
+ emitEvent,
520
+ config.readToolCallBudgetEvents,
521
+ )
522
+ }
523
+ this.fileReadTracker = config.fileReadTracker ?? createFileReadTracker()
520
524
  this.config = config
521
525
  this.activityStore = activityStore
522
526
  this.emitEvent = emitEvent
@@ -730,6 +734,18 @@ export class ToolExecutor {
730
734
  if (owned && !this.preparedBatches.has(owned)) {
731
735
  throw new Error('Prepared tool batch is not owned by this executor.')
732
736
  }
737
+ const refusal = this.toolCallBudget
738
+ ? await this.toolCallBudget.admit(
739
+ toolCalls.filter((call) => prior?.get(call.id) === undefined).length,
740
+ 'batch',
741
+ this.config.abortSignal,
742
+ )
743
+ : undefined
744
+ if (refusal) {
745
+ const refused = new Map(denials)
746
+ for (const call of toolCalls) if (!refused.has(call.id)) refused.set(call.id, refusal)
747
+ return await this.runBatch(toolCalls, refused, prior, owned)
748
+ }
733
749
  return await this.runBatch(toolCalls, denials, prior, owned)
734
750
  } finally {
735
751
  // Cleared so a later single execution outside a batch resolves
@@ -779,6 +795,24 @@ export class ToolExecutor {
779
795
  const results: ToolCallOutcome[] = new Array(toolCalls.length)
780
796
  const parallel: Promise<void>[] = []
781
797
  let serial: Promise<void> = Promise.resolve()
798
+ let barrier: Promise<void> | undefined
799
+ const schedule = (run: () => Promise<void>, safe: boolean, isBarrier: boolean): void => {
800
+ if (isBarrier) {
801
+ // Settle the entire preceding segment, even when host plumbing
802
+ // rejects. A rejected host operation prevents dependent execution.
803
+ barrier = Promise.allSettled([...parallel, serial]).then(async (settled) => {
804
+ const failed = settled.find((entry) => entry.status === 'rejected')
805
+ if (failed?.status === 'rejected') throw failed.reason
806
+ await run()
807
+ })
808
+ parallel.length = 0
809
+ serial = barrier
810
+ } else if (safe) {
811
+ parallel.push(barrier ? barrier.then(run) : run())
812
+ } else {
813
+ serial = serial.then(run)
814
+ }
815
+ }
782
816
  // Bounded fan-out. A model emitting fifty parallel reads used to open
783
817
  // fifty file handles and fifty activity records simultaneously; the
784
818
  // gate keeps that at a working-set size while preserving completion
@@ -786,6 +820,8 @@ export class ToolExecutor {
786
820
  const gate = new Semaphore(this.config.maxToolConcurrency ?? DEFAULT_TOOL_CONCURRENCY)
787
821
  toolCalls.forEach((toolCall, i) => {
788
822
  const preparedCall = preparedBatch?.calls.get(toolCall.id)
823
+ const tool = this.config.tools.get(preparedCall?.toolName ?? toolCall.function.name)
824
+ const isBarrier = tool?.executionBarrier === true
789
825
  const recovered = prior?.get(toolCall.id)
790
826
  if (recovered !== undefined) {
791
827
  // This call already ran, in a process that died before the
@@ -798,19 +834,21 @@ export class ToolExecutor {
798
834
  output: recovered.result,
799
835
  isError: recovered.isError,
800
836
  }
837
+ if (isBarrier) schedule(async () => {}, true, true)
801
838
  return
802
839
  }
803
840
 
804
841
  const denialReason = denials?.get(toolCall.id)
805
842
  if (denialReason !== undefined) {
806
843
  // Denied calls never touch the tool; they still get a result
807
- // message so the assistant turn stays fully answered. Run them
808
- // on the parallel branch — they perform no side effects, so
809
- // serialization would only add latency.
810
- parallel.push(
811
- this.recordDenial(toolCall, denialReason, preparedCall).then((r) => {
812
- results[i] = r
813
- }),
844
+ // message so the assistant turn stays fully answered. They can
845
+ // overlap other calls within a segment, respecting its barriers.
846
+ schedule(
847
+ async () => {
848
+ results[i] = await this.recordDenial(toolCall, denialReason, preparedCall)
849
+ },
850
+ true,
851
+ isBarrier,
814
852
  )
815
853
  return
816
854
  }
@@ -868,13 +906,8 @@ export class ToolExecutor {
868
906
  } catch {
869
907
  // non-JSON args → treat as unsafe (serialize), the conservative path
870
908
  }
871
- const preparedToolName = preparedCall?.toolName
872
- const safe =
873
- this.config.tools
874
- .get(preparedToolName ?? toolCall.function.name)
875
- ?.isConcurrencySafe?.(input) === true
876
- if (safe) parallel.push(gated())
877
- else serial = serial.then(run)
909
+ const safe = tool?.isConcurrencySafe?.(input) === true
910
+ schedule(safe ? gated : run, safe, isBarrier)
878
911
  })
879
912
  await Promise.all([...parallel, serial])
880
913
 
@@ -942,8 +975,14 @@ export class ToolExecutor {
942
975
  // retained closure must be observationally inert after its invocation
943
976
  // ends, not merely unable to finish the registry call it already started.
944
977
  signal.throwIfAborted()
978
+ // Preparation detaches input synchronously before its first await.
979
+ // Admission must not add an earlier yield where the caller can mutate it.
945
980
  const preparedCall = await this.prepareNestedCall(name, input, signal)
946
981
  signal.throwIfAborted()
982
+ if (this.toolCallBudget) {
983
+ const refusal = await this.toolCallBudget.admit(1, 'nested', signal)
984
+ if (refusal) return { success: false, output: '', error: refusal }
985
+ }
947
986
  const preparedInput = preparedCall.input
948
987
 
949
988
  const parent = context.toolUseId
@@ -1161,6 +1200,7 @@ export class ToolExecutor {
1161
1200
  toolUseId: nestedId,
1162
1201
  toolName: name,
1163
1202
  result: budgeted.output,
1203
+ ...(!budgeted.truncated ? this.resultPresentation(name, preparedInput, result) : {}),
1164
1204
  isError: !result.success,
1165
1205
  durationMs: Date.now() - startedAt,
1166
1206
  outputLength: budgeted.originalLength,
@@ -1180,6 +1220,21 @@ export class ToolExecutor {
1180
1220
  return visibleResult
1181
1221
  }
1182
1222
 
1223
+ private resultPresentation(name: string, input: unknown, result: ToolResult) {
1224
+ if (!result.success) return {}
1225
+ try {
1226
+ const view = this.config.tools.get(name)?.presentResult?.(input, result)
1227
+ if (view?.kind !== 'diff') return {}
1228
+ const serialized = JSON.stringify(view)
1229
+ if (serialized.length > (this.config.maxToolOutputChars ?? DEFAULT_MAX_TOOL_OUTPUT_CHARS))
1230
+ return {}
1231
+ return { presentation: view }
1232
+ } catch {
1233
+ // A presentation hook must not fail an already completed mutation.
1234
+ return {}
1235
+ }
1236
+ }
1237
+
1183
1238
  private buildToolContext(
1184
1239
  recordObservation: (observation: ToolResultObservation) => void = () => {},
1185
1240
  ): ToolContext {
@@ -1550,6 +1605,19 @@ export class ToolExecutor {
1550
1605
  break
1551
1606
  }
1552
1607
 
1608
+ let refusal: string | undefined
1609
+ try {
1610
+ if (this.toolCallBudget)
1611
+ refusal = await this.toolCallBudget.admit(1, 'retry', this.config.abortSignal)
1612
+ } catch (error) {
1613
+ if (this.config.abortSignal.aborted) break
1614
+ throw error
1615
+ }
1616
+ if (refusal) {
1617
+ result = { success: false, output: '', error: refusal }
1618
+ post = { override: null, retry: false }
1619
+ break
1620
+ }
1553
1621
  result = await this.runOnce(toolName, input, toolContext, prepared)
1554
1622
  post = await this.runPostToolHook(toolName, input, result)
1555
1623
  }
@@ -1658,6 +1726,9 @@ export class ToolExecutor {
1658
1726
  toolUseId: toolCall.id,
1659
1727
  toolName,
1660
1728
  result: output,
1729
+ ...(!postOverride && !budgeted.truncated && rawOutput === output
1730
+ ? this.resultPresentation(toolName, input, result)
1731
+ : {}),
1661
1732
  isError: effectiveIsError,
1662
1733
  durationMs,
1663
1734
  // Pre-truncation size, so a host can show "returned 2.1 MB" even
@@ -149,13 +149,16 @@ import {
149
149
  resolveSandboxTeardownTimeoutMs,
150
150
  teardownSandbox,
151
151
  } from './sandbox-lifecycle.js'
152
- import { SteeringBinding, type SteeringChannel } from './steering.js'
152
+ import { SteeringBinding, type SteeringChannel, isOperatorUserMessage } from './steering.js'
153
153
  import { resolveQueryBudget } from './token-budget.js'
154
+ import { assertMaxToolCalls } from './tool-call-budget.js'
154
155
  import { ToolGrantSet } from './tool-grants.js'
155
156
  import { createToolPause } from './tool-pause.js'
156
157
  import { ToolingBootstrap } from './tooling.js'
157
158
 
158
159
  export interface QueryParams {
160
+ /** Share observations across turns of one conversation and filesystem; otherwise run-local. */
161
+ fileReadTracker?: import('../../types/tool/index.js').FileReadTracker
159
162
  /** One account shared with the task scheduler and descendant runs. */
160
163
  budget?: TokenBudget
161
164
  /** Canonical tree ledger; defaults to disk beside the root run. */
@@ -349,6 +352,8 @@ export interface QueryParams {
349
352
 
350
353
  /** Max concurrently-executing concurrency-safe tools in one batch. */
351
354
  maxToolConcurrency?: number
355
+ /** Per-run cumulative tool attempt limit, including nested calls and retries. Unset is unlimited. Re-supply on resume; durable reservations are never refunded. */
356
+ maxToolCalls?: number
352
357
 
353
358
  /**
354
359
  * Model-visible size cap for a single tool result. Over-budget output is
@@ -450,14 +455,9 @@ export interface QueryParams {
450
455
  beforeStep?: BeforeStep
451
456
 
452
457
  /**
453
- * Force the run to finish by calling a schema-validated tool, and land
454
- * the parsed value on `Run.structuredOutput`.
455
- *
456
- * Both leaf pieces already shipped and neither was reachable:
457
- * `createStructuredOutputTool` is excluded from the default builtin set,
458
- * and `StructuredOutputConfig` had no field on QueryParams at all. A host
459
- * needing a typed result had to register the tool by hand and hope —
460
- * nothing forced the call, and nothing stopped the loop when it came.
458
+ * Produce a locally validated structured result. Defaults to an output tool;
459
+ * mode:'native' requests JSON Schema from an explicitly capable driver.
460
+ * Host review and bounded corrections apply before publication.
461
461
  */
462
462
  structuredOutput?: StructuredOutputConfig
463
463
 
@@ -1027,6 +1027,19 @@ function withoutOwnedResumeTurn(
1027
1027
  }
1028
1028
 
1029
1029
  export async function* query(params: QueryParams): AsyncGenerator<RunEvent, Run> {
1030
+ assertMaxToolCalls(params.maxToolCalls)
1031
+ // Required types do not protect JavaScript callers. Reject missing scope
1032
+ // before opening a budget or persisting a run without its owning identity.
1033
+ const missingFields = (['sessionId', 'topicId', 'projectId', 'tenantId'] as const).filter(
1034
+ (field) => !params[field],
1035
+ )
1036
+ if (missingFields.length > 0) {
1037
+ throw new NamzuError({
1038
+ code: 'invalid_config',
1039
+ message: `query requires sessionId, topicId, projectId, and tenantId; missing: ${missingFields.join(', ')}.`,
1040
+ details: { missingFields },
1041
+ })
1042
+ }
1030
1043
  const selectedResumeState = selectedResumeStates.get(params)
1031
1044
  selectedResumeStates.delete(params)
1032
1045
  // Resolved at the DOOR, before a run id exists or a logger is built.
@@ -1154,6 +1167,8 @@ export async function* query(params: QueryParams): AsyncGenerator<RunEvent, Run>
1154
1167
  runConfig.timeoutMs,
1155
1168
  log,
1156
1169
  )
1170
+ const modelContextWindows = new Map<string, number | undefined>()
1171
+ if (runConfig.model) modelContextWindows.set(runConfig.model, providerContextWindow)
1157
1172
 
1158
1173
  // The mode this conversation was left in, when the run config names none.
1159
1174
  // Read once, before the loop exists, for the same reason the context
@@ -1556,7 +1571,11 @@ export async function* query(params: QueryParams): AsyncGenerator<RunEvent, Run>
1556
1571
  // invalidate the whole prompt cache for the rest of the run — the same
1557
1572
  // reason the forced-final turn keeps its tools array and uses
1558
1573
  // `toolChoice: 'none'` instead of dropping it.
1559
- if (params.structuredOutput && !params.tools.has(STRUCTURED_OUTPUT_TOOL_NAME)) {
1574
+ if (
1575
+ params.structuredOutput &&
1576
+ params.structuredOutput.mode !== 'native' &&
1577
+ !params.tools.has(STRUCTURED_OUTPUT_TOOL_NAME)
1578
+ ) {
1560
1579
  params.tools.register(createStructuredOutputTool(params.structuredOutput.schema))
1561
1580
  }
1562
1581
 
@@ -1714,10 +1733,18 @@ export async function* query(params: QueryParams): AsyncGenerator<RunEvent, Run>
1714
1733
  // registry would answer about whatever the last run configured.
1715
1734
  ...(params.skillRegistry ? { skills: params.skillRegistry } : {}),
1716
1735
  ...(params.web ? { web: params.web } : {}),
1736
+ ...(params.fileReadTracker ? { fileReadTracker: params.fileReadTracker } : {}),
1717
1737
  ...(params.toolTimeoutMs !== undefined ? { toolTimeoutMs: params.toolTimeoutMs } : {}),
1718
1738
  ...(params.toolRetryBackoff !== undefined
1719
1739
  ? { toolRetryBackoff: params.toolRetryBackoff }
1720
1740
  : {}),
1741
+ ...(params.maxToolCalls !== undefined
1742
+ ? {
1743
+ maxToolCalls: params.maxToolCalls,
1744
+ readToolCallBudgetEvents: () =>
1745
+ ctx.runMgr.getRunStore().readEvents({ integrity: 'strict' }),
1746
+ }
1747
+ : {}),
1721
1748
  ...(params.maxToolConcurrency !== undefined
1722
1749
  ? { maxToolConcurrency: params.maxToolConcurrency }
1723
1750
  : {}),
@@ -1970,11 +1997,27 @@ export async function* query(params: QueryParams): AsyncGenerator<RunEvent, Run>
1970
1997
  ...(params.repeatCallAdvisory === false ? {} : { repeatCalls: new RepeatCallTracker() }),
1971
1998
  compactionConfig,
1972
1999
  ...(params.inboundMessages ? { inboundMessages: params.inboundMessages } : {}),
2000
+ ...(params.resumeFromCheckpoint ? { resumedInput: queuedForThisRun } : {}),
1973
2001
  ...(params.waitForInbound ? { waitForInbound: params.waitForInbound } : {}),
1974
2002
  ...(params.projectInstructionContext
1975
2003
  ? { projectInstructionContext: params.projectInstructionContext }
1976
2004
  : {}),
1977
2005
  ...(providerContextWindow !== undefined ? { providerContextWindow } : {}),
2006
+ resolveModelContextWindow: async (model) => {
2007
+ if (!modelContextWindows.has(model)) {
2008
+ modelContextWindows.set(
2009
+ model,
2010
+ await resolveProviderContextWindow(
2011
+ resilientProvider,
2012
+ model,
2013
+ ctx.abortController.signal,
2014
+ runConfig.timeoutMs,
2015
+ log,
2016
+ ),
2017
+ )
2018
+ }
2019
+ return modelContextWindows.get(model)
2020
+ },
1978
2021
  workingStateManager,
1979
2022
  taskRouter: params.taskRouter,
1980
2023
  contextReducer: params.contextReducer,
@@ -2333,7 +2376,6 @@ export async function* query(params: QueryParams): AsyncGenerator<RunEvent, Run>
2333
2376
  }
2334
2377
  } else {
2335
2378
  pushSystemMessages()
2336
- let isFirstUserMessage = true
2337
2379
  for (const msg of initialMessages) {
2338
2380
  if (msg.role === 'system') {
2339
2381
  // A fresh run rebuilds its current static/dynamic prompt above,
@@ -2351,11 +2393,18 @@ export async function* query(params: QueryParams): AsyncGenerator<RunEvent, Run>
2351
2393
  continue
2352
2394
  }
2353
2395
  ctx.runMgr.pushMessage(msg)
2354
-
2355
- if (workingStateManager && msg.role === 'user' && msg.content) {
2356
- extractFromUserMessage(workingStateManager, msg.content, isFirstUserMessage)
2357
- isFirstUserMessage = false
2358
- }
2396
+ }
2397
+ }
2398
+ // Fresh and continuation histories seed the same operator state.
2399
+ // A worker report or project-policy message may have role `user`,
2400
+ // but it must not become the task or an operator requirement.
2401
+ // Resume restores this state and adopts only its newer queue arrivals.
2402
+ if (!params.resumeFromCheckpoint && workingStateManager) {
2403
+ let isFirstUserMessage = true
2404
+ for (const message of initialMessages) {
2405
+ if (!isOperatorUserMessage(message) || !message.content.trim()) continue
2406
+ extractFromUserMessage(workingStateManager, message.content, isFirstUserMessage)
2407
+ isFirstUserMessage = false
2359
2408
  }
2360
2409
  }
2361
2410
 
@@ -2713,6 +2762,16 @@ export async function* query(params: QueryParams): AsyncGenerator<RunEvent, Run>
2713
2762
  ctx.log,
2714
2763
  )
2715
2764
 
2765
+ if (outputVerdict.blocked || outputVerdict.rewritten !== undefined) {
2766
+ ctx.runMgr.clearStructuredOutput()
2767
+ if (
2768
+ params.structuredOutput &&
2769
+ outputVerdict.rewritten !== undefined &&
2770
+ ctx.runMgr.stopReason === 'end_turn'
2771
+ )
2772
+ ctx.runMgr.setStopReason('output_guardrail')
2773
+ }
2774
+
2716
2775
  if (outputVerdict.blocked) {
2717
2776
  await eventTranslator.emitEvent({
2718
2777
  type: 'guardrail_triggered',
@@ -2773,6 +2832,7 @@ export async function* query(params: QueryParams): AsyncGenerator<RunEvent, Run>
2773
2832
  }
2774
2833
  }
2775
2834
  }
2835
+ if (ctx.abortController.signal.aborted) ctx.runMgr.markCancelled()
2776
2836
  yield* resultAssembler.completeRun(rootSpan)
2777
2837
  } catch (err) {
2778
2838
  // A failed run still spent its steps; report them.