@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
@@ -1,11 +1,13 @@
1
1
  import { SpanStatusCode } from '@opentelemetry/api';
2
2
  import { resolveContextWindow } from '../../../compaction/context-window.js';
3
- import { extractFromAssistantMessage } from '../../../compaction/extractor.js';
3
+ import { extractFromAssistantMessage, extractFromUserMessage, } from '../../../compaction/extractor.js';
4
+ import { estimateMessageTokens } from '../../../compaction/token-estimate.js';
4
5
  import { AUTO_CONTINUATION_USER_MESSAGE } from '../../../constants/continuation.js';
5
6
  import { DEFAULT_STRUCTURED_OUTPUT_RETRIES, STRUCTURED_OUTPUT_REPROMPT, } from '../../../constants/tools/index.js';
6
7
  import { renderSkillsSection } from '../../../persona/assembler.js';
7
8
  import { resolveProviderCapabilities } from '../../../provider/capabilities.js';
8
9
  import { collectChatCompletion } from '../../../provider/collect-chat-completion.js';
10
+ import { renderToolSchema } from '../../../registry/tool/schema.js';
9
11
  import { formatCompletionNotification } from '../../../scheduler/completion-inbox.js';
10
12
  import { GENAI, NAMZU, agentIterationSpanName, parentContext, } from '../../../telemetry/attributes.js';
11
13
  import { getTracer } from '../../../telemetry/runtime-accessors.js';
@@ -17,12 +19,15 @@ import { classifyProviderError } from '../../../types/provider/errors.js';
17
19
  import { toErrorMessage } from '../../../utils/error.js';
18
20
  import { stableDigest } from '../../../utils/hash.js';
19
21
  import { generateMessageId } from '../../../utils/id.js';
22
+ import { projectObservationContext } from '../observation-context.js';
20
23
  import { applyLifecycleHookResults } from '../plugin-hooks.js';
24
+ import { diffRequestContext, snapshotRequestContext, } from '../request-context.js';
21
25
  import { DEFAULT_MAX_REQUEST_RICH_CONTENT_BYTES, markProviderRejectedImage, projectRequestRichContent, } from '../request-rich-content.js';
22
- import { formatSteeringNote } from '../steering.js';
26
+ import { formatSteeringNote, isOperatorUserMessage } from '../steering.js';
27
+ import { parseNativeCandidate } from './native-output.js';
23
28
  import { runAdvisoryPhase } from './phases/advisory.js';
24
29
  import { runIterationCheckpoint } from './phases/checkpoint.js';
25
- import { measureContext, relieveOverflow, runCompactionCheck } from './phases/compaction.js';
30
+ import { activeContextWindow, measureContext, relieveOverflow, runCompactionCheck, } from './phases/compaction.js';
26
31
  import { runPlanGate } from './phases/plan.js';
27
32
  import { runToolReview } from './phases/tool-review.js';
28
33
  import { refreshWorkingMemory } from './phases/working-memory.js';
@@ -104,6 +109,13 @@ export class IterationOrchestrator {
104
109
  * one process must not suppress each other's first envelope.
105
110
  */
106
111
  lastEnvelopeKey;
112
+ previousRequestContext;
113
+ projectObservations(messages) {
114
+ const config = this.ctx.compactionConfig;
115
+ return config && config.strategy !== 'disabled' && config.deduplicateObservations !== false
116
+ ? projectObservationContext(messages, this.ctx.tools, config.preserveToolResultsFrom)
117
+ : messages;
118
+ }
107
119
  /** Rich tool blocks already reported; durable history is scanned every turn. */
108
120
  warnedRichToolResults = new Set();
109
121
  /**
@@ -121,8 +133,29 @@ export class IterationOrchestrator {
121
133
  * sets it.
122
134
  */
123
135
  stopDeferredForOutstandingWork = false;
136
+ /** One current input, independent of the compactable history array. */
137
+ latestUserMessage;
124
138
  constructor(ctx) {
125
- this.ctx = ctx;
139
+ this.ctx = {
140
+ ...ctx,
141
+ onSteeringDelivered: (text) => {
142
+ this.rememberUserMessage(createRuntimeContextMessage(text, 'steering'));
143
+ },
144
+ };
145
+ ctx.checkpointMgr.setLatestUserMessageSource(() => this.latestUserMessage);
146
+ ctx.checkpointMgr.setStructuredReviewAttemptsSource?.(() => this.structuredReviewAttempts);
147
+ ctx.checkpointMgr.setNativeStructuredAttemptsSource?.(() => this.nativeStructuredAttempts);
148
+ if (ctx.structuredOutput?.mode === 'native') {
149
+ const limit = ctx.structuredOutput.maxRetries;
150
+ if (limit !== undefined && (!Number.isSafeInteger(limit) || limit < 0))
151
+ throw new RangeError('Native structuredOutput.maxRetries must be a nonnegative safe integer');
152
+ }
153
+ if (ctx.structuredOutput?.mode !== undefined &&
154
+ !['tool', 'native'].includes(ctx.structuredOutput.mode))
155
+ throw new RangeError('Unknown structuredOutput.mode');
156
+ const maxReviews = ctx.structuredOutput?.maxReviews;
157
+ if (maxReviews !== undefined && (!Number.isSafeInteger(maxReviews) || maxReviews < 0))
158
+ throw new RangeError('structuredOutput.maxReviews must be a nonnegative safe integer');
126
159
  }
127
160
  /**
128
161
  * Check the exact post-budget request for tool-result shapes the active driver
@@ -198,6 +231,19 @@ export class IterationOrchestrator {
198
231
  const { runConfig, runMgr } = this.ctx;
199
232
  const { model } = runConfig;
200
233
  const tracer = getTracer();
234
+ // Resume hydration happens after construction, before the loop starts.
235
+ this.latestUserMessage = this.ctx.checkpointMgr.restoredLatestUserMessage;
236
+ this.structuredReviewAttempts = this.ctx.checkpointMgr.restoredStructuredReviewAttempts ?? 0;
237
+ this.nativeStructuredAttempts = this.ctx.checkpointMgr.restoredNativeStructuredAttempts ?? 0;
238
+ if (!this.latestUserMessage) {
239
+ for (const message of runMgr.messages)
240
+ this.rememberUserMessage(message, false);
241
+ }
242
+ // The restored field can outlive the historical message it describes.
243
+ // Only known post-checkpoint arrivals may supersede it, never an old
244
+ // retained user turn encountered while scanning restored history.
245
+ for (const message of this.ctx.resumedInput ?? [])
246
+ this.rememberUserMessage(message);
201
247
  // One context-overflow relief per *stuck point*, not per run.
202
248
  //
203
249
  // The latch exists so that a second overflow immediately after a
@@ -222,6 +268,22 @@ export class IterationOrchestrator {
222
268
  // no post-loop block reaches.
223
269
  try {
224
270
  while (true) {
271
+ if (this.ctx.abortController.signal.aborted) {
272
+ runMgr.setStopReason('cancelled');
273
+ runMgr.markCancelled();
274
+ break;
275
+ }
276
+ if (this.ctx.structuredOutput?.mode === 'native' &&
277
+ this.nativeStructuredAttempts > this.structuredOutputRetryLimit()) {
278
+ runMgr.setStopReason('structured_output_failed');
279
+ break;
280
+ }
281
+ if (this.ctx.structuredOutput?.review &&
282
+ this.structuredReviewAttempts >
283
+ (this.ctx.structuredOutput.maxReviews ?? DEFAULT_ANSWER_REVIEW_LIMIT)) {
284
+ runMgr.setStopReason('answer_rejected');
285
+ break;
286
+ }
225
287
  // Read AND clear, in that order, in this one place.
226
288
  //
227
289
  // The flag is set by the previous iteration and read by this
@@ -265,6 +327,14 @@ export class IterationOrchestrator {
265
327
  // run and been paid for; this is the seam a host with a live
266
328
  // rate limit or a revoked tenant actually needs.
267
329
  const veto = await this.beforeStep(runMgr.currentIteration + 1);
330
+ // The hook may settle because its run signal was aborted. Stop
331
+ // before interpreting that settlement as a policy refusal or
332
+ // counting an iteration that will never reach the provider.
333
+ if (this.ctx.abortController.signal.aborted) {
334
+ runMgr.setStopReason('cancelled');
335
+ runMgr.markCancelled();
336
+ break;
337
+ }
268
338
  if (veto) {
269
339
  // Namespaced. The un-namespaced keys elsewhere in this file are
270
340
  // the frozen inventory LOG-22 exists to drain; a new call site
@@ -354,10 +424,6 @@ export class IterationOrchestrator {
354
424
  // compaction preserves). No-op when no provider is configured.
355
425
  await refreshWorkingMemory(this.ctx);
356
426
  await runCompactionCheck(this.ctx);
357
- // A context edit is a host-visible state transition, not a prelude
358
- // whose events may wait behind the next network call. In particular,
359
- // a slow or failing provider must not leave the host displaying the
360
- // pre-compaction context after Run.messages already shrank.
361
427
  yield* this.ctx.drainPending();
362
428
  // Cache discipline: keep the tools param byte-stable even on the
363
429
  // forced-final iteration and forbid tool use via tool_choice
@@ -373,9 +439,22 @@ export class IterationOrchestrator {
373
439
  // Shape this step before calling the model. `stopWhen` decides
374
440
  // whether to keep going; this decides HOW. No-op when the host
375
441
  // supplied no hook.
442
+ const contextModelBeforePreparation = this.ctx.contextModel ?? model;
376
443
  const step = await this.prepareStep(iterationNum);
444
+ stepModel = step.model ?? model;
445
+ await this.selectContextModel(stepModel);
446
+ // Preserve post-compaction preparation/recall semantics. A changed
447
+ // model needs a second check against its own window; never replay
448
+ // host preparation effects merely to rebuild its request guidance.
449
+ if (stepModel !== contextModelBeforePreparation)
450
+ await runCompactionCheck(this.ctx);
451
+ // Publish context edits before entering a possibly slow provider.
452
+ yield* this.ctx.drainPending();
377
453
  const stepAllowedTools = step.allowedTools ?? this.ctx.allowedTools;
378
- const llmTools = this.ctx.tools.toLLMTools(stepAllowedTools);
454
+ const llmTools = this.ctx.tools
455
+ .toLLMTools(stepAllowedTools)
456
+ .filter((tool) => this.ctx.structuredOutput?.mode !== 'native' ||
457
+ tool.function.name !== STRUCTURED_OUTPUT_TOOL_NAME);
379
458
  // The same list the request was built from now also bounds what
380
459
  // may run. Narrowing only the request left the restriction
381
460
  // presentational — the model was shown fewer tools and could
@@ -438,7 +517,7 @@ export class IterationOrchestrator {
438
517
  const requestHistory = stepPreamble
439
518
  ? [...baseMessages, createSystemMessage(stepPreamble)]
440
519
  : [...baseMessages];
441
- const messages = projectRequestRichContent(requestHistory, this.ctx.runConfig.maxRequestRichContentBytes ?? DEFAULT_MAX_REQUEST_RICH_CONTENT_BYTES);
520
+ const messages = projectRequestRichContent(this.projectObservations(requestHistory), this.ctx.runConfig.maxRequestRichContentBytes ?? DEFAULT_MAX_REQUEST_RICH_CONTENT_BYTES);
442
521
  await this.reportUnsupportedToolResults(messages);
443
522
  yield* this.ctx.drainPending();
444
523
  // What the model is about to be ASKED, recorded when it
@@ -482,6 +561,16 @@ export class IterationOrchestrator {
482
561
  });
483
562
  }
484
563
  if (this.ctx.pluginManager) {
564
+ const snapshot = snapshotRequestContext(messages);
565
+ const context = Object.freeze({
566
+ snapshot,
567
+ ...(this.previousRequestContext
568
+ ? {
569
+ change: diffRequestContext(this.previousRequestContext, snapshot),
570
+ }
571
+ : {}),
572
+ });
573
+ this.previousRequestContext = snapshot;
485
574
  const hookResults = await this.ctx.pluginManager.executeHooks('pre_llm_call', {
486
575
  runId: runMgr.id,
487
576
  iteration: iterationNum,
@@ -489,6 +578,7 @@ export class IterationOrchestrator {
489
578
  // Built inside the guard: a run with no plugins installed
490
579
  // pays nothing for a projection nobody reads.
491
580
  request: Object.freeze({
581
+ context,
492
582
  model: stepModel,
493
583
  // Copied per turn, not handed over live: these are the
494
584
  // run's own message objects, and a hook writing into
@@ -531,6 +621,18 @@ export class IterationOrchestrator {
531
621
  };
532
622
  const { response, messageId } = yield* streamProviderTurn(this.ctx.provider, {
533
623
  model: stepModel,
624
+ ...(this.ctx.structuredOutput?.mode === 'native'
625
+ ? {
626
+ responseFormat: {
627
+ type: 'json_schema',
628
+ json_schema: {
629
+ name: 'structured_output',
630
+ schema: renderToolSchema(this.ctx.structuredOutput.schema),
631
+ strict: true,
632
+ },
633
+ },
634
+ }
635
+ : {}),
534
636
  providerRoute: requestedRoute,
535
637
  messages,
536
638
  tools: llmTools.length > 0 ? llmTools : undefined,
@@ -550,6 +652,7 @@ export class IterationOrchestrator {
550
652
  cacheControl: { type: 'auto' },
551
653
  ...(runConfig.thinking ? { thinking: runConfig.thinking } : {}),
552
654
  ...(runConfig.effort ? { effort: runConfig.effort } : {}),
655
+ ...(!forceFinalize && runConfig.webSearch ? { webSearch: runConfig.webSearch } : {}),
553
656
  // Thread the run abort into the model call so a Stop tears the
554
657
  // in-flight turn down (provider passes it to fetch; the consumer
555
658
  // also races it). Inert when never aborted.
@@ -646,7 +749,7 @@ export class IterationOrchestrator {
646
749
  const contextFigures = this.ctx.compactionConfig
647
750
  ? (() => {
648
751
  const measured = measureContext(this.ctx);
649
- const window = resolveContextWindow(this.ctx.compactionConfig?.contextWindowTokens, runConfig.model, this.ctx.providerContextWindow);
752
+ const window = activeContextWindow(this.ctx);
650
753
  return {
651
754
  contextTokens: measured.tokens,
652
755
  contextMeasuredBy: measured.source,
@@ -780,6 +883,60 @@ export class IterationOrchestrator {
780
883
  usageBefore,
781
884
  costBefore,
782
885
  });
886
+ if (this.ctx.structuredOutput?.mode === 'native') {
887
+ const candidate = await parseNativeCandidate(this.ctx.structuredOutput.schema, response, this.ctx.abortController.signal);
888
+ let outcome;
889
+ if (candidate.success)
890
+ outcome = await this.reviewStructuredOutput(candidate.value);
891
+ else {
892
+ this.nativeStructuredAttempts++;
893
+ runMgr.pushMessage(createRuntimeContextMessage('Return a complete JSON value matching the supplied response schema. Do not continue a partial JSON fragment.', 'structured-output'));
894
+ const checkpoint = await this.ctx.checkpointMgr.create(runMgr, iterationNum);
895
+ await this.ctx.emitEvent({
896
+ type: 'checkpoint_created',
897
+ runId: runMgr.id,
898
+ checkpointId: checkpoint.id,
899
+ iteration: iterationNum,
900
+ });
901
+ outcome =
902
+ this.nativeStructuredAttempts > this.structuredOutputRetryLimit()
903
+ ? 'exhausted'
904
+ : 'retry';
905
+ }
906
+ await this.ctx.emitEvent({
907
+ type: 'iteration_completed',
908
+ runId: runMgr.id,
909
+ iteration: iterationNum,
910
+ hasToolCalls: false,
911
+ });
912
+ yield* this.ctx.drainPending();
913
+ if (this.ctx.abortController.signal.aborted || outcome === 'cancelled') {
914
+ runMgr.setStopReason('cancelled');
915
+ runMgr.markCancelled();
916
+ break;
917
+ }
918
+ if (outcome === 'accepted') {
919
+ if (!forceFinalize) {
920
+ const changed = yield* this.holdForOutstandingWork(iterationNum, false);
921
+ const inbound = this.deliverInbound();
922
+ if (changed || inbound > 0)
923
+ continue;
924
+ }
925
+ if (this.ctx.abortController.signal.aborted) {
926
+ runMgr.setStopReason('cancelled');
927
+ runMgr.markCancelled();
928
+ break;
929
+ }
930
+ this.publishStructuredOutput();
931
+ runMgr.setStopReason('end_turn');
932
+ break;
933
+ }
934
+ if (outcome === 'exhausted') {
935
+ runMgr.setStopReason(candidate.success ? 'answer_rejected' : 'structured_output_failed');
936
+ break;
937
+ }
938
+ continue;
939
+ }
783
940
  const hasContent = response.message.content !== null && response.message.content.length > 0;
784
941
  // Auto-continuation on `stop_reason: max_tokens`. The
785
942
  // model hit its per-call output cap mid-text (NOT
@@ -862,6 +1019,11 @@ export class IterationOrchestrator {
862
1019
  // a loud stop rather than a loop.
863
1020
  if (!forceFinalize && this.ctx.reviewAnswer) {
864
1021
  const review = await this.reviewAnswer(response.message.content ?? '');
1022
+ if (this.ctx.abortController.signal.aborted) {
1023
+ runMgr.setStopReason('cancelled');
1024
+ runMgr.markCancelled();
1025
+ break;
1026
+ }
865
1027
  if (review && !review.accept) {
866
1028
  const attempt = ++this.answerReviewAttempts;
867
1029
  const limit = this.ctx.maxAnswerReviews ?? DEFAULT_ANSWER_REVIEW_LIMIT;
@@ -988,12 +1150,34 @@ export class IterationOrchestrator {
988
1150
  // run ends here rather than paying for another turn whose only
989
1151
  // job would be to restate it — unless it shared its turn with
990
1152
  // other calls, which relays instead. See the method.
991
- if (this.captureStructuredOutput(reviewOutcome.results, response)) {
1153
+ const structuredOutcome = await this.captureStructuredOutput(reviewOutcome.results, response);
1154
+ if (structuredOutcome === 'retry' ||
1155
+ structuredOutcome === 'exhausted' ||
1156
+ structuredOutcome === 'cancelled') {
1157
+ await this.ctx.emitEvent({
1158
+ type: 'iteration_completed',
1159
+ runId: runMgr.id,
1160
+ iteration: iterationNum,
1161
+ hasToolCalls: true,
1162
+ });
1163
+ yield* this.ctx.drainPending();
1164
+ if (this.ctx.abortController.signal.aborted) {
1165
+ runMgr.setStopReason('cancelled');
1166
+ runMgr.markCancelled();
1167
+ break;
1168
+ }
1169
+ if (structuredOutcome === 'retry')
1170
+ continue;
1171
+ runMgr.setStopReason(structuredOutcome === 'cancelled' ? 'cancelled' : 'answer_rejected');
1172
+ if (structuredOutcome === 'cancelled')
1173
+ runMgr.markCancelled();
1174
+ break;
1175
+ }
1176
+ if (structuredOutcome === 'accepted') {
992
1177
  this.ctx.log.info('Structured output produced — ending run', {
993
1178
  [NAMZU.RUN_ID]: runMgr.id,
994
1179
  [NAMZU.ITERATION]: iterationNum,
995
1180
  });
996
- runMgr.setStopReason('end_turn');
997
1181
  await this.ctx.emitEvent({
998
1182
  type: 'iteration_completed',
999
1183
  runId: runMgr.id,
@@ -1001,6 +1185,13 @@ export class IterationOrchestrator {
1001
1185
  hasToolCalls: true,
1002
1186
  });
1003
1187
  yield* this.ctx.drainPending();
1188
+ if (this.ctx.abortController.signal.aborted) {
1189
+ runMgr.setStopReason('cancelled');
1190
+ runMgr.markCancelled();
1191
+ break;
1192
+ }
1193
+ this.publishStructuredOutput();
1194
+ runMgr.setStopReason('end_turn');
1004
1195
  break;
1005
1196
  }
1006
1197
  // A tool the author declared terminal settles the run with its
@@ -1406,18 +1597,39 @@ export class IterationOrchestrator {
1406
1597
  * message becomes the reason, so an operator is not left with a run
1407
1598
  * that stopped and no account of it.
1408
1599
  */
1600
+ stepContext(stepNumber, prepared) {
1601
+ const model = prepared.model ?? this.ctx.runConfig.model;
1602
+ const window = resolveContextWindow(this.ctx.compactionConfig?.contextWindowTokens, model, model === this.ctx.runConfig.model
1603
+ ? this.ctx.providerContextWindow
1604
+ : model === this.ctx.contextModel
1605
+ ? this.ctx.activeProviderContextWindow
1606
+ : undefined);
1607
+ const skills = prepared.skills ? renderSkillsSection([...prepared.skills]) : null;
1608
+ const preamble = [prepared.system, skills].filter(Boolean).join('\n\n');
1609
+ const preparedTokens = preamble ? estimateMessageTokens(createSystemMessage(preamble)) : 0;
1610
+ const responseReserve = Math.min(prepared.maxResponseTokens ??
1611
+ this.ctx.runConfig.maxResponseTokens ??
1612
+ Math.floor(window.tokens / 4), Math.floor(window.tokens / 4));
1613
+ return {
1614
+ runId: this.ctx.runMgr.id,
1615
+ stepNumber,
1616
+ messages: this.ctx.runMgr.messages,
1617
+ ...(this.latestUserMessage ? { latestUserMessage: this.latestUserMessage } : {}),
1618
+ signal: this.ctx.abortController.signal,
1619
+ contextBudget: {
1620
+ windowTokens: window.tokens,
1621
+ remainingTokens: Math.max(0, Math.floor(window.tokens - measureContext(this.ctx).tokens - preparedTokens - responseReserve)),
1622
+ },
1623
+ steps: this.steps,
1624
+ prepared,
1625
+ };
1626
+ }
1409
1627
  async beforeStep(stepNumber) {
1410
1628
  const configured = this.ctx.beforeStep;
1411
1629
  if (!configured)
1412
1630
  return undefined;
1413
1631
  try {
1414
- return ((await configured({
1415
- runId: this.ctx.runMgr.id,
1416
- stepNumber,
1417
- messages: this.ctx.runMgr.messages,
1418
- steps: this.steps,
1419
- prepared: {},
1420
- })) ?? undefined);
1632
+ return (await configured(this.stepContext(stepNumber, {}))) ?? undefined;
1421
1633
  }
1422
1634
  catch (err) {
1423
1635
  return { reason: `beforeStep threw: ${toErrorMessage(err)}` };
@@ -1435,15 +1647,10 @@ export class IterationOrchestrator {
1435
1647
  let result = {};
1436
1648
  for (const stage of stages) {
1437
1649
  try {
1438
- const decided = await stage({
1439
- runId: this.ctx.runMgr.id,
1440
- stepNumber,
1441
- messages: this.ctx.runMgr.messages,
1442
- steps: this.steps,
1443
- prepared: result,
1444
- });
1650
+ const decided = await stage(this.stepContext(stepNumber, result));
1445
1651
  if (decided)
1446
1652
  result = { ...result, ...decided };
1653
+ await this.selectContextModel(result.model ?? this.ctx.runConfig.model);
1447
1654
  }
1448
1655
  catch (err) {
1449
1656
  // Skipped, and the rest still run: one broken concern must
@@ -1498,6 +1705,17 @@ export class IterationOrchestrator {
1498
1705
  }
1499
1706
  return prepared;
1500
1707
  }
1708
+ async selectContextModel(model) {
1709
+ if (model !== (this.ctx.contextModel ?? this.ctx.runConfig.model)) {
1710
+ // A measurement from another tokenizer cannot price the new request.
1711
+ this.ctx.runMgr.clearLastPromptTokens();
1712
+ }
1713
+ this.ctx.contextModel = model;
1714
+ this.ctx.activeProviderContextWindow =
1715
+ model && model !== this.ctx.runConfig.model && !this.ctx.compactionConfig?.contextWindowTokens
1716
+ ? await this.ctx.resolveModelContextWindow?.(model)
1717
+ : undefined;
1718
+ }
1501
1719
  /** Steps completed so far, exposed on the returned `Run`. */
1502
1720
  steps = [];
1503
1721
  getSteps() {
@@ -1524,16 +1742,32 @@ export class IterationOrchestrator {
1524
1742
  * empty drain must change nothing at all: a `continue` on nothing queued
1525
1743
  * spends an iteration and a model call to say the same thing again.
1526
1744
  */
1745
+ rememberUserMessage(message, arriving = true) {
1746
+ if (!isOperatorUserMessage(message))
1747
+ return;
1748
+ this.latestUserMessage = message;
1749
+ // The hook field alone does not reach the model. Preserve arrivals in
1750
+ // the compaction state too, before their original message or attached
1751
+ // tool result can be shed. Initial history was already extracted at seed.
1752
+ const manager = this.ctx.workingStateManager;
1753
+ if (arriving && manager) {
1754
+ extractFromUserMessage(manager, message.content, !manager.getState().task);
1755
+ }
1756
+ }
1527
1757
  deliverInbound() {
1528
1758
  const queued = this.ctx.inboundMessages?.() ?? [];
1529
- for (const message of queued)
1759
+ for (const message of queued) {
1530
1760
  this.ctx.runMgr.pushMessage(message);
1761
+ this.rememberUserMessage(message);
1762
+ }
1531
1763
  // The steering channel's remainder. `attachSteering` already took
1532
1764
  // what it could carry on a tool result; anything still pending is
1533
1765
  // guidance from a turn that had no result to attach it to.
1534
1766
  const stranded = this.ctx.steering?.drain();
1535
1767
  if (stranded) {
1536
- this.ctx.runMgr.pushMessage(createRuntimeContextMessage(formatSteeringNote(stranded), 'steering'));
1768
+ const message = createRuntimeContextMessage(formatSteeringNote(stranded), 'steering');
1769
+ this.ctx.runMgr.pushMessage(message);
1770
+ this.rememberUserMessage(createRuntimeContextMessage(stranded, 'steering'));
1537
1771
  }
1538
1772
  return queued.length + (stranded ? 1 : 0);
1539
1773
  }
@@ -1611,7 +1845,10 @@ export class IterationOrchestrator {
1611
1845
  }
1612
1846
  /** Turns spent asking the model again for a valid structured output. */
1613
1847
  structuredOutputAttempts = 0;
1848
+ nativeStructuredAttempts = 0;
1614
1849
  structuredOutputDone = false;
1850
+ pendingStructuredOutput;
1851
+ structuredReviewAttempts = 0;
1615
1852
  structuredOutputRetryLimit() {
1616
1853
  return this.ctx.structuredOutput?.maxRetries ?? DEFAULT_STRUCTURED_OUTPUT_RETRIES;
1617
1854
  }
@@ -1632,6 +1869,8 @@ export class IterationOrchestrator {
1632
1869
  * avoid.
1633
1870
  */
1634
1871
  terminalToolOutput(results, response) {
1872
+ if (this.ctx.structuredOutput?.mode === 'native')
1873
+ return undefined;
1635
1874
  const terminal = results.filter((r) => this.ctx.tools.get(r.toolName)?.terminal === true);
1636
1875
  if (terminal.length === 0)
1637
1876
  return undefined;
@@ -1698,30 +1937,98 @@ export class IterationOrchestrator {
1698
1937
  * doing work, and it is the bound the neighbour relies on for the
1699
1938
  * identical pathology.
1700
1939
  */
1701
- captureStructuredOutput(results, response) {
1702
- if (!this.needsStructuredOutput())
1703
- return false;
1940
+ async captureStructuredOutput(results, response) {
1941
+ if (!this.needsStructuredOutput() || this.ctx.structuredOutput?.mode === 'native')
1942
+ return 'absent';
1704
1943
  const hit = results.find((r) => r.toolName === STRUCTURED_OUTPUT_TOOL_NAME && !r.isError);
1705
1944
  if (!hit)
1706
- return false;
1945
+ return 'absent';
1707
1946
  const callCount = response.message.toolCalls?.length ?? 0;
1708
1947
  if (callCount > 1) {
1709
1948
  this.ctx.log.info('Structured output shared its turn — relaying instead of settling', {
1710
1949
  [NAMZU.RUN_ID]: this.ctx.runMgr.id,
1711
1950
  'namzu.runtime.calls_in_turn': callCount,
1712
1951
  });
1713
- return false;
1952
+ return 'absent';
1714
1953
  }
1954
+ let parsed;
1715
1955
  try {
1716
- this.ctx.runMgr.setStructuredOutput(JSON.parse(hit.output));
1956
+ parsed = JSON.parse(hit.output);
1717
1957
  }
1718
1958
  catch {
1719
1959
  // The tool serializes its own validated input, so this is
1720
1960
  // unreachable in practice; keep the raw text rather than losing it.
1721
- this.ctx.runMgr.setStructuredOutput(hit.output);
1961
+ if (this.ctx.structuredOutput?.review)
1962
+ throw new Error('Structured review requires an intact JSON tool result; check tool-output limits and result transformations');
1963
+ parsed = hit.output;
1722
1964
  }
1965
+ return this.reviewStructuredOutput(parsed);
1966
+ }
1967
+ publishStructuredOutput() {
1968
+ this.ctx.runMgr.setStructuredOutput(this.pendingStructuredOutput);
1723
1969
  this.structuredOutputDone = true;
1724
- return true;
1970
+ }
1971
+ async reviewStructuredOutput(parsed) {
1972
+ if (this.ctx.abortController.signal.aborted)
1973
+ return 'cancelled';
1974
+ const reviewer = this.ctx.structuredOutput?.review;
1975
+ if (reviewer) {
1976
+ const signal = this.ctx.abortController.signal;
1977
+ if (signal.aborted)
1978
+ return 'cancelled';
1979
+ let onAbort = () => { };
1980
+ const aborted = new Promise((_resolve, reject) => {
1981
+ onAbort = () => reject(signal.reason ?? new Error('Structured review cancelled'));
1982
+ signal.addEventListener('abort', onAbort, { once: true });
1983
+ });
1984
+ let verdict;
1985
+ try {
1986
+ verdict = await Promise.race([
1987
+ Promise.resolve().then(() => reviewer(structuredClone(parsed), {
1988
+ runId: this.ctx.runMgr.id,
1989
+ iteration: this.ctx.runMgr.currentIteration,
1990
+ signal,
1991
+ messages: this.ctx.runMgr.messages,
1992
+ })),
1993
+ aborted,
1994
+ ]);
1995
+ }
1996
+ catch (error) {
1997
+ if (signal.aborted)
1998
+ return 'cancelled';
1999
+ throw error;
2000
+ }
2001
+ finally {
2002
+ signal.removeEventListener('abort', onAbort);
2003
+ }
2004
+ if (signal.aborted)
2005
+ return 'cancelled';
2006
+ if (!verdict || typeof verdict.accept !== 'boolean')
2007
+ throw new Error('Structured reviewer returned an invalid verdict');
2008
+ if (!verdict.accept) {
2009
+ if (typeof verdict.feedback !== 'string' || verdict.feedback.trim().length === 0)
2010
+ throw new Error('Structured reviewer rejection requires feedback');
2011
+ this.structuredReviewAttempts++;
2012
+ this.ctx.runMgr.pushMessage(createRuntimeContextMessage(verdict.feedback, 'answer-review'));
2013
+ // Persist both the feedback and its consumed allowance before the
2014
+ // next request. This checkpoint is not an approval/park boundary.
2015
+ const checkpoint = await this.ctx.checkpointMgr.create(this.ctx.runMgr, this.ctx.runMgr.currentIteration);
2016
+ await this.ctx.emitEvent({
2017
+ type: 'checkpoint_created',
2018
+ runId: this.ctx.runMgr.id,
2019
+ checkpointId: checkpoint.id,
2020
+ iteration: this.ctx.runMgr.currentIteration,
2021
+ });
2022
+ if (signal.aborted)
2023
+ return 'cancelled';
2024
+ return this.structuredReviewAttempts >
2025
+ (this.ctx.structuredOutput?.maxReviews ?? DEFAULT_ANSWER_REVIEW_LIMIT)
2026
+ ? 'exhausted'
2027
+ : 'retry';
2028
+ }
2029
+ }
2030
+ this.pendingStructuredOutput = parsed;
2031
+ return 'accepted';
1725
2032
  }
1726
2033
  /**
1727
2034
  * Ask the host whether this answer is good enough.
@@ -1742,6 +2049,7 @@ export class IterationOrchestrator {
1742
2049
  return await this.ctx.reviewAnswer(answer, {
1743
2050
  runId: this.ctx.runMgr.id,
1744
2051
  iteration: this.ctx.runMgr.currentIteration,
2052
+ signal: this.ctx.abortController.signal,
1745
2053
  messages: this.ctx.runMgr.messages,
1746
2054
  });
1747
2055
  }
@@ -1801,6 +2109,8 @@ export class IterationOrchestrator {
1801
2109
  });
1802
2110
  }
1803
2111
  async requestFinalResponse(model, reason) {
2112
+ if (this.ctx.structuredOutput?.mode === 'native')
2113
+ return 'structured_output_failed';
1804
2114
  const lastAssistant = [...this.ctx.runMgr.messages]
1805
2115
  .reverse()
1806
2116
  .find((m) => m.role === 'assistant');
@@ -1823,7 +2133,7 @@ export class IterationOrchestrator {
1823
2133
  ...this.ctx.runMgr.messages,
1824
2134
  createRuntimeContextMessage(`[SYSTEM] Run is ending due to ${reason}. You MUST provide a final response now summarizing all your findings and work so far. Do not use any tools.`, 'limit-finalization'),
1825
2135
  ];
1826
- const finalMessages = projectRequestRichContent(finalHistory, this.ctx.runConfig.maxRequestRichContentBytes ?? DEFAULT_MAX_REQUEST_RICH_CONTENT_BYTES);
2136
+ const finalMessages = projectRequestRichContent(this.projectObservations(finalHistory), this.ctx.runConfig.maxRequestRichContentBytes ?? DEFAULT_MAX_REQUEST_RICH_CONTENT_BYTES);
1827
2137
  await this.reportUnsupportedToolResults(finalMessages);
1828
2138
  // Same cache discipline as the forced-final iteration: keep the
1829
2139
  // tools param identical to prior iterations (cache prefix intact,