@namzu/sdk 34.2.0 → 35.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 (637) hide show
  1. package/CHANGELOG.md +133 -0
  2. package/README.md +2 -6
  3. package/dist/agents/PipelineAgent.d.ts.map +1 -1
  4. package/dist/agents/PipelineAgent.js +118 -100
  5. package/dist/agents/PipelineAgent.js.map +1 -1
  6. package/dist/agents/ReactiveAgent.d.ts.map +1 -1
  7. package/dist/agents/ReactiveAgent.js +2 -0
  8. package/dist/agents/ReactiveAgent.js.map +1 -1
  9. package/dist/agents/RouterAgent.d.ts.map +1 -1
  10. package/dist/agents/RouterAgent.js +105 -61
  11. package/dist/agents/RouterAgent.js.map +1 -1
  12. package/dist/agents/SupervisorAgent.d.ts.map +1 -1
  13. package/dist/agents/SupervisorAgent.js +8 -4
  14. package/dist/agents/SupervisorAgent.js.map +1 -1
  15. package/dist/agents/budget.d.ts +6 -0
  16. package/dist/agents/budget.d.ts.map +1 -0
  17. package/dist/agents/budget.js +33 -0
  18. package/dist/agents/budget.js.map +1 -0
  19. package/dist/agents/explore.d.ts +20 -0
  20. package/dist/agents/explore.d.ts.map +1 -0
  21. package/dist/agents/explore.js +26 -0
  22. package/dist/agents/explore.js.map +1 -0
  23. package/dist/agents/file-definitions.d.ts +80 -0
  24. package/dist/agents/file-definitions.d.ts.map +1 -0
  25. package/dist/agents/file-definitions.js +179 -0
  26. package/dist/agents/file-definitions.js.map +1 -0
  27. package/dist/agents/index.d.ts +3 -0
  28. package/dist/agents/index.d.ts.map +1 -1
  29. package/dist/agents/index.js +2 -0
  30. package/dist/agents/index.js.map +1 -1
  31. package/dist/bridge/a2a/mapper.d.ts.map +1 -1
  32. package/dist/bridge/a2a/mapper.js +6 -0
  33. package/dist/bridge/a2a/mapper.js.map +1 -1
  34. package/dist/bridge/sse/mapper.d.ts.map +1 -1
  35. package/dist/bridge/sse/mapper.js +22 -0
  36. package/dist/bridge/sse/mapper.js.map +1 -1
  37. package/dist/bus/lock.d.ts.map +1 -1
  38. package/dist/bus/lock.js +1 -10
  39. package/dist/bus/lock.js.map +1 -1
  40. package/dist/compaction/consolidation.d.ts +31 -0
  41. package/dist/compaction/consolidation.d.ts.map +1 -0
  42. package/dist/compaction/consolidation.js +63 -0
  43. package/dist/compaction/consolidation.js.map +1 -0
  44. package/dist/compaction/factory.d.ts.map +1 -1
  45. package/dist/compaction/factory.js +3 -0
  46. package/dist/compaction/factory.js.map +1 -1
  47. package/dist/compaction/index.d.ts +6 -1
  48. package/dist/compaction/index.d.ts.map +1 -1
  49. package/dist/compaction/index.js +6 -0
  50. package/dist/compaction/index.js.map +1 -1
  51. package/dist/compaction/manager.d.ts +7 -0
  52. package/dist/compaction/manager.d.ts.map +1 -1
  53. package/dist/compaction/manager.js +31 -0
  54. package/dist/compaction/manager.js.map +1 -1
  55. package/dist/compaction/plan.d.ts +23 -0
  56. package/dist/compaction/plan.d.ts.map +1 -1
  57. package/dist/compaction/plan.js +41 -24
  58. package/dist/compaction/plan.js.map +1 -1
  59. package/dist/compaction/salience/bm25.d.ts +26 -0
  60. package/dist/compaction/salience/bm25.d.ts.map +1 -0
  61. package/dist/compaction/salience/bm25.js +56 -0
  62. package/dist/compaction/salience/bm25.js.map +1 -0
  63. package/dist/compaction/salience/goal.d.ts +21 -0
  64. package/dist/compaction/salience/goal.d.ts.map +1 -0
  65. package/dist/compaction/salience/goal.js +32 -0
  66. package/dist/compaction/salience/goal.js.map +1 -0
  67. package/dist/compaction/salience/index.d.ts +4 -0
  68. package/dist/compaction/salience/index.d.ts.map +1 -0
  69. package/dist/compaction/salience/index.js +4 -0
  70. package/dist/compaction/salience/index.js.map +1 -0
  71. package/dist/compaction/salience/minhash.d.ts +17 -0
  72. package/dist/compaction/salience/minhash.d.ts.map +1 -0
  73. package/dist/compaction/salience/minhash.js +54 -0
  74. package/dist/compaction/salience/minhash.js.map +1 -0
  75. package/dist/compaction/salience/score.d.ts +64 -0
  76. package/dist/compaction/salience/score.d.ts.map +1 -0
  77. package/dist/compaction/salience/score.js +256 -0
  78. package/dist/compaction/salience/score.js.map +1 -0
  79. package/dist/compaction/salience/tokenize.d.ts +20 -0
  80. package/dist/compaction/salience/tokenize.d.ts.map +1 -0
  81. package/dist/compaction/salience/tokenize.js +92 -0
  82. package/dist/compaction/salience/tokenize.js.map +1 -0
  83. package/dist/compaction/salience/working-set.d.ts +59 -0
  84. package/dist/compaction/salience/working-set.d.ts.map +1 -0
  85. package/dist/compaction/salience/working-set.js +137 -0
  86. package/dist/compaction/salience/working-set.js.map +1 -0
  87. package/dist/compaction/serializer.d.ts +2 -0
  88. package/dist/compaction/serializer.d.ts.map +1 -1
  89. package/dist/compaction/serializer.js +15 -0
  90. package/dist/compaction/serializer.js.map +1 -1
  91. package/dist/compaction/token-estimate.d.ts +13 -0
  92. package/dist/compaction/token-estimate.d.ts.map +1 -0
  93. package/dist/compaction/token-estimate.js +58 -0
  94. package/dist/compaction/token-estimate.js.map +1 -0
  95. package/dist/compaction/tool-result-editing.d.ts +10 -2
  96. package/dist/compaction/tool-result-editing.d.ts.map +1 -1
  97. package/dist/compaction/tool-result-editing.js +22 -24
  98. package/dist/compaction/tool-result-editing.js.map +1 -1
  99. package/dist/compaction/types.d.ts +22 -1
  100. package/dist/compaction/types.d.ts.map +1 -1
  101. package/dist/compaction/wire.d.ts +3 -1
  102. package/dist/compaction/wire.d.ts.map +1 -1
  103. package/dist/compaction/wire.js +2 -0
  104. package/dist/compaction/wire.js.map +1 -1
  105. package/dist/config/runtime.d.ts +58 -28
  106. package/dist/config/runtime.d.ts.map +1 -1
  107. package/dist/config/runtime.js +13 -1
  108. package/dist/config/runtime.js.map +1 -1
  109. package/dist/connector/builtins/http.d.ts.map +1 -1
  110. package/dist/connector/builtins/http.js +2 -8
  111. package/dist/connector/builtins/http.js.map +1 -1
  112. package/dist/connector/builtins/webhook.js +2 -2
  113. package/dist/connector/builtins/webhook.js.map +1 -1
  114. package/dist/connector/mcp/adapter.d.ts +2 -0
  115. package/dist/connector/mcp/adapter.d.ts.map +1 -1
  116. package/dist/connector/mcp/adapter.js +30 -0
  117. package/dist/connector/mcp/adapter.js.map +1 -1
  118. package/dist/connector/tools/adapter.js +2 -2
  119. package/dist/connector/tools/adapter.js.map +1 -1
  120. package/dist/connector/tools/definitions.js +2 -2
  121. package/dist/connector/tools/definitions.js.map +1 -1
  122. package/dist/constants/compaction/index.d.ts +1 -0
  123. package/dist/constants/compaction/index.d.ts.map +1 -1
  124. package/dist/constants/compaction/index.js +1 -0
  125. package/dist/constants/compaction/index.js.map +1 -1
  126. package/dist/constants/telemetry/index.d.ts +0 -1
  127. package/dist/constants/telemetry/index.d.ts.map +1 -1
  128. package/dist/constants/telemetry/index.js +0 -1
  129. package/dist/constants/telemetry/index.js.map +1 -1
  130. package/dist/contracts/a2a.d.ts +5 -5
  131. package/dist/contracts/api.d.ts +4 -2
  132. package/dist/contracts/api.d.ts.map +1 -1
  133. package/dist/contracts/schemas.d.ts +1 -15
  134. package/dist/contracts/schemas.d.ts.map +1 -1
  135. package/dist/contracts/schemas.js +5 -20
  136. package/dist/contracts/schemas.js.map +1 -1
  137. package/dist/invariants/index.d.ts +1 -1
  138. package/dist/manager/agent/lifecycle.d.ts +2 -18
  139. package/dist/manager/agent/lifecycle.d.ts.map +1 -1
  140. package/dist/manager/agent/lifecycle.js +373 -340
  141. package/dist/manager/agent/lifecycle.js.map +1 -1
  142. package/dist/manager/run/persistence.d.ts +3 -0
  143. package/dist/manager/run/persistence.d.ts.map +1 -1
  144. package/dist/manager/run/persistence.js +35 -5
  145. package/dist/manager/run/persistence.js.map +1 -1
  146. package/dist/plugin/index.d.ts +2 -0
  147. package/dist/plugin/index.d.ts.map +1 -1
  148. package/dist/plugin/index.js +1 -0
  149. package/dist/plugin/index.js.map +1 -1
  150. package/dist/plugin/shell-hook.d.ts +128 -0
  151. package/dist/plugin/shell-hook.d.ts.map +1 -0
  152. package/dist/plugin/shell-hook.js +299 -0
  153. package/dist/plugin/shell-hook.js.map +1 -0
  154. package/dist/prompt/coding-agent-doctrine.d.ts +63 -0
  155. package/dist/prompt/coding-agent-doctrine.d.ts.map +1 -0
  156. package/dist/prompt/coding-agent-doctrine.js +100 -0
  157. package/dist/prompt/coding-agent-doctrine.js.map +1 -0
  158. package/dist/prompt/index.d.ts +2 -0
  159. package/dist/prompt/index.d.ts.map +1 -1
  160. package/dist/prompt/index.js +1 -0
  161. package/dist/prompt/index.js.map +1 -1
  162. package/dist/provider/errors.d.ts +1 -1
  163. package/dist/provider/errors.js +1 -1
  164. package/dist/provider/fallback.d.ts +2 -0
  165. package/dist/provider/fallback.d.ts.map +1 -1
  166. package/dist/provider/fallback.js +3 -1
  167. package/dist/provider/fallback.js.map +1 -1
  168. package/dist/provider/retry.d.ts +2 -0
  169. package/dist/provider/retry.d.ts.map +1 -1
  170. package/dist/provider/retry.js +3 -1
  171. package/dist/provider/retry.js.map +1 -1
  172. package/dist/provider/token-budget.d.ts +13 -0
  173. package/dist/provider/token-budget.d.ts.map +1 -0
  174. package/dist/provider/token-budget.js +102 -0
  175. package/dist/provider/token-budget.js.map +1 -0
  176. package/dist/public-runtime.d.ts +12 -12
  177. package/dist/public-runtime.d.ts.map +1 -1
  178. package/dist/public-runtime.js +14 -9
  179. package/dist/public-runtime.js.map +1 -1
  180. package/dist/public-tools.d.ts +2 -0
  181. package/dist/public-tools.d.ts.map +1 -1
  182. package/dist/public-tools.js +2 -0
  183. package/dist/public-tools.js.map +1 -1
  184. package/dist/public-types.d.ts +12 -2
  185. package/dist/public-types.d.ts.map +1 -1
  186. package/dist/registry/command/kernel-commands.d.ts.map +1 -1
  187. package/dist/registry/command/kernel-commands.js +18 -6
  188. package/dist/registry/command/kernel-commands.js.map +1 -1
  189. package/dist/registry/tool/execute.d.ts.map +1 -1
  190. package/dist/registry/tool/execute.js +4 -1
  191. package/dist/registry/tool/execute.js.map +1 -1
  192. package/dist/run/LimitChecker.js +1 -1
  193. package/dist/run/LimitChecker.js.map +1 -1
  194. package/dist/run/drain.js +1 -1
  195. package/dist/run/reporter.d.ts.map +1 -1
  196. package/dist/run/reporter.js +15 -0
  197. package/dist/run/reporter.js.map +1 -1
  198. package/dist/run/token-budget.d.ts +108 -0
  199. package/dist/run/token-budget.d.ts.map +1 -0
  200. package/dist/run/token-budget.js +591 -0
  201. package/dist/run/token-budget.js.map +1 -0
  202. package/dist/runtime/jobs/registry.d.ts +29 -0
  203. package/dist/runtime/jobs/registry.d.ts.map +1 -1
  204. package/dist/runtime/jobs/registry.js +98 -18
  205. package/dist/runtime/jobs/registry.js.map +1 -1
  206. package/dist/runtime/query/checkpoint.d.ts.map +1 -1
  207. package/dist/runtime/query/checkpoint.js +10 -3
  208. package/dist/runtime/query/checkpoint.js.map +1 -1
  209. package/dist/runtime/query/context.d.ts +2 -26
  210. package/dist/runtime/query/context.d.ts.map +1 -1
  211. package/dist/runtime/query/context.js +1 -29
  212. package/dist/runtime/query/context.js.map +1 -1
  213. package/dist/runtime/query/executor.d.ts +12 -9
  214. package/dist/runtime/query/executor.d.ts.map +1 -1
  215. package/dist/runtime/query/executor.js +95 -46
  216. package/dist/runtime/query/executor.js.map +1 -1
  217. package/dist/runtime/query/guard.d.ts.map +1 -1
  218. package/dist/runtime/query/guard.js +8 -0
  219. package/dist/runtime/query/guard.js.map +1 -1
  220. package/dist/runtime/query/index.d.ts +35 -4
  221. package/dist/runtime/query/index.d.ts.map +1 -1
  222. package/dist/runtime/query/index.js +152 -52
  223. package/dist/runtime/query/index.js.map +1 -1
  224. package/dist/runtime/query/iteration/index.d.ts.map +1 -1
  225. package/dist/runtime/query/iteration/index.js +16 -5
  226. package/dist/runtime/query/iteration/index.js.map +1 -1
  227. package/dist/runtime/query/iteration/phases/compaction.d.ts.map +1 -1
  228. package/dist/runtime/query/iteration/phases/compaction.js +98 -30
  229. package/dist/runtime/query/iteration/phases/compaction.js.map +1 -1
  230. package/dist/runtime/query/iteration/phases/context.d.ts +2 -0
  231. package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
  232. package/dist/runtime/query/iteration/phases/context.js.map +1 -1
  233. package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
  234. package/dist/runtime/query/iteration/phases/tool-review.js +29 -7
  235. package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
  236. package/dist/runtime/query/iteration/phases/working-memory.d.ts.map +1 -1
  237. package/dist/runtime/query/iteration/phases/working-memory.js +25 -15
  238. package/dist/runtime/query/iteration/phases/working-memory.js.map +1 -1
  239. package/dist/runtime/query/plugin-hooks.d.ts +1 -1
  240. package/dist/runtime/query/plugin-hooks.d.ts.map +1 -1
  241. package/dist/runtime/query/plugin-hooks.js +20 -1
  242. package/dist/runtime/query/plugin-hooks.js.map +1 -1
  243. package/dist/runtime/query/repeat-call.d.ts +20 -2
  244. package/dist/runtime/query/repeat-call.d.ts.map +1 -1
  245. package/dist/runtime/query/repeat-call.js +35 -7
  246. package/dist/runtime/query/repeat-call.js.map +1 -1
  247. package/dist/runtime/query/result.d.ts.map +1 -1
  248. package/dist/runtime/query/result.js +9 -0
  249. package/dist/runtime/query/result.js.map +1 -1
  250. package/dist/runtime/query/review-policy.d.ts +142 -0
  251. package/dist/runtime/query/review-policy.d.ts.map +1 -0
  252. package/dist/runtime/query/review-policy.js +144 -0
  253. package/dist/runtime/query/review-policy.js.map +1 -0
  254. package/dist/runtime/query/run-state.d.ts.map +1 -1
  255. package/dist/runtime/query/run-state.js +4 -0
  256. package/dist/runtime/query/run-state.js.map +1 -1
  257. package/dist/runtime/query/steering.d.ts +4 -0
  258. package/dist/runtime/query/steering.d.ts.map +1 -1
  259. package/dist/runtime/query/steering.js +29 -0
  260. package/dist/runtime/query/steering.js.map +1 -1
  261. package/dist/runtime/query/token-budget.d.ts +7 -0
  262. package/dist/runtime/query/token-budget.d.ts.map +1 -0
  263. package/dist/runtime/query/token-budget.js +101 -0
  264. package/dist/runtime/query/token-budget.js.map +1 -0
  265. package/dist/runtime/query/tool-output-budget.d.ts +2 -0
  266. package/dist/runtime/query/tool-output-budget.d.ts.map +1 -1
  267. package/dist/runtime/query/tool-output-budget.js +29 -11
  268. package/dist/runtime/query/tool-output-budget.js.map +1 -1
  269. package/dist/runtime/query/tool-pause.d.ts.map +1 -1
  270. package/dist/runtime/query/tool-pause.js +4 -2
  271. package/dist/runtime/query/tool-pause.js.map +1 -1
  272. package/dist/runtime/query/tooling.d.ts +4 -0
  273. package/dist/runtime/query/tooling.d.ts.map +1 -1
  274. package/dist/runtime/query/tooling.js +4 -0
  275. package/dist/runtime/query/tooling.js.map +1 -1
  276. package/dist/sandbox/provider/local.d.ts +3 -1
  277. package/dist/sandbox/provider/local.d.ts.map +1 -1
  278. package/dist/sandbox/provider/local.js +112 -12
  279. package/dist/sandbox/provider/local.js.map +1 -1
  280. package/dist/scheduler/delegating.d.ts +1 -0
  281. package/dist/scheduler/delegating.d.ts.map +1 -1
  282. package/dist/scheduler/delegating.js +29 -12
  283. package/dist/scheduler/delegating.js.map +1 -1
  284. package/dist/scheduler/local.d.ts +1 -0
  285. package/dist/scheduler/local.d.ts.map +1 -1
  286. package/dist/scheduler/local.js +4 -7
  287. package/dist/scheduler/local.js.map +1 -1
  288. package/dist/session/index.d.ts +0 -1
  289. package/dist/session/index.d.ts.map +1 -1
  290. package/dist/session/index.js +0 -1
  291. package/dist/session/index.js.map +1 -1
  292. package/dist/session/workspace/path-builder.d.ts.map +1 -1
  293. package/dist/session/workspace/path-builder.js +5 -4
  294. package/dist/session/workspace/path-builder.js.map +1 -1
  295. package/dist/store/feedback/disk.d.ts.map +1 -1
  296. package/dist/store/feedback/disk.js +4 -6
  297. package/dist/store/feedback/disk.js.map +1 -1
  298. package/dist/store/index.d.ts +2 -0
  299. package/dist/store/index.d.ts.map +1 -1
  300. package/dist/store/index.js +1 -0
  301. package/dist/store/index.js.map +1 -1
  302. package/dist/store/memory/disk.d.ts.map +1 -1
  303. package/dist/store/memory/disk.js +3 -12
  304. package/dist/store/memory/disk.js.map +1 -1
  305. package/dist/store/run/checkpoint-disk.d.ts +3 -3
  306. package/dist/store/run/checkpoint-disk.d.ts.map +1 -1
  307. package/dist/store/run/checkpoint-disk.js +14 -26
  308. package/dist/store/run/checkpoint-disk.js.map +1 -1
  309. package/dist/store/run/claim-disk.js +1 -1
  310. package/dist/store/run/conformance.d.ts +1 -1
  311. package/dist/store/run/conformance.d.ts.map +1 -1
  312. package/dist/store/run/conformance.js +41 -33
  313. package/dist/store/run/conformance.js.map +1 -1
  314. package/dist/store/run/disk.d.ts.map +1 -1
  315. package/dist/store/run/disk.js +20 -4
  316. package/dist/store/run/disk.js.map +1 -1
  317. package/dist/store/run/token-budget-disk.d.ts +37 -0
  318. package/dist/store/run/token-budget-disk.d.ts.map +1 -0
  319. package/dist/store/run/token-budget-disk.js +208 -0
  320. package/dist/store/run/token-budget-disk.js.map +1 -0
  321. package/dist/store/session/disk.d.ts +4 -13
  322. package/dist/store/session/disk.d.ts.map +1 -1
  323. package/dist/store/session/disk.js +34 -31
  324. package/dist/store/session/disk.js.map +1 -1
  325. package/dist/store/session/memory.d.ts +2 -0
  326. package/dist/store/session/memory.d.ts.map +1 -1
  327. package/dist/store/session/memory.js +41 -2
  328. package/dist/store/session/memory.js.map +1 -1
  329. package/dist/store/task/disk.d.ts.map +1 -1
  330. package/dist/store/task/disk.js +7 -8
  331. package/dist/store/task/disk.js.map +1 -1
  332. package/dist/store/topic/memory.d.ts +2 -0
  333. package/dist/store/topic/memory.d.ts.map +1 -1
  334. package/dist/store/topic/memory.js +13 -1
  335. package/dist/store/topic/memory.js.map +1 -1
  336. package/dist/test-support/ids.d.ts +4 -19
  337. package/dist/test-support/ids.d.ts.map +1 -1
  338. package/dist/test-support/ids.js +51 -59
  339. package/dist/test-support/ids.js.map +1 -1
  340. package/dist/tools/advisory/index.d.ts.map +1 -1
  341. package/dist/tools/advisory/index.js +3 -1
  342. package/dist/tools/advisory/index.js.map +1 -1
  343. package/dist/tools/builtins/bash.d.ts +2 -0
  344. package/dist/tools/builtins/bash.d.ts.map +1 -1
  345. package/dist/tools/builtins/bash.js +9 -11
  346. package/dist/tools/builtins/bash.js.map +1 -1
  347. package/dist/tools/builtins/computer-use.d.ts +2 -2
  348. package/dist/tools/builtins/computer-use.d.ts.map +1 -1
  349. package/dist/tools/builtins/computer-use.js +4 -2
  350. package/dist/tools/builtins/computer-use.js.map +1 -1
  351. package/dist/tools/builtins/edit.js +2 -2
  352. package/dist/tools/builtins/edit.js.map +1 -1
  353. package/dist/tools/builtins/glob.js +3 -3
  354. package/dist/tools/builtins/glob.js.map +1 -1
  355. package/dist/tools/builtins/grep.js +2 -2
  356. package/dist/tools/builtins/grep.js.map +1 -1
  357. package/dist/tools/builtins/ls.js +2 -2
  358. package/dist/tools/builtins/ls.js.map +1 -1
  359. package/dist/tools/builtins/lsp.js +2 -2
  360. package/dist/tools/builtins/lsp.js.map +1 -1
  361. package/dist/tools/builtins/read-file.js +2 -2
  362. package/dist/tools/builtins/read-file.js.map +1 -1
  363. package/dist/tools/builtins/write-file.js +2 -2
  364. package/dist/tools/builtins/write-file.js.map +1 -1
  365. package/dist/tools/coordinator/ask-user-question.d.ts +33 -0
  366. package/dist/tools/coordinator/ask-user-question.d.ts.map +1 -0
  367. package/dist/tools/coordinator/ask-user-question.js +237 -0
  368. package/dist/tools/coordinator/ask-user-question.js.map +1 -0
  369. package/dist/tools/coordinator/index.d.ts +1 -2
  370. package/dist/tools/coordinator/index.d.ts.map +1 -1
  371. package/dist/tools/coordinator/index.js +4 -220
  372. package/dist/tools/coordinator/index.js.map +1 -1
  373. package/dist/tools/memory/read.d.ts.map +1 -1
  374. package/dist/tools/memory/read.js +2 -4
  375. package/dist/tools/memory/read.js.map +1 -1
  376. package/dist/tools/paths.d.ts +13 -0
  377. package/dist/tools/paths.d.ts.map +1 -1
  378. package/dist/tools/paths.js +53 -0
  379. package/dist/tools/paths.js.map +1 -1
  380. package/dist/tools/roster.d.ts +27 -0
  381. package/dist/tools/roster.d.ts.map +1 -0
  382. package/dist/tools/roster.js +42 -0
  383. package/dist/tools/roster.js.map +1 -0
  384. package/dist/types/agent/base.d.ts +5 -0
  385. package/dist/types/agent/base.d.ts.map +1 -1
  386. package/dist/types/agent/pipeline.d.ts +3 -0
  387. package/dist/types/agent/pipeline.d.ts.map +1 -1
  388. package/dist/types/agent/router.d.ts +2 -3
  389. package/dist/types/agent/router.d.ts.map +1 -1
  390. package/dist/types/agent/scheduler.d.ts +3 -0
  391. package/dist/types/agent/scheduler.d.ts.map +1 -1
  392. package/dist/types/agent/task.d.ts +5 -16
  393. package/dist/types/agent/task.d.ts.map +1 -1
  394. package/dist/types/agent/task.js.map +1 -1
  395. package/dist/types/common/index.d.ts.map +1 -1
  396. package/dist/types/common/index.js +3 -0
  397. package/dist/types/common/index.js.map +1 -1
  398. package/dist/types/computer-use/index.d.ts +8 -0
  399. package/dist/types/computer-use/index.d.ts.map +1 -1
  400. package/dist/types/computer-use/index.js.map +1 -1
  401. package/dist/types/hitl/index.d.ts +5 -0
  402. package/dist/types/hitl/index.d.ts.map +1 -1
  403. package/dist/types/hitl/index.js.map +1 -1
  404. package/dist/types/ids/brand.d.ts +5 -47
  405. package/dist/types/ids/brand.d.ts.map +1 -1
  406. package/dist/types/ids/brand.js +2 -39
  407. package/dist/types/ids/brand.js.map +1 -1
  408. package/dist/types/ids/index.d.ts +59 -69
  409. package/dist/types/ids/index.d.ts.map +1 -1
  410. package/dist/types/ids/index.js +12 -10
  411. package/dist/types/ids/index.js.map +1 -1
  412. package/dist/types/permission/index.d.ts +9 -0
  413. package/dist/types/permission/index.d.ts.map +1 -1
  414. package/dist/types/permission/index.js +9 -1
  415. package/dist/types/permission/index.js.map +1 -1
  416. package/dist/types/plugin/index.d.ts +45 -4
  417. package/dist/types/plugin/index.d.ts.map +1 -1
  418. package/dist/types/plugin/index.js +7 -0
  419. package/dist/types/plugin/index.js.map +1 -1
  420. package/dist/types/run/config.d.ts +3 -0
  421. package/dist/types/run/config.d.ts.map +1 -1
  422. package/dist/types/run/emergency.d.ts +5 -0
  423. package/dist/types/run/emergency.d.ts.map +1 -1
  424. package/dist/types/run/emergency.js.map +1 -1
  425. package/dist/types/run/entity.d.ts +6 -2
  426. package/dist/types/run/entity.d.ts.map +1 -1
  427. package/dist/types/run/events.d.ts +35 -0
  428. package/dist/types/run/events.d.ts.map +1 -1
  429. package/dist/types/run/events.js.map +1 -1
  430. package/dist/types/run/index.d.ts +1 -0
  431. package/dist/types/run/index.d.ts.map +1 -1
  432. package/dist/types/run/index.js +1 -0
  433. package/dist/types/run/index.js.map +1 -1
  434. package/dist/types/run/state.d.ts +16 -15
  435. package/dist/types/run/state.d.ts.map +1 -1
  436. package/dist/types/run/state.js +41 -22
  437. package/dist/types/run/state.js.map +1 -1
  438. package/dist/types/run/stop-reason.d.ts +3 -14
  439. package/dist/types/run/stop-reason.d.ts.map +1 -1
  440. package/dist/types/run/token-budget-store.d.ts +29 -0
  441. package/dist/types/run/token-budget-store.d.ts.map +1 -0
  442. package/dist/types/run/token-budget-store.js +25 -0
  443. package/dist/types/run/token-budget-store.js.map +1 -0
  444. package/dist/types/sandbox/index.d.ts +27 -2
  445. package/dist/types/sandbox/index.d.ts.map +1 -1
  446. package/dist/types/sandbox/index.js.map +1 -1
  447. package/dist/types/session/store.d.ts +8 -0
  448. package/dist/types/session/store.d.ts.map +1 -1
  449. package/dist/types/tool/index.d.ts +15 -0
  450. package/dist/types/tool/index.d.ts.map +1 -1
  451. package/dist/types/tool/index.js.map +1 -1
  452. package/dist/utils/frontmatter.d.ts +1 -1
  453. package/dist/utils/frontmatter.js +1 -1
  454. package/dist/utils/id-format.d.ts +3 -0
  455. package/dist/utils/id-format.d.ts.map +1 -0
  456. package/dist/utils/id-format.js +9 -0
  457. package/dist/utils/id-format.js.map +1 -0
  458. package/dist/utils/id.d.ts +65 -32
  459. package/dist/utils/id.d.ts.map +1 -1
  460. package/dist/utils/id.js +168 -148
  461. package/dist/utils/id.js.map +1 -1
  462. package/dist/utils/log/exception.js +1 -1
  463. package/dist/utils/log/exception.js.map +1 -1
  464. package/dist/utils/log/index.d.ts.map +1 -1
  465. package/dist/utils/log/index.js +1 -2
  466. package/dist/utils/log/index.js.map +1 -1
  467. package/dist/utils/log/templates.d.ts.map +1 -1
  468. package/dist/utils/log/templates.js +0 -1
  469. package/dist/utils/log/templates.js.map +1 -1
  470. package/package.json +1 -1
  471. package/src/agents/AGENTS.md +1 -1
  472. package/src/agents/PipelineAgent.ts +129 -109
  473. package/src/agents/ReactiveAgent.ts +2 -0
  474. package/src/agents/RouterAgent.ts +120 -73
  475. package/src/agents/SupervisorAgent.ts +12 -4
  476. package/src/agents/budget.ts +42 -0
  477. package/src/agents/explore.ts +29 -0
  478. package/src/agents/file-definitions.ts +237 -0
  479. package/src/agents/index.ts +15 -0
  480. package/src/bridge/a2a/mapper.ts +6 -0
  481. package/src/bridge/sse/mapper.ts +22 -0
  482. package/src/bus/lock.ts +1 -10
  483. package/src/compaction/consolidation.ts +79 -0
  484. package/src/compaction/factory.ts +3 -0
  485. package/src/compaction/index.ts +34 -4
  486. package/src/compaction/manager.ts +39 -1
  487. package/src/compaction/plan.ts +52 -21
  488. package/src/compaction/salience/bm25.ts +72 -0
  489. package/src/compaction/salience/goal.ts +44 -0
  490. package/src/compaction/salience/index.ts +19 -0
  491. package/src/compaction/salience/minhash.ts +53 -0
  492. package/src/compaction/salience/score.ts +305 -0
  493. package/src/compaction/salience/tokenize.ts +89 -0
  494. package/src/compaction/salience/working-set.ts +187 -0
  495. package/src/compaction/serializer.ts +16 -0
  496. package/src/compaction/token-estimate.ts +57 -0
  497. package/src/compaction/tool-result-editing.ts +28 -26
  498. package/src/compaction/types.ts +24 -1
  499. package/src/compaction/wire.ts +5 -1
  500. package/src/config/runtime.ts +13 -1
  501. package/src/connector/builtins/http.ts +2 -8
  502. package/src/connector/builtins/webhook.ts +2 -2
  503. package/src/connector/mcp/adapter.ts +32 -0
  504. package/src/connector/tools/adapter.ts +2 -2
  505. package/src/connector/tools/definitions.ts +2 -2
  506. package/src/constants/compaction/index.ts +1 -0
  507. package/src/constants/telemetry/index.ts +0 -1
  508. package/src/contracts/api.ts +5 -1
  509. package/src/contracts/schemas.ts +6 -20
  510. package/src/invariants/index.ts +1 -1
  511. package/src/manager/agent/lifecycle.ts +380 -352
  512. package/src/manager/run/persistence.ts +35 -5
  513. package/src/plugin/index.ts +19 -0
  514. package/src/plugin/shell-hook.ts +403 -0
  515. package/src/prompt/coding-agent-doctrine.ts +118 -0
  516. package/src/prompt/index.ts +8 -0
  517. package/src/provider/errors.ts +1 -1
  518. package/src/provider/fallback.ts +4 -1
  519. package/src/provider/retry.ts +4 -1
  520. package/src/provider/token-budget.ts +114 -0
  521. package/src/public-runtime.ts +54 -27
  522. package/src/public-tools.ts +5 -0
  523. package/src/public-types.ts +65 -0
  524. package/src/registry/command/kernel-commands.ts +16 -6
  525. package/src/registry/tool/execute.ts +4 -1
  526. package/src/run/LimitChecker.ts +1 -1
  527. package/src/run/drain.ts +1 -1
  528. package/src/run/reporter.ts +15 -0
  529. package/src/run/token-budget.ts +692 -0
  530. package/src/runtime/jobs/registry.ts +123 -17
  531. package/src/runtime/query/checkpoint.ts +10 -3
  532. package/src/runtime/query/context.ts +3 -57
  533. package/src/runtime/query/executor.ts +128 -58
  534. package/src/runtime/query/guard.ts +8 -0
  535. package/src/runtime/query/index.ts +201 -62
  536. package/src/runtime/query/iteration/index.ts +24 -6
  537. package/src/runtime/query/iteration/phases/compaction.ts +130 -31
  538. package/src/runtime/query/iteration/phases/context.ts +2 -0
  539. package/src/runtime/query/iteration/phases/tool-review.ts +39 -7
  540. package/src/runtime/query/iteration/phases/working-memory.ts +23 -14
  541. package/src/runtime/query/plugin-hooks.ts +24 -2
  542. package/src/runtime/query/repeat-call.ts +42 -7
  543. package/src/runtime/query/result.ts +9 -0
  544. package/src/runtime/query/review-policy.ts +231 -0
  545. package/src/runtime/query/run-state.ts +4 -0
  546. package/src/runtime/query/steering.ts +32 -0
  547. package/src/runtime/query/token-budget.ts +127 -0
  548. package/src/runtime/query/tool-output-budget.ts +33 -10
  549. package/src/runtime/query/tool-pause.ts +4 -2
  550. package/src/runtime/query/tooling.ts +8 -0
  551. package/src/sandbox/provider/local.ts +123 -13
  552. package/src/scheduler/delegating.ts +35 -13
  553. package/src/scheduler/local.ts +5 -7
  554. package/src/session/index.ts +0 -1
  555. package/src/session/workspace/path-builder.ts +5 -4
  556. package/src/store/feedback/disk.ts +4 -6
  557. package/src/store/index.ts +2 -0
  558. package/src/store/memory/disk.ts +3 -11
  559. package/src/store/run/checkpoint-disk.ts +14 -27
  560. package/src/store/run/claim-disk.ts +1 -1
  561. package/src/store/run/conformance.ts +55 -39
  562. package/src/store/run/disk.ts +19 -4
  563. package/src/store/run/token-budget-disk.ts +247 -0
  564. package/src/store/session/disk.ts +36 -29
  565. package/src/store/session/memory.ts +38 -1
  566. package/src/store/task/disk.ts +7 -8
  567. package/src/store/topic/memory.ts +13 -1
  568. package/src/test-support/ids.ts +62 -59
  569. package/src/tools/advisory/index.ts +3 -1
  570. package/src/tools/builtins/bash.ts +11 -12
  571. package/src/tools/builtins/computer-use.ts +6 -2
  572. package/src/tools/builtins/edit.ts +2 -2
  573. package/src/tools/builtins/glob.ts +3 -3
  574. package/src/tools/builtins/grep.ts +2 -2
  575. package/src/tools/builtins/ls.ts +2 -2
  576. package/src/tools/builtins/lsp.ts +2 -2
  577. package/src/tools/builtins/read-file.ts +2 -2
  578. package/src/tools/builtins/write-file.ts +2 -2
  579. package/src/tools/coordinator/ask-user-question.ts +284 -0
  580. package/src/tools/coordinator/index.ts +5 -248
  581. package/src/tools/memory/read.ts +2 -4
  582. package/src/tools/paths.ts +64 -0
  583. package/src/tools/roster.ts +46 -0
  584. package/src/types/agent/base.ts +6 -0
  585. package/src/types/agent/pipeline.ts +3 -0
  586. package/src/types/agent/router.ts +2 -3
  587. package/src/types/agent/scheduler.ts +4 -0
  588. package/src/types/agent/task.ts +5 -18
  589. package/src/types/common/index.ts +3 -0
  590. package/src/types/computer-use/index.ts +8 -0
  591. package/src/types/hitl/index.ts +5 -0
  592. package/src/types/ids/brand.ts +5 -48
  593. package/src/types/ids/index.ts +66 -75
  594. package/src/types/permission/index.ts +11 -0
  595. package/src/types/plugin/index.ts +49 -1
  596. package/src/types/run/config.ts +3 -0
  597. package/src/types/run/emergency.ts +5 -0
  598. package/src/types/run/entity.ts +6 -2
  599. package/src/types/run/events.ts +37 -0
  600. package/src/types/run/index.ts +1 -0
  601. package/src/types/run/state.ts +58 -30
  602. package/src/types/run/stop-reason.ts +3 -14
  603. package/src/types/run/token-budget-store.ts +54 -0
  604. package/src/types/sandbox/index.ts +32 -0
  605. package/src/types/session/store.ts +8 -0
  606. package/src/types/tool/index.ts +15 -0
  607. package/src/utils/frontmatter.ts +1 -1
  608. package/src/utils/id-format.ts +9 -0
  609. package/src/utils/id.ts +222 -181
  610. package/src/utils/log/exception.ts +1 -1
  611. package/src/utils/log/index.ts +1 -2
  612. package/src/utils/log/templates.ts +0 -1
  613. package/dist/session/migration/errors.d.ts +0 -26
  614. package/dist/session/migration/errors.d.ts.map +0 -1
  615. package/dist/session/migration/errors.js +0 -22
  616. package/dist/session/migration/errors.js.map +0 -1
  617. package/dist/session/migration/filesystem.d.ts +0 -122
  618. package/dist/session/migration/filesystem.d.ts.map +0 -1
  619. package/dist/session/migration/filesystem.js +0 -379
  620. package/dist/session/migration/filesystem.js.map +0 -1
  621. package/dist/session/migration/id-prefix.d.ts +0 -113
  622. package/dist/session/migration/id-prefix.d.ts.map +0 -1
  623. package/dist/session/migration/id-prefix.js +0 -132
  624. package/dist/session/migration/id-prefix.js.map +0 -1
  625. package/dist/session/migration/index.d.ts +0 -12
  626. package/dist/session/migration/index.d.ts.map +0 -1
  627. package/dist/session/migration/index.js +0 -12
  628. package/dist/session/migration/index.js.map +0 -1
  629. package/dist/session/migration/marker.d.ts +0 -57
  630. package/dist/session/migration/marker.d.ts.map +0 -1
  631. package/dist/session/migration/marker.js +0 -123
  632. package/dist/session/migration/marker.js.map +0 -1
  633. package/src/session/migration/errors.ts +0 -23
  634. package/src/session/migration/filesystem.ts +0 -468
  635. package/src/session/migration/id-prefix.ts +0 -166
  636. package/src/session/migration/index.ts +0 -41
  637. package/src/session/migration/marker.ts +0 -142
@@ -1,17 +1,24 @@
1
1
  import { resolveContextWindow } from '../../../../compaction/context-window.js'
2
2
  import { findDanglingMessages } from '../../../../compaction/dangling.js'
3
- import { type CompactionPlan, planCompaction } from '../../../../compaction/plan.js'
3
+ import {
4
+ type CompactionPlan,
5
+ DEFAULT_SOFT_TARGET,
6
+ planCompaction,
7
+ planSalienceWorkingSet,
8
+ } from '../../../../compaction/plan.js'
4
9
  import type { ContextReducer, ContextReduction } from '../../../../compaction/reducer.js'
5
10
  import { createSlidingWindowReducer } from '../../../../compaction/reducer.js'
6
11
  import { findRetainedIndices } from '../../../../compaction/retention.js'
7
12
  import { serializeState } from '../../../../compaction/serializer.js'
8
13
  import { buildCompactionMessage, isCompactionMessage } from '../../../../compaction/summary.js'
14
+ import { estimateMessagesTokens } from '../../../../compaction/token-estimate.js'
9
15
  import { buildVerifiedSummaryWithBoundedProvider } from '../../../../compaction/verifier.js'
10
16
  import { CHARS_PER_TOKEN } from '../../../../constants/limits.js'
11
17
  import { NAMZU } from '../../../../constants/telemetry/index.js'
12
18
  import { invariants } from '../../../../invariants/index.js'
13
19
  import { resolveTaskModel } from '../../../../model-router/task-router.js'
14
20
  import type { Message } from '../../../../types/message/index.js'
21
+ import { applyLifecycleHookResults } from '../../plugin-hooks.js'
15
22
  import type { IterationContext } from './context.js'
16
23
  import { isWorkingMemoryMessage } from './working-memory.js'
17
24
 
@@ -31,16 +38,11 @@ export { isCompactionMessage } from '../../../../compaction/summary.js'
31
38
  * fraction of itself.
32
39
  */
33
40
  const MIN_RELIEF_FRACTION = 0.02
34
- const MIN_RELIEF_CHARS = 2_000
41
+ const MIN_RELIEF_TOKENS = 500
35
42
 
36
43
  /**
37
- * Model-visible size of a message body, in characters.
38
- *
39
- * An image block is measured by its base64 payload because that is what
40
- * actually occupies the request. It is NOT what the model is billed for —
41
- * an image costs far fewer tokens than its base64 length divided by four —
42
- * but under-counting it to zero is the worse error: it let a run full of
43
- * screenshots read as an empty context.
44
+ * Serialized content size, only for byte-volume telemetry. This is never
45
+ * converted to prompt tokens: compressed image bytes are not model text.
44
46
  */
45
47
  function measureContentChars(content: unknown): number {
46
48
  if (typeof content === 'string') return content.length
@@ -53,23 +55,6 @@ function measureContentChars(content: unknown): number {
53
55
  return total
54
56
  }
55
57
 
56
- function estimateMessageTokens(messages: readonly Message[]): number {
57
- let chars = 0
58
- for (const msg of messages) {
59
- // `content` is `string | ToolResultBlock[]`. On an array, `.length` is
60
- // the BLOCK COUNT, so a tool result carrying a 400 KB screenshot
61
- // contributed 1 — and the estimate that decides when to compact read
62
- // near zero for exactly the runs that need compacting most.
63
- chars += measureContentChars(msg.content)
64
- if (msg.role === 'assistant' && msg.toolCalls) {
65
- for (const tc of msg.toolCalls) {
66
- chars += tc.function.name.length + tc.function.arguments.length
67
- }
68
- }
69
- }
70
- return Math.ceil(chars / CHARS_PER_TOKEN)
71
- }
72
-
73
58
  /**
74
59
  * Tokens the tool catalogue occupies in every request.
75
60
  *
@@ -94,7 +79,7 @@ function estimateToolCatalogTokens(ctx: IterationContext): number {
94
79
  }
95
80
 
96
81
  function estimateTokens(ctx: IterationContext): number {
97
- return estimateMessageTokens(ctx.runMgr.messages) + estimateToolCatalogTokens(ctx)
82
+ return estimateMessagesTokens(ctx.runMgr.messages) + estimateToolCatalogTokens(ctx)
98
83
  }
99
84
 
100
85
  type ToolResultClearPlan = Extract<CompactionPlan, { kind: 'cleared' }>
@@ -124,6 +109,7 @@ async function emitContextUsageSnapshot(
124
109
  type: 'token_usage_updated',
125
110
  runId: ctx.runMgr.id,
126
111
  usage: { ...ctx.runMgr.tokenUsage },
112
+ budget: ctx.runMgr.budget?.summary(),
127
113
  cost: { ...ctx.runMgr.costInfo },
128
114
  contextTokens,
129
115
  contextMeasuredBy: 'estimate',
@@ -148,6 +134,7 @@ async function emitToolResultClear(
148
134
  runId: ctx.runMgr.id,
149
135
  iteration: ctx.runMgr.currentIteration,
150
136
  clearedCount: plan.clearedCount,
137
+ ...(plan.stubbedCount !== undefined ? { stubbedCount: plan.stubbedCount } : {}),
151
138
  charsReclaimed: plan.charsReclaimed,
152
139
  reclaimedTokens: plan.reclaimedTokens,
153
140
  reliefWasEnough: plan.reliefWasEnough,
@@ -207,7 +194,7 @@ export function measureContext(ctx: IterationContext): {
207
194
  if (reported !== undefined && reported > 0) {
208
195
  const measuredThrough = ctx.runMgr.lastPromptMessageCount ?? ctx.runMgr.messages.length
209
196
  const appended = ctx.runMgr.messages.slice(measuredThrough)
210
- return { tokens: reported + estimateMessageTokens(appended), source: 'provider' }
197
+ return { tokens: reported + estimateMessagesTokens(appended), source: 'provider' }
211
198
  }
212
199
  return { tokens: estimateTokens(ctx), source: 'estimate' }
213
200
  }
@@ -233,22 +220,25 @@ export function measureContext(ctx: IterationContext): {
233
220
  export async function relieveOverflow(ctx: IterationContext): Promise<boolean> {
234
221
  const before = ctx.runMgr.messages.length
235
222
  const beforeChars = totalChars(ctx.runMgr.messages)
223
+ const beforeTokens = estimateMessagesTokens(ctx.runMgr.messages)
236
224
 
237
225
  await runCompactionCheck(ctx, { force: true })
238
226
 
239
227
  const shed = beforeChars - totalChars(ctx.runMgr.messages)
228
+ const tokensShed = beforeTokens - estimateMessagesTokens(ctx.runMgr.messages)
240
229
  // A shed has to be big enough to plausibly change the provider's verdict.
241
230
  // Any positive number used to count, so clearing a single short tool
242
231
  // result reported success, the turn was retried against a prompt that was
243
232
  // still over the window, and the retry burned a call to learn nothing.
244
233
  // The floor is a fraction of what was there rather than a constant: what
245
234
  // counts as meaningful scales with the prompt.
246
- const meaningful = Math.max(MIN_RELIEF_CHARS, beforeChars * MIN_RELIEF_FRACTION)
247
- if (shed < meaningful) {
235
+ const meaningful = Math.max(MIN_RELIEF_TOKENS, beforeTokens * MIN_RELIEF_FRACTION)
236
+ if (tokensShed < meaningful) {
248
237
  ctx.log.warn('Context overflow with too little left to shed — the prompt is irreducible', {
249
238
  [NAMZU.RUN_ID]: ctx.runMgr.id,
250
239
  'namzu.runtime.messages': before,
251
240
  'namzu.runtime.chars_shed': shed,
241
+ 'namzu.runtime.tokens_shed': tokensShed,
252
242
  'namzu.runtime.needed_at_least': Math.ceil(meaningful),
253
243
  })
254
244
  return false
@@ -259,6 +249,7 @@ export async function relieveOverflow(ctx: IterationContext): Promise<boolean> {
259
249
  'namzu.runtime.messages_before': before,
260
250
  'namzu.runtime.messages_after': ctx.runMgr.messages.length,
261
251
  'namzu.runtime.chars_shed': shed,
252
+ 'namzu.runtime.tokens_shed': tokensShed,
262
253
  })
263
254
  return true
264
255
  }
@@ -490,9 +481,57 @@ async function recordShed(
490
481
  })
491
482
  }
492
483
 
484
+ /**
485
+ * A pass, once the check decided to run one, is bracketed by the
486
+ * `pre_compact` and `post_compact` hooks. Observational: a hook sees the
487
+ * numbers and cannot stop the pass, because a context the provider will
488
+ * reject is not a thing a hook may insist on.
489
+ */
490
+ interface CompactionPass {
491
+ attempted: boolean
492
+ reason: 'threshold' | 'overflow'
493
+ tokensBefore: number
494
+ contextWindowTokens: number
495
+ }
496
+
493
497
  export async function runCompactionCheck(
494
498
  ctx: IterationContext,
495
499
  options?: { force?: boolean },
500
+ ): Promise<void> {
501
+ const pass: CompactionPass = {
502
+ attempted: false,
503
+ reason: options?.force ? 'overflow' : 'threshold',
504
+ tokensBefore: 0,
505
+ contextWindowTokens: 0,
506
+ }
507
+ try {
508
+ await runCompactionCheckInner(ctx, pass, options)
509
+ } finally {
510
+ if (pass.attempted && ctx.pluginManager) {
511
+ const results = await ctx.pluginManager.executeHooks(
512
+ 'post_compact',
513
+ {
514
+ runId: ctx.runMgr.id,
515
+ iteration: ctx.runMgr.currentIteration,
516
+ compaction: {
517
+ reason: pass.reason,
518
+ tokensBefore: pass.tokensBefore,
519
+ tokensAfter: estimateTokens(ctx),
520
+ contextWindowTokens: pass.contextWindowTokens,
521
+ },
522
+ signal: ctx.abortController.signal,
523
+ },
524
+ ctx.emitEvent,
525
+ )
526
+ applyLifecycleHookResults('post_compact', results)
527
+ }
528
+ }
529
+ }
530
+
531
+ async function runCompactionCheckInner(
532
+ ctx: IterationContext,
533
+ pass: CompactionPass,
534
+ options?: { force?: boolean },
496
535
  ): Promise<void> {
497
536
  const config = ctx.compactionConfig
498
537
  if (!config) return
@@ -519,7 +558,34 @@ export async function runCompactionCheck(
519
558
 
520
559
  // A forced pass skips the threshold: it runs because the provider
521
560
  // rejected the prompt, which is stronger evidence than any estimate.
522
- if (!options?.force && usage < config.triggerThreshold) return
561
+ // The salience strategy starts holding the context at `softTarget`,
562
+ // well before the summary trigger; every other strategy waits for it.
563
+ const salience = config.strategy === 'salience'
564
+ const startAt = salience
565
+ ? Math.min(config.softTarget ?? DEFAULT_SOFT_TARGET, config.triggerThreshold)
566
+ : config.triggerThreshold
567
+ if (!options?.force && usage < startAt) return
568
+
569
+ pass.attempted = true
570
+ pass.tokensBefore = estimatedTokens
571
+ pass.contextWindowTokens = budget
572
+ if (ctx.pluginManager) {
573
+ const results = await ctx.pluginManager.executeHooks(
574
+ 'pre_compact',
575
+ {
576
+ runId: ctx.runMgr.id,
577
+ iteration: ctx.runMgr.currentIteration,
578
+ compaction: {
579
+ reason: pass.reason,
580
+ tokensBefore: estimatedTokens,
581
+ contextWindowTokens: budget,
582
+ },
583
+ signal: ctx.abortController.signal,
584
+ },
585
+ ctx.emitEvent,
586
+ )
587
+ applyLifecycleHookResults('pre_compact', results)
588
+ }
523
589
 
524
590
  // A reducer, when the run has one, OWNS reduction — the structured pass
525
591
  // below does not also run. `strategy: 'sliding-window'` resolves to the
@@ -571,6 +637,39 @@ export async function runCompactionCheck(
571
637
  // The decision is `planCompaction`'s; installing it is this file's. The
572
638
  // planner touches no `ctx` at all, which is what lets the boundary
573
639
  // arithmetic be tested without a run.
640
+ if (salience) {
641
+ let openTasks: string[] | undefined
642
+ if (ctx.taskStore) {
643
+ try {
644
+ const tasks = await ctx.taskStore.list({ runId: ctx.runMgr.id })
645
+ openTasks = tasks
646
+ .filter((t) => t.status !== 'completed')
647
+ .map((t) => t.description)
648
+ .filter((d): d is string => typeof d === 'string' && d.length > 0)
649
+ } catch {
650
+ // The goal is measured without the plan items; a task store
651
+ // that cannot answer must not stop the pass.
652
+ }
653
+ }
654
+ const working = planSalienceWorkingSet({
655
+ messages: ctx.runMgr.messages,
656
+ config,
657
+ contextWindowTokens: budget,
658
+ estimatedTokens,
659
+ ...(openTasks ? { openTasks } : {}),
660
+ })
661
+ if (working.reclaimedTokens > 0) {
662
+ await commitToolResultClear(ctx, working, budget, window.source)
663
+ }
664
+ // Under the trigger, the working set was the whole pass: the summary
665
+ // path is for the trigger, not for the soft target.
666
+ if (
667
+ !options?.force &&
668
+ (estimatedTokens - working.reclaimedTokens) / budget < config.triggerThreshold
669
+ ) {
670
+ return
671
+ }
672
+ }
574
673
  const clearPlan = planCompaction({
575
674
  messages: ctx.runMgr.messages,
576
675
  config,
@@ -131,6 +131,8 @@ export interface IterationContext {
131
131
  * drained and no tool result is extended.
132
132
  */
133
133
  readonly steering?: SteeringChannel
134
+ /** Exit notices for the run's background jobs, drained into the next tool result. */
135
+ readonly jobNotices?: SteeringChannel
134
136
  readonly checkpointMgr: CheckpointManager
135
137
  readonly planManager: PlanManager
136
138
 
@@ -8,7 +8,7 @@ import {
8
8
  replaceProjectInstructionSnapshot,
9
9
  } from '../../project-instructions.js'
10
10
  import { attachRepeatNotice } from '../../repeat-call.js'
11
- import { attachSteering } from '../../steering.js'
11
+ import { attachNotice, attachSteering, formatJobNote } from '../../steering.js'
12
12
  import { type IterationContext, awaitDecisionDurably } from './context.js'
13
13
 
14
14
  interface VerificationAwareContext extends IterationContext {
@@ -97,18 +97,47 @@ export async function* runToolReview(
97
97
  }
98
98
  let toolCallSummaries = summariesFor(preparedBatch)
99
99
 
100
+ /**
101
+ * A call that has failed identically too many times in a row is answered
102
+ * with the tracker's refusal instead of being run — the one denial the
103
+ * tracker makes, on top of whatever the caller already denied.
104
+ */
105
+ const withRepeatRefusals = (denials?: ToolCallDenials): ToolCallDenials | undefined => {
106
+ const tracker = ctx.repeatCalls
107
+ if (!tracker) return denials
108
+ let merged: Map<string, string> | undefined
109
+ for (const summary of toolCallSummaries) {
110
+ if (denials?.has(summary.id)) continue
111
+ const refusal = tracker.refusal(summary.name, summary.input)
112
+ if (!refusal) continue
113
+ merged ??= new Map(denials ?? [])
114
+ merged.set(summary.id, refusal)
115
+ }
116
+ return merged ?? denials
117
+ }
118
+
100
119
  /** Executes the batch, answering every call, and appends the results. */
101
120
  const settle = async (denials?: ToolCallDenials): Promise<void> => {
102
121
  const startedAt = Date.now()
103
- const batch = await ctx.toolExecutor.executeBatch(response, denials, undefined, preparedBatch)
122
+ const batch = await ctx.toolExecutor.executeBatch(
123
+ response,
124
+ withRepeatRefusals(denials),
125
+ undefined,
126
+ preparedBatch,
127
+ )
104
128
  toolMs += Date.now() - startedAt
105
129
  executed = batch.results
106
- // Recorded AFTER execution and never before it: this advises, it does
107
- // not deny, so the call has already run and its real result is in the
108
- // batch. Wiring it ahead of `executeBatch` would make it a gate.
130
+ // Recorded AFTER execution, with the real result: the notice advises
131
+ // on the call that already ran, and the failure count is what the
132
+ // refusal above reads on the NEXT identical call.
109
133
  const notices = []
110
134
  for (const summary of toolCallSummaries) {
111
- const notice = ctx.repeatCalls?.record(summary.name, summary.input)
135
+ const outcome = batch.results.find((result) => result.toolCallId === summary.id)
136
+ const notice = ctx.repeatCalls?.record(
137
+ summary.name,
138
+ summary.input,
139
+ outcome ? { failed: outcome.isError === true } : undefined,
140
+ )
112
141
  if (notice) notices.push(notice)
113
142
  }
114
143
  // Guidance the host queued while this batch was running rides out on
@@ -116,7 +145,10 @@ export async function* runToolReview(
116
145
  // block must be answered by a `tool_result` with the same id, so a
117
146
  // user message wedged between them is rejected by the provider. Same
118
147
  // delivery a denial already uses, without the refusal.
119
- for (const msg of attachRepeatNotice(attachSteering(batch.messages, ctx.steering), notices)) {
148
+ for (const msg of attachRepeatNotice(
149
+ attachNotice(attachSteering(batch.messages, ctx.steering), ctx.jobNotices, formatJobNote),
150
+ notices,
151
+ )) {
120
152
  ctx.runMgr.pushMessage(msg)
121
153
  }
122
154
  // The complete tool-result batch is already in history before host policy
@@ -1,3 +1,4 @@
1
+ import { renderPins } from '../../../../compaction/serializer.js'
1
2
  import { NAMZU } from '../../../../constants/telemetry/index.js'
2
3
  import { createSystemMessage } from '../../../../types/message/index.js'
3
4
  import type { IterationContext } from './context.js'
@@ -37,22 +38,30 @@ export function isWorkingMemoryMessage(content: string | null | undefined): bool
37
38
  */
38
39
  export async function refreshWorkingMemory(ctx: IterationContext): Promise<void> {
39
40
  const provider = ctx.workingMemoryProvider
40
- if (!provider) return
41
+ // What the tools pinned joins the slot beside what the host provides: a
42
+ // pin exists to be in front of the model every iteration, and until this
43
+ // the working state reached the history only through a compaction
44
+ // summary. No provider and no pins leaves the history untouched.
45
+ const pinned = ctx.workingStateManager ? renderPins(ctx.workingStateManager.getState()) : null
46
+ if (!provider && !pinned) return
41
47
 
42
- let block: string
43
- try {
44
- block =
45
- (await provider({
46
- runId: ctx.runMgr.id,
47
- iteration: ctx.runMgr.currentIteration,
48
- })) ?? ''
49
- } catch (err) {
50
- ctx.log.warn('workingMemoryProvider failed; keeping prior slot', {
51
- [NAMZU.RUN_ID]: ctx.runMgr.id,
52
- 'exception.message': err instanceof Error ? err.message : String(err),
53
- })
54
- return
48
+ let block = ''
49
+ if (provider) {
50
+ try {
51
+ block =
52
+ (await provider({
53
+ runId: ctx.runMgr.id,
54
+ iteration: ctx.runMgr.currentIteration,
55
+ })) ?? ''
56
+ } catch (err) {
57
+ ctx.log.warn('workingMemoryProvider failed; keeping prior slot', {
58
+ [NAMZU.RUN_ID]: ctx.runMgr.id,
59
+ 'exception.message': err instanceof Error ? err.message : String(err),
60
+ })
61
+ return
62
+ }
55
63
  }
64
+ if (pinned) block = block.trim() ? `${block.trim()}\n\n${pinned}` : pinned
56
65
 
57
66
  const msgs = ctx.runMgr.messages
58
67
 
@@ -12,18 +12,39 @@ import type { PluginHookEvent, PluginHookResult } from '../../types/plugin/index
12
12
  export function applyLifecycleHookResults(
13
13
  event: PluginHookEvent,
14
14
  results: readonly PluginHookResult[],
15
- ): void {
15
+ ): string[] {
16
+ const annotations: string[] = []
16
17
  for (const result of results) {
17
18
  switch (result.action) {
18
19
  case 'continue':
19
20
  continue
21
+ case 'annotate':
22
+ if (event !== 'user_prompt_submit') {
23
+ throw new Error(
24
+ `Plugin hook ${event} returned 'annotate', which only user_prompt_submit accepts`,
25
+ )
26
+ }
27
+ if (result.text.trim().length > 0) annotations.push(result.text.trim())
28
+ continue
29
+ case 'skip':
30
+ // The one lifecycle event with a verdict: a hook may refuse the
31
+ // prompt before the model sees it, and the run ends there.
32
+ if (event === 'user_prompt_submit') {
33
+ throw new NamzuError({
34
+ code: 'plugin_error',
35
+ message: `Prompt blocked by hook: ${result.reason}`,
36
+ details: { event, blocked: true, reason: result.reason },
37
+ })
38
+ }
39
+ throw new Error(
40
+ `Plugin hook ${event} returned unsupported action 'skip' for a lifecycle event`,
41
+ )
20
42
  case 'error':
21
43
  throw new NamzuError({
22
44
  code: 'plugin_error',
23
45
  message: `Plugin hook ${event} reported error: ${result.message}`,
24
46
  details: { event },
25
47
  })
26
- case 'skip':
27
48
  case 'modify':
28
49
  case 'retry':
29
50
  case 'replace':
@@ -36,4 +57,5 @@ export function applyLifecycleHookResults(
36
57
  }
37
58
  }
38
59
  }
60
+ return annotations
39
61
  }
@@ -12,11 +12,18 @@ import { stableStringify } from './tool-grants.js'
12
12
  * regardless of whether anything is repeating and needs a human at the
13
13
  * other end.
14
14
  *
15
- * It advises; it never denies. A repeat is not necessarily wrong — polling
16
- * for a build to finish is the same call by design — and a tracker that
17
- * refused would break that case to fix a different one. What the model
18
- * lacks is not permission but the observation, which it cannot make about
19
- * itself: each turn it sees a history, not a count.
15
+ * It advises, and it refuses exactly one thing. A repeat is not
16
+ * necessarily wrong — polling for a build to finish is the same call by
17
+ * design so a repeat that keeps SUCCEEDING is only ever noticed. A repeat
18
+ * that keeps FAILING the same way is different: an operator watched a
19
+ * model ask a desktop it could not reach for a screenshot, read the same
20
+ * error, and ask again, for as long as the run was allowed to go on. After
21
+ * `refuseFailedAfter` consecutive identical failures the next identical
22
+ * call is answered with a refusal instead of being run, and the refusal
23
+ * says why. A success resets the count, so a poll that fails a few times
24
+ * before it succeeds is never touched. What the model lacks is not
25
+ * permission but the observation, which it cannot make about itself: each
26
+ * turn it sees a history, not a count.
20
27
  */
21
28
 
22
29
  /** Same key `ToolGrantSet` uses, so "the same call" means one thing here. */
@@ -29,11 +36,17 @@ export interface RepeatCallThresholds {
29
36
  readonly notifyAfter: number
30
37
  /** Repeats at which the wording escalates. */
31
38
  readonly escalateAfter: number
39
+ /**
40
+ * Consecutive identical FAILURES after which the next identical call is
41
+ * refused rather than run. A success in between resets the count.
42
+ */
43
+ readonly refuseFailedAfter: number
32
44
  }
33
45
 
34
46
  export const DEFAULT_REPEAT_THRESHOLDS: RepeatCallThresholds = {
35
47
  notifyAfter: 3,
36
48
  escalateAfter: 5,
49
+ refuseFailedAfter: 4,
37
50
  }
38
51
 
39
52
  export interface RepeatCallNotice {
@@ -52,17 +65,27 @@ export class RepeatCallTracker {
52
65
  /** Which keys have already been reported at which level, so one repeat
53
66
  * does not produce the same sentence on every subsequent turn. */
54
67
  private readonly announced = new Map<string, 'notice' | 'escalated'>()
68
+ /** Consecutive failures per key; a success deletes the entry. */
69
+ private readonly failures = new Map<string, number>()
55
70
 
56
71
  constructor(private readonly thresholds: RepeatCallThresholds = DEFAULT_REPEAT_THRESHOLDS) {}
57
72
 
58
73
  /**
59
74
  * Records one call and returns a notice when this is the repeat that
60
- * crosses a threshold, `undefined` otherwise.
75
+ * crosses a threshold, `undefined` otherwise. `outcome.failed` is what
76
+ * the refusal counts; a call recorded without an outcome counts as a
77
+ * repeat but never towards a refusal.
61
78
  */
62
- record(toolName: string, input: unknown): RepeatCallNotice | undefined {
79
+ record(
80
+ toolName: string,
81
+ input: unknown,
82
+ outcome?: { readonly failed: boolean },
83
+ ): RepeatCallNotice | undefined {
63
84
  const key = keyFor(toolName, input)
64
85
  const count = (this.counts.get(key) ?? 0) + 1
65
86
  this.counts.set(key, count)
87
+ if (outcome?.failed === true) this.failures.set(key, (this.failures.get(key) ?? 0) + 1)
88
+ else if (outcome?.failed === false) this.failures.delete(key)
66
89
 
67
90
  const already = this.announced.get(key)
68
91
  if (count >= this.thresholds.escalateAfter && already !== 'escalated') {
@@ -90,6 +113,18 @@ export class RepeatCallTracker {
90
113
  countOf(toolName: string, input: unknown): number {
91
114
  return this.counts.get(keyFor(toolName, input)) ?? 0
92
115
  }
116
+
117
+ /**
118
+ * The refusal for a call that has failed identically too many times in
119
+ * a row, or `undefined` when the call may run. Asked BEFORE execution;
120
+ * the refused call is still recorded afterwards, as a failure, so the
121
+ * refusal holds until the model changes something.
122
+ */
123
+ refusal(toolName: string, input: unknown): string | undefined {
124
+ const failed = this.failures.get(keyFor(toolName, input)) ?? 0
125
+ if (failed < this.thresholds.refuseFailedAfter) return undefined
126
+ return `Refused: \`${toolName}\` with these exact arguments has failed ${failed} times in a row in this run, with the same result each time. It will not be run again with these arguments. Change the arguments, use a different tool, or tell the user what is blocking you and stop.`
127
+ }
93
128
  }
94
129
 
95
130
  /**
@@ -2,6 +2,7 @@ import { type Span, SpanStatusCode } from '@opentelemetry/api'
2
2
  import type { PlanManager } from '../../manager/plan/lifecycle.js'
3
3
  import type { RunPersistence } from '../../manager/run/persistence.js'
4
4
  import { isCallerAbortError, isProviderRequestError } from '../../provider/errors.js'
5
+ import { TokenBudgetAdmissionError } from '../../provider/token-budget.js'
5
6
  import type { ActivityStore } from '../../store/activity/memory.js'
6
7
  import { GENAI, NAMZU } from '../../telemetry/attributes.js'
7
8
  import { explainError } from '../../types/errors/catalog.js'
@@ -85,6 +86,7 @@ export class ResultAssembler {
85
86
 
86
87
  await emitEvent({
87
88
  type: 'run_completed',
89
+ budget: runMgr.budget?.summary(),
88
90
  runId: runMgr.id,
89
91
  result: runMgr.getRun().result ?? '',
90
92
  // Read AFTER `markCompleted`, which is where a run that was stopped
@@ -133,6 +135,11 @@ export class ResultAssembler {
133
135
  yield* this.completeRun(rootSpan)
134
136
  return
135
137
  }
138
+ if (err instanceof TokenBudgetAdmissionError) {
139
+ runMgr.setStopReason('token_budget')
140
+ yield* this.completeRun(rootSpan)
141
+ return
142
+ }
136
143
  const errorMessage = toErrorMessage(err)
137
144
  // The classifier at the provider boundary already walked the cause
138
145
  // chain over status, errno and `Retry-After`, so a fully-populated
@@ -176,6 +183,7 @@ export class ResultAssembler {
176
183
 
177
184
  await emitEvent({
178
185
  type: 'run_paused',
186
+ budget: runMgr.budget?.summary(),
179
187
  runId: runMgr.id,
180
188
  checkpointId: resumeFrom,
181
189
  reason: errorMessage,
@@ -219,6 +227,7 @@ export class ResultAssembler {
219
227
 
220
228
  await emitEvent({
221
229
  type: 'run_failed',
230
+ budget: runMgr.budget?.summary(),
222
231
  runId: runMgr.id,
223
232
  error: errorMessage,
224
233
  failure,