@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,7 +1,10 @@
1
1
  import type { CompactionConfig } from '../config/runtime.js'
2
- import { CHARS_PER_TOKEN } from '../constants/limits.js'
3
2
  import type { Message } from '../types/message/index.js'
4
3
  import { findSafeTrimIndex } from './dangling.js'
4
+ import { buildGoal } from './salience/goal.js'
5
+ import { scoreMessages } from './salience/score.js'
6
+ import { type WorkingSetPlan, planWorkingSet } from './salience/working-set.js'
7
+ import { estimateMessageTokens, estimateMessagesTokens } from './token-estimate.js'
5
8
  import { clearStaleToolResults } from './tool-result-editing.js'
6
9
 
7
10
  /**
@@ -43,6 +46,8 @@ export type CompactionPlan =
43
46
  readonly kind: 'cleared'
44
47
  readonly messages: readonly Message[]
45
48
  readonly clearedCount: number
49
+ /** Assistant narrations cut to their first sentence by the salience pass. */
50
+ readonly stubbedCount?: number
46
51
  readonly charsReclaimed: number
47
52
  readonly reclaimedTokens: number
48
53
  readonly reliefWasEnough: boolean
@@ -86,24 +91,6 @@ export interface CompactionPlanInput {
86
91
  readonly skipToolResultClear?: boolean
87
92
  }
88
93
 
89
- /**
90
- * How many characters a message's content is worth.
91
- *
92
- * An image costs far fewer tokens than its base64 length divided by four —
93
- * but under-counting it to zero is the worse error: it let a run full of
94
- * screenshots read as an empty context.
95
- */
96
- function measureContentChars(content: unknown): number {
97
- if (typeof content === 'string') return content.length
98
- if (!Array.isArray(content)) return 0
99
- let total = 0
100
- for (const block of content as readonly Record<string, unknown>[]) {
101
- if (block.type === 'text' && typeof block.text === 'string') total += block.text.length
102
- else if (block.type === 'image' && typeof block.data === 'string') total += block.data.length
103
- }
104
- return total
105
- }
106
-
107
94
  /**
108
95
  * The last index whose tail fits in `budgetTokens`, walking backwards.
109
96
  *
@@ -125,7 +112,7 @@ export function naiveKeepStartByTokens(messages: readonly Message[], budgetToken
125
112
  let tokens = 0
126
113
  let start = messages.length
127
114
  for (let index = messages.length - 1; index >= 0; index--) {
128
- const cost = Math.ceil(measureContentChars(messages[index]?.content) / CHARS_PER_TOKEN)
115
+ const cost = estimateMessageTokens(messages[index] as Message)
129
116
  // Checked BEFORE adding, so the boundary never includes a message
130
117
  // that pushes the tail over. Adding first and trimming after would
131
118
  // admit one oversized message on every run.
@@ -136,6 +123,49 @@ export function naiveKeepStartByTokens(messages: readonly Message[], budgetToken
136
123
  return start
137
124
  }
138
125
 
126
+ /**
127
+ * The salience pass: score every message and evict the least salient
128
+ * until the context is under `softTarget`. Returned as a `cleared` plan
129
+ * so the phase commits it the way it commits the stale-result pass; the
130
+ * summary path runs after it only when the trigger threshold is still
131
+ * exceeded.
132
+ */
133
+ /** Where the salience pass holds the context, as a fraction of the window. */
134
+ export const DEFAULT_SOFT_TARGET = 0.5
135
+
136
+ export function planSalienceWorkingSet(input: {
137
+ readonly messages: readonly Message[]
138
+ readonly config: CompactionConfig
139
+ readonly contextWindowTokens: number
140
+ readonly estimatedTokens: number
141
+ readonly openTasks?: readonly string[]
142
+ }): Extract<CompactionPlan, { kind: 'cleared' }> & { readonly working: WorkingSetPlan } {
143
+ const { config, estimatedTokens, contextWindowTokens: budget } = input
144
+ const goal = buildGoal(input.messages, {
145
+ ...(input.openTasks ? { openTasks: input.openTasks } : {}),
146
+ })
147
+ const scored = scoreMessages(input.messages, {
148
+ goal,
149
+ keepRecentMessages: config.keepRecentMessages,
150
+ })
151
+ const working = planWorkingSet(input.messages, scored, {
152
+ estimatedTokens,
153
+ targetTokens: Math.floor(budget * (config.softTarget ?? DEFAULT_SOFT_TARGET)),
154
+ minToolResultChars: config.minToolResultCharsToClear,
155
+ ...(config.preserveToolResultsFrom ? { preserveTools: config.preserveToolResultsFrom } : {}),
156
+ })
157
+ return {
158
+ kind: 'cleared',
159
+ messages: working.messages,
160
+ clearedCount: working.clearedCount,
161
+ stubbedCount: working.stubbedCount,
162
+ charsReclaimed: working.charsReclaimed,
163
+ reclaimedTokens: working.reclaimedTokens,
164
+ reliefWasEnough: (estimatedTokens - working.reclaimedTokens) / budget < config.triggerThreshold,
165
+ working,
166
+ }
167
+ }
168
+
139
169
  export function planCompaction(input: CompactionPlanInput): CompactionPlan {
140
170
  const { config, estimatedTokens, contextWindowTokens: budget } = input
141
171
 
@@ -151,7 +181,8 @@ export function planCompaction(input: CompactionPlanInput): CompactionPlan {
151
181
  })
152
182
 
153
183
  if (edit.clearedCount > 0) {
154
- const reclaimedTokens = Math.ceil(edit.charsReclaimed / CHARS_PER_TOKEN)
184
+ const reclaimedTokens =
185
+ estimateMessagesTokens(input.messages) - estimateMessagesTokens(edit.messages)
155
186
  // NOT on a forced pass. A forced pass runs because the provider
156
187
  // REJECTED the prompt as too long, which is a measurement — and
157
188
  // answering it with the same estimate the provider just refuted
@@ -0,0 +1,72 @@
1
+ /**
2
+ * BM25 over the run's own messages.
3
+ *
4
+ * The corpus is small — a few hundred documents at most — so the index
5
+ * is rebuilt from term frequencies each pass rather than maintained
6
+ * incrementally; the arithmetic is the cost of a few string splits. The
7
+ * constants are the textbook ones (k1 = 1.2, b = 0.75). What matters
8
+ * here is not ranking quality against a web corpus but that a message
9
+ * mentioning the goal's identifiers outscores one that does not, and
10
+ * that a term every message contains (the run's own file name, say)
11
+ * stops counting.
12
+ */
13
+
14
+ import { termFrequencies, tokenize } from './tokenize.js'
15
+
16
+ export interface Bm25Document {
17
+ readonly tf: ReadonlyMap<string, number>
18
+ readonly length: number
19
+ }
20
+
21
+ export interface Bm25Index {
22
+ readonly documents: readonly Bm25Document[]
23
+ readonly documentFrequency: ReadonlyMap<string, number>
24
+ readonly averageLength: number
25
+ }
26
+
27
+ const K1 = 1.2
28
+ const B = 0.75
29
+
30
+ export function indexDocument(text: string): Bm25Document {
31
+ const tokens = tokenize(text)
32
+ return { tf: termFrequencies(tokens), length: tokens.length }
33
+ }
34
+
35
+ export function buildIndex(documents: readonly Bm25Document[]): Bm25Index {
36
+ const documentFrequency = new Map<string, number>()
37
+ let total = 0
38
+ for (const doc of documents) {
39
+ total += doc.length
40
+ for (const term of doc.tf.keys()) {
41
+ documentFrequency.set(term, (documentFrequency.get(term) ?? 0) + 1)
42
+ }
43
+ }
44
+ return {
45
+ documents,
46
+ documentFrequency,
47
+ averageLength: documents.length === 0 ? 0 : total / documents.length,
48
+ }
49
+ }
50
+
51
+ /** BM25 score of one document for a query given as tokens. */
52
+ export function bm25Score(
53
+ index: Bm25Index,
54
+ doc: Bm25Document,
55
+ queryTokens: readonly string[],
56
+ ): number {
57
+ if (doc.length === 0 || index.documents.length === 0) return 0
58
+ const n = index.documents.length
59
+ let score = 0
60
+ const seen = new Set<string>()
61
+ for (const term of queryTokens) {
62
+ if (seen.has(term)) continue
63
+ seen.add(term)
64
+ const tf = doc.tf.get(term)
65
+ if (!tf) continue
66
+ const df = index.documentFrequency.get(term) ?? 0
67
+ const idf = Math.log(1 + (n - df + 0.5) / (df + 0.5))
68
+ const norm = tf + K1 * (1 - B + (B * doc.length) / Math.max(1, index.averageLength))
69
+ score += idf * ((tf * (K1 + 1)) / norm)
70
+ }
71
+ return score
72
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * The goal vector: what "relevant" is measured against.
3
+ *
4
+ * Not the whole history — that would make every message relevant to
5
+ * itself — but the four things that say what the run is for right now:
6
+ * the first user message (the task), the most recent user turns (the
7
+ * requirements as they were refined), the open items of the task list
8
+ * when the run keeps one, and the latest assistant text (its stated
9
+ * intent). Weighted by repetition rather than a coefficient: the task
10
+ * statement is included twice so a run that has drifted into detail is
11
+ * still scored against what it was asked to do.
12
+ */
13
+
14
+ import type { Message } from '../../types/message/index.js'
15
+
16
+ export interface GoalSources {
17
+ /** Titles of task-list items not yet completed, when the host keeps a task store. */
18
+ readonly openTasks?: readonly string[]
19
+ /** How many of the latest user turns count as live requirements. */
20
+ readonly recentUserTurns?: number
21
+ }
22
+
23
+ export function buildGoal(messages: readonly Message[], sources: GoalSources = {}): string {
24
+ const users = messages.filter(
25
+ (m): m is Extract<Message, { role: 'user' }> =>
26
+ m.role === 'user' && typeof m.content === 'string',
27
+ )
28
+ const first = users[0]?.content ?? ''
29
+ const recent = users
30
+ .slice(-(sources.recentUserTurns ?? 3))
31
+ .map((m) => m.content)
32
+ .filter((text) => text !== first)
33
+ let latestIntent = ''
34
+ for (let i = messages.length - 1; i >= 0; i -= 1) {
35
+ const m = messages[i] as Message
36
+ if (m.role === 'assistant' && typeof m.content === 'string' && m.content.trim().length > 0) {
37
+ latestIntent = m.content
38
+ break
39
+ }
40
+ }
41
+ return [first, first, ...recent, ...(sources.openTasks ?? []), latestIntent]
42
+ .filter((part) => part.length > 0)
43
+ .join('\n')
44
+ }
@@ -0,0 +1,19 @@
1
+ export { buildGoal, type GoalSources } from './goal.js'
2
+ export {
3
+ DEFAULT_SALIENCE_CONFIG,
4
+ DEFAULT_SALIENCE_WEIGHTS,
5
+ type ProtectedReason,
6
+ type SalienceConfig,
7
+ type SalienceWeights,
8
+ type ScoreOptions,
9
+ type ScoredMessage,
10
+ messageText,
11
+ scoreMessages,
12
+ } from './score.js'
13
+ export {
14
+ type WorkingSetAction,
15
+ type WorkingSetOptions,
16
+ type WorkingSetPlan,
17
+ isStubbedNarration,
18
+ planWorkingSet,
19
+ } from './working-set.js'
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Near-duplicate detection with MinHash over word shingles.
3
+ *
4
+ * Two tool results are rarely byte-identical — a timestamp, a duration,
5
+ * a line number moves — and still the same output. Three-word shingles
6
+ * hashed 64 ways give a Jaccard estimate that is stable against those
7
+ * edits and cheap enough to compare every message against every other
8
+ * once per pass at the sizes a run reaches. Hashing is FNV-1a with a
9
+ * per-slot seed; nothing here needs to be cryptographic, only consistent
10
+ * within a process.
11
+ */
12
+
13
+ const HASHES = 64
14
+ const SHINGLE = 3
15
+
16
+ function fnv1a(text: string, seed: number): number {
17
+ let hash = (0x811c9dc5 ^ seed) >>> 0
18
+ for (let i = 0; i < text.length; i += 1) {
19
+ hash ^= text.charCodeAt(i)
20
+ hash = Math.imul(hash, 0x01000193) >>> 0
21
+ }
22
+ return hash
23
+ }
24
+
25
+ /** The signature of `tokens`; an empty signature for fewer than one shingle. */
26
+ export function minhash(tokens: readonly string[]): Uint32Array {
27
+ const signature = new Uint32Array(HASHES).fill(0xffffffff)
28
+ if (tokens.length < SHINGLE) {
29
+ if (tokens.length === 0) return signature
30
+ const single = tokens.join(' ')
31
+ for (let slot = 0; slot < HASHES; slot += 1) signature[slot] = fnv1a(single, slot)
32
+ return signature
33
+ }
34
+ for (let i = 0; i + SHINGLE <= tokens.length; i += 1) {
35
+ const shingle = `${tokens[i]} ${tokens[i + 1]} ${tokens[i + 2]}`
36
+ for (let slot = 0; slot < HASHES; slot += 1) {
37
+ const h = fnv1a(shingle, slot)
38
+ if (h < (signature[slot] as number)) signature[slot] = h
39
+ }
40
+ }
41
+ return signature
42
+ }
43
+
44
+ /** Estimated Jaccard similarity of two signatures, 0..1. */
45
+ export function similarity(a: Uint32Array, b: Uint32Array): number {
46
+ let same = 0
47
+ for (let slot = 0; slot < HASHES; slot += 1) if (a[slot] === b[slot]) same += 1
48
+ return same / HASHES
49
+ }
50
+
51
+ export function isEmptySignature(signature: Uint32Array): boolean {
52
+ return signature.every((h) => h === 0xffffffff)
53
+ }
@@ -0,0 +1,305 @@
1
+ /**
2
+ * Salience: how much the next step depends on each message.
3
+ *
4
+ * The compaction pass chose what to keep by position — the floor, the
5
+ * last few turns, the last few tool results — and a fact stated in the
6
+ * middle of a long run aged out at the same rate as chatter. This gives
7
+ * every message a number instead, from four things the kernel can
8
+ * observe without a model:
9
+ *
10
+ * recency how many messages ago, decayed with a half-life;
11
+ * relevance BM25 against the goal — the task, the requirements, the
12
+ * open plan items, the latest intent;
13
+ * utility whether it was USED: a tool result whose paths and
14
+ * identifiers reappear in a later tool input or assistant
15
+ * turn; an instruction from the user;
16
+ * redundancy whether a later message says the same thing — a repeated
17
+ * read, the same error twice — so the older copy yields.
18
+ *
19
+ * What no score may cross is stated as `protected`: the leading system
20
+ * run, `retain` markers with the turn they pull in, the most recent
21
+ * turns, and the other half of a tool-call pair. Pure, like `plan.ts`:
22
+ * no run, no logger, no provider, so it can be asked without one.
23
+ */
24
+
25
+ import type { AssistantMessage, Message, ToolMessage } from '../../types/message/index.js'
26
+ import { findRetainedIndices } from '../retention.js'
27
+ import { estimateMessageTokens } from '../token-estimate.js'
28
+ import { type Bm25Document, bm25Score, buildIndex, indexDocument } from './bm25.js'
29
+ import { isEmptySignature, minhash, similarity } from './minhash.js'
30
+ import { tokenize } from './tokenize.js'
31
+
32
+ export interface SalienceWeights {
33
+ readonly recency: number
34
+ readonly relevance: number
35
+ readonly utility: number
36
+ readonly redundancy: number
37
+ }
38
+
39
+ export const DEFAULT_SALIENCE_WEIGHTS: SalienceWeights = {
40
+ recency: 1,
41
+ relevance: 1,
42
+ utility: 1,
43
+ redundancy: 1,
44
+ }
45
+
46
+ export interface SalienceConfig {
47
+ /** Messages after which recency has halved. */
48
+ readonly halfLifeMessages: number
49
+ /** Estimated Jaccard at or above which two messages are the same thing. */
50
+ readonly duplicateThreshold: number
51
+ readonly weights: SalienceWeights
52
+ }
53
+
54
+ export const DEFAULT_SALIENCE_CONFIG: SalienceConfig = {
55
+ halfLifeMessages: 12,
56
+ duplicateThreshold: 0.8,
57
+ weights: DEFAULT_SALIENCE_WEIGHTS,
58
+ }
59
+
60
+ export type ProtectedReason = 'system-floor' | 'retain' | 'recent' | 'pair'
61
+
62
+ export interface ScoredMessage {
63
+ readonly index: number
64
+ readonly role: Message['role']
65
+ /** Estimated tokens of the message, including rich content and tool inputs. */
66
+ readonly tokens: number
67
+ readonly recency: number
68
+ readonly relevance: number
69
+ readonly utility: number
70
+ readonly redundancy: number
71
+ /** The weighted sum; meaningful only relative to the other messages of the same pass. */
72
+ readonly salience: number
73
+ readonly protected: ProtectedReason | null
74
+ }
75
+
76
+ export interface ScoreOptions {
77
+ /** The goal vector as text: task statement, requirements, open plan items, latest intent. */
78
+ readonly goal: string
79
+ /** How many trailing messages are protected as recent. */
80
+ readonly keepRecentMessages: number
81
+ readonly config?: Partial<SalienceConfig>
82
+ }
83
+
84
+ /** The model-visible text of a message, with an assistant's tool inputs. */
85
+ export function messageText(message: Message): string {
86
+ if (message.role === 'tool') {
87
+ return typeof message.content === 'string'
88
+ ? message.content
89
+ : message.content.flatMap((block) => (block.type === 'text' ? [block.text] : [])).join('\n')
90
+ }
91
+ const parts: string[] = []
92
+ if (typeof message.content === 'string') parts.push(message.content)
93
+ if (message.role === 'assistant') {
94
+ for (const call of (message as AssistantMessage).toolCalls ?? []) {
95
+ parts.push(call.function.name, call.function.arguments)
96
+ }
97
+ }
98
+ return parts.join('\n')
99
+ }
100
+
101
+ function hasRichContent(message: Message): boolean {
102
+ return (
103
+ (message.role === 'user' && (message.attachments?.length ?? 0) > 0) ||
104
+ (message.role === 'tool' &&
105
+ typeof message.content !== 'string' &&
106
+ message.content.some((block) => block.type !== 'text'))
107
+ )
108
+ }
109
+
110
+ const isAssistantWithCalls = (m: Message): m is AssistantMessage =>
111
+ m.role === 'assistant' && Array.isArray((m as AssistantMessage).toolCalls)
112
+
113
+ /** Tokens that look like something a later turn could cite: paths, identifiers, dotted keys. */
114
+ function citable(tokens: readonly string[]): Set<string> {
115
+ const out = new Set<string>()
116
+ for (const token of tokens) {
117
+ if (token.length >= 5 || token.includes('/') || token.includes('.')) out.add(token)
118
+ }
119
+ return out
120
+ }
121
+
122
+ export function scoreMessages(
123
+ messages: readonly Message[],
124
+ options: ScoreOptions,
125
+ ): ScoredMessage[] {
126
+ const config: SalienceConfig = {
127
+ ...DEFAULT_SALIENCE_CONFIG,
128
+ ...options.config,
129
+ weights: { ...DEFAULT_SALIENCE_WEIGHTS, ...options.config?.weights },
130
+ }
131
+ const n = messages.length
132
+ const texts = messages.map(messageText)
133
+ const richContent = messages.map(hasRichContent)
134
+ const tokenLists = texts.map(tokenize)
135
+ const documents: Bm25Document[] = texts.map(indexDocument)
136
+ const index = buildIndex(documents)
137
+ const goalTokens = tokenize(options.goal)
138
+
139
+ // Relevance, normalised to the best message of the pass so weights mean
140
+ // the same thing in a short run and a long one.
141
+ // Normalised to the best message the pass could evict, not to the user
142
+ // turn that stated the goal: that turn matches the goal by definition,
143
+ // and measured against it every result reads as barely relevant.
144
+ const rawRelevance = documents.map((doc) => bm25Score(index, doc, goalTokens))
145
+ // Nor to an assistant turn that only issued a call: its arguments echo
146
+ // the goal's path in a dozen tokens, which BM25 scores above the
147
+ // four-thousand-token result that actually holds the file.
148
+ const maxRelevance = Math.max(
149
+ 0,
150
+ ...rawRelevance.filter((_, i) => {
151
+ const m = messages[i] as Message
152
+ return m.role === 'tool' || (m.role === 'assistant' && !isAssistantWithCalls(m))
153
+ }),
154
+ )
155
+
156
+ // Citation index: everything a LATER assistant turn or tool input names.
157
+ // Built once, suffix-wise, so each message asks "does anything after me
158
+ // cite my identifiers" in one lookup.
159
+ const citedAfter: Set<string>[] = new Array(n)
160
+ let running = new Set<string>()
161
+ for (let i = n - 1; i >= 0; i -= 1) {
162
+ citedAfter[i] = running
163
+ const message = messages[i] as Message
164
+ if (message.role === 'assistant' || message.role === 'user') {
165
+ running = new Set([...running, ...citable(tokenLists[i] as string[])])
166
+ }
167
+ }
168
+
169
+ // Redundancy: the highest similarity to any later message of the same
170
+ // role, and a full demotion when a later assistant turn repeats this
171
+ // message's tool call exactly.
172
+ const signatures = tokenLists.map(minhash)
173
+ const callKeys = messages.map((m) =>
174
+ isAssistantWithCalls(m)
175
+ ? (m.toolCalls ?? []).map((c) => `${c.function.name}:${c.function.arguments}`)
176
+ : [],
177
+ )
178
+ const laterCallKeys: Set<string>[] = new Array(n)
179
+ let calls = new Set<string>()
180
+ for (let i = n - 1; i >= 0; i -= 1) {
181
+ laterCallKeys[i] = calls
182
+ if ((callKeys[i] as string[]).length > 0)
183
+ calls = new Set([...calls, ...(callKeys[i] as string[])])
184
+ }
185
+
186
+ // Protection.
187
+ const protectedBy: (ProtectedReason | null)[] = new Array(n).fill(null)
188
+ let floorEnd = 0
189
+ while (floorEnd < n && messages[floorEnd]?.role === 'system') {
190
+ protectedBy[floorEnd] = 'system-floor'
191
+ floorEnd += 1
192
+ }
193
+ for (const i of findRetainedIndices(messages))
194
+ if (protectedBy[i] === null) protectedBy[i] = 'retain'
195
+ for (let i = Math.max(floorEnd, n - options.keepRecentMessages); i < n; i += 1) {
196
+ if (protectedBy[i] === null) protectedBy[i] = 'recent'
197
+ }
198
+ // A protected half of a pair protects the other half.
199
+ for (let i = 0; i < n; i += 1) {
200
+ const message = messages[i] as Message
201
+ if (!isAssistantWithCalls(message) || protectedBy[i] === null) continue
202
+ const ids = new Set((message.toolCalls ?? []).map((c) => c.id))
203
+ for (let j = i + 1; j < n && ids.size > 0; j += 1) {
204
+ const candidate = messages[j] as Message
205
+ if (candidate.role !== 'tool') {
206
+ if (candidate.role === 'assistant') break
207
+ continue
208
+ }
209
+ if (ids.has((candidate as ToolMessage).toolCallId)) {
210
+ ids.delete((candidate as ToolMessage).toolCallId)
211
+ if (protectedBy[j] === null) protectedBy[j] = 'pair'
212
+ }
213
+ }
214
+ }
215
+ for (let j = n - 1; j >= 0; j -= 1) {
216
+ const message = messages[j] as Message
217
+ if (message.role !== 'tool' || protectedBy[j] === null) continue
218
+ const id = (message as ToolMessage).toolCallId
219
+ for (let i = j - 1; i >= 0; i -= 1) {
220
+ const candidate = messages[i] as Message
221
+ if (isAssistantWithCalls(candidate) && (candidate.toolCalls ?? []).some((c) => c.id === id)) {
222
+ if (protectedBy[i] === null) protectedBy[i] = 'pair'
223
+ break
224
+ }
225
+ }
226
+ }
227
+
228
+ const scored: ScoredMessage[] = []
229
+ for (let i = 0; i < n; i += 1) {
230
+ const message = messages[i] as Message
231
+ const distance = n - 1 - i
232
+ const recency = 2 ** (-distance / Math.max(1, config.halfLifeMessages))
233
+ const relevance = maxRelevance > 0 ? (rawRelevance[i] as number) / maxRelevance : 0
234
+
235
+ let utility = 0
236
+ if (message.role === 'user') {
237
+ // An instruction is used by everything after it; an acknowledgment
238
+ // ("ok, go on") is not an instruction. The difference is whether it
239
+ // names anything or says more than a few words.
240
+ const tokens = tokenLists[i] as string[]
241
+ utility = citable(tokens).size > 0 || tokens.length >= 6 ? 1 : 0.2
242
+ } else if (message.role === 'tool') {
243
+ // Used is used: one identifier from this result named by a later
244
+ // turn is the evidence, and a count would let the recency of
245
+ // everything after it outvote the one result the run came back
246
+ // for. The eval that placed the account id deep in an early dump
247
+ // and cited it later watched the salience pass clear it under a
248
+ // thirds rule.
249
+ const mine = citable(tokenLists[i] as string[])
250
+ let hits = 0
251
+ for (const token of mine) if ((citedAfter[i] as Set<string>).has(token)) hits += 1
252
+ utility = hits > 0 ? 1 : 0
253
+ } else if (isAssistantWithCalls(message)) utility = 0.5
254
+
255
+ let redundancy = 0
256
+ const signature = signatures[i] as Uint32Array
257
+ // A caption or a repeated call cannot prove that two screenshots or
258
+ // documents contain the same evidence. The lexical scorer has no
259
+ // access to their meaning, so it must not call those messages duplicates.
260
+ if (!richContent[i] && !isEmptySignature(signature)) {
261
+ for (let j = i + 1; j < n; j += 1) {
262
+ if (richContent[j] || (messages[j] as Message).role !== message.role) continue
263
+ const sim = similarity(signature, signatures[j] as Uint32Array)
264
+ if (sim > redundancy) redundancy = sim
265
+ }
266
+ }
267
+ if (redundancy < config.duplicateThreshold) redundancy = redundancy >= 0.5 ? redundancy : 0
268
+ else redundancy = 1
269
+ if (message.role === 'tool' && !richContent[i]) {
270
+ // The result of a call a later turn repeats exactly: the newer
271
+ // result is the one that counts.
272
+ for (let k = i - 1; k >= 0; k -= 1) {
273
+ const producer = messages[k] as Message
274
+ if (!isAssistantWithCalls(producer)) continue
275
+ const call = (producer.toolCalls ?? []).find(
276
+ (c) => c.id === (message as ToolMessage).toolCallId,
277
+ )
278
+ if (call) {
279
+ const key = `${call.function.name}:${call.function.arguments}`
280
+ if ((laterCallKeys[i] as Set<string>).has(key)) redundancy = 1
281
+ break
282
+ }
283
+ }
284
+ }
285
+
286
+ const w = config.weights
287
+ const salience =
288
+ w.recency * recency +
289
+ w.relevance * relevance +
290
+ w.utility * utility -
291
+ w.redundancy * redundancy
292
+ scored.push({
293
+ index: i,
294
+ role: message.role,
295
+ tokens: estimateMessageTokens(message),
296
+ recency,
297
+ relevance,
298
+ utility,
299
+ redundancy,
300
+ salience,
301
+ protected: protectedBy[i] as ProtectedReason | null,
302
+ })
303
+ }
304
+ return scored
305
+ }