agentfootprint 7.16.0 → 7.18.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 (295) hide show
  1. package/AGENTS.md +1 -1
  2. package/CLAUDE.md +2 -2
  3. package/ai-instructions/claude-code/SKILL.md +1 -1
  4. package/dist/conventions.js +8 -6
  5. package/dist/conventions.js.map +1 -1
  6. package/dist/core/Agent.js +81 -27
  7. package/dist/core/Agent.js.map +1 -1
  8. package/dist/core/RunnerBase.js +16 -1
  9. package/dist/core/RunnerBase.js.map +1 -1
  10. package/dist/core/agent/AgentBuilder.js +209 -43
  11. package/dist/core/agent/AgentBuilder.js.map +1 -1
  12. package/dist/core/agent/buildAgentChart.js +8 -8
  13. package/dist/core/agent/buildAgentChart.js.map +1 -1
  14. package/dist/core/agent/buildDynamicAgentChart.js +6 -6
  15. package/dist/core/agent/buildDynamicAgentChart.js.map +1 -1
  16. package/dist/core/agent/middleware/errors.js +54 -0
  17. package/dist/core/agent/middleware/errors.js.map +1 -0
  18. package/dist/core/agent/middleware/index.js +23 -0
  19. package/dist/core/agent/middleware/index.js.map +1 -0
  20. package/dist/core/agent/middleware/ledger.js +61 -0
  21. package/dist/core/agent/middleware/ledger.js.map +1 -0
  22. package/dist/core/agent/middleware/outcomes.js +66 -0
  23. package/dist/core/agent/middleware/outcomes.js.map +1 -0
  24. package/dist/core/agent/middleware/runChain.js +144 -0
  25. package/dist/core/agent/middleware/runChain.js.map +1 -0
  26. package/dist/core/agent/middleware/types.js +41 -0
  27. package/dist/core/agent/middleware/types.js.map +1 -0
  28. package/dist/core/agent/stages/prepareFinal.js +10 -0
  29. package/dist/core/agent/stages/prepareFinal.js.map +1 -1
  30. package/dist/core/agent/stages/route.js +62 -1
  31. package/dist/core/agent/stages/route.js.map +1 -1
  32. package/dist/core/agent/stages/seed.js +130 -85
  33. package/dist/core/agent/stages/seed.js.map +1 -1
  34. package/dist/core/agent/stages/toolCalls.js +195 -8
  35. package/dist/core/agent/stages/toolCalls.js.map +1 -1
  36. package/dist/core/agent/stages/window.js +141 -0
  37. package/dist/core/agent/stages/window.js.map +1 -0
  38. package/dist/core/agent/window/errors.js.map +1 -0
  39. package/dist/core/agent/window/index.js +36 -0
  40. package/dist/core/agent/window/index.js.map +1 -0
  41. package/dist/core/agent/window/notice.js +57 -0
  42. package/dist/core/agent/window/notice.js.map +1 -0
  43. package/dist/core/agent/window/options.js +93 -0
  44. package/dist/core/agent/window/options.js.map +1 -0
  45. package/dist/core/agent/window/removal.js +45 -0
  46. package/dist/core/agent/window/removal.js.map +1 -0
  47. package/dist/core/agent/window/strategies/drop.js +106 -0
  48. package/dist/core/agent/window/strategies/drop.js.map +1 -0
  49. package/dist/core/agent/window/strategies/slidingWindow.js +87 -0
  50. package/dist/core/agent/window/strategies/slidingWindow.js.map +1 -0
  51. package/dist/core/agent/window/strategies/summarizeOldest.js +178 -0
  52. package/dist/core/agent/window/strategies/summarizeOldest.js.map +1 -0
  53. package/dist/core/agent/window/strategies/tokenBudget.js +95 -0
  54. package/dist/core/agent/window/strategies/tokenBudget.js.map +1 -0
  55. package/dist/core/agent/window/strategy.js +42 -0
  56. package/dist/core/agent/window/strategy.js.map +1 -0
  57. package/dist/core/agent/window/summarize.js.map +1 -0
  58. package/dist/core/agent/{compaction → window}/turns.js +50 -28
  59. package/dist/core/agent/window/turns.js.map +1 -0
  60. package/dist/core/agent/window/types.js +23 -0
  61. package/dist/core/agent/window/types.js.map +1 -0
  62. package/dist/core/pause.js +19 -1
  63. package/dist/core/pause.js.map +1 -1
  64. package/dist/esm/conventions.d.ts +8 -6
  65. package/dist/esm/conventions.js +8 -6
  66. package/dist/esm/conventions.js.map +1 -1
  67. package/dist/esm/core/Agent.d.ts +14 -6
  68. package/dist/esm/core/Agent.js +82 -28
  69. package/dist/esm/core/Agent.js.map +1 -1
  70. package/dist/esm/core/RunnerBase.js +16 -1
  71. package/dist/esm/core/RunnerBase.js.map +1 -1
  72. package/dist/esm/core/agent/AgentBuilder.d.ts +157 -4
  73. package/dist/esm/core/agent/AgentBuilder.js +209 -43
  74. package/dist/esm/core/agent/AgentBuilder.js.map +1 -1
  75. package/dist/esm/core/agent/buildAgentChart.d.ts +16 -9
  76. package/dist/esm/core/agent/buildAgentChart.js +8 -8
  77. package/dist/esm/core/agent/buildAgentChart.js.map +1 -1
  78. package/dist/esm/core/agent/buildDynamicAgentChart.js +6 -6
  79. package/dist/esm/core/agent/buildDynamicAgentChart.js.map +1 -1
  80. package/dist/esm/core/agent/middleware/errors.d.ts +51 -0
  81. package/dist/esm/core/agent/middleware/errors.js +50 -0
  82. package/dist/esm/core/agent/middleware/errors.js.map +1 -0
  83. package/dist/esm/core/agent/middleware/index.d.ts +16 -0
  84. package/dist/esm/core/agent/middleware/index.js +16 -0
  85. package/dist/esm/core/agent/middleware/index.js.map +1 -0
  86. package/dist/esm/core/agent/middleware/ledger.d.ts +40 -0
  87. package/dist/esm/core/agent/middleware/ledger.js +57 -0
  88. package/dist/esm/core/agent/middleware/ledger.js.map +1 -0
  89. package/dist/esm/core/agent/middleware/outcomes.d.ts +45 -0
  90. package/dist/esm/core/agent/middleware/outcomes.js +60 -0
  91. package/dist/esm/core/agent/middleware/outcomes.js.map +1 -0
  92. package/dist/esm/core/agent/middleware/runChain.d.ts +104 -0
  93. package/dist/esm/core/agent/middleware/runChain.js +139 -0
  94. package/dist/esm/core/agent/middleware/runChain.js.map +1 -0
  95. package/dist/esm/core/agent/middleware/types.d.ts +191 -0
  96. package/dist/esm/core/agent/middleware/types.js +40 -0
  97. package/dist/esm/core/agent/middleware/types.js.map +1 -0
  98. package/dist/esm/core/agent/stages/prepareFinal.d.ts +10 -0
  99. package/dist/esm/core/agent/stages/prepareFinal.js +10 -0
  100. package/dist/esm/core/agent/stages/prepareFinal.js.map +1 -1
  101. package/dist/esm/core/agent/stages/route.d.ts +29 -0
  102. package/dist/esm/core/agent/stages/route.js +60 -0
  103. package/dist/esm/core/agent/stages/route.js.map +1 -1
  104. package/dist/esm/core/agent/stages/seed.d.ts +16 -1
  105. package/dist/esm/core/agent/stages/seed.js +130 -85
  106. package/dist/esm/core/agent/stages/seed.js.map +1 -1
  107. package/dist/esm/core/agent/stages/toolCalls.d.ts +23 -0
  108. package/dist/esm/core/agent/stages/toolCalls.js +195 -8
  109. package/dist/esm/core/agent/stages/toolCalls.js.map +1 -1
  110. package/dist/esm/core/agent/stages/window.d.ts +63 -0
  111. package/dist/esm/core/agent/stages/window.js +137 -0
  112. package/dist/esm/core/agent/stages/window.js.map +1 -0
  113. package/dist/esm/core/agent/types.d.ts +33 -8
  114. package/dist/esm/core/agent/window/errors.js.map +1 -0
  115. package/dist/esm/core/agent/window/index.d.ts +27 -0
  116. package/dist/esm/core/agent/window/index.js +25 -0
  117. package/dist/esm/core/agent/window/index.js.map +1 -0
  118. package/dist/esm/core/agent/window/notice.d.ts +46 -0
  119. package/dist/esm/core/agent/window/notice.js +52 -0
  120. package/dist/esm/core/agent/window/notice.js.map +1 -0
  121. package/dist/esm/core/agent/window/options.d.ts +33 -0
  122. package/dist/esm/core/agent/window/options.js +87 -0
  123. package/dist/esm/core/agent/window/options.js.map +1 -0
  124. package/dist/esm/core/agent/window/removal.d.ts +22 -0
  125. package/dist/esm/core/agent/window/removal.js +40 -0
  126. package/dist/esm/core/agent/window/removal.js.map +1 -0
  127. package/dist/esm/core/agent/window/strategies/drop.d.ts +54 -0
  128. package/dist/esm/core/agent/window/strategies/drop.js +102 -0
  129. package/dist/esm/core/agent/window/strategies/drop.js.map +1 -0
  130. package/dist/esm/core/agent/window/strategies/slidingWindow.d.ts +48 -0
  131. package/dist/esm/core/agent/window/strategies/slidingWindow.js +83 -0
  132. package/dist/esm/core/agent/window/strategies/slidingWindow.js.map +1 -0
  133. package/dist/esm/core/agent/window/strategies/summarizeOldest.d.ts +42 -0
  134. package/dist/esm/core/agent/window/strategies/summarizeOldest.js +174 -0
  135. package/dist/esm/core/agent/window/strategies/summarizeOldest.js.map +1 -0
  136. package/dist/esm/core/agent/window/strategies/tokenBudget.d.ts +47 -0
  137. package/dist/esm/core/agent/window/strategies/tokenBudget.js +91 -0
  138. package/dist/esm/core/agent/window/strategies/tokenBudget.js.map +1 -0
  139. package/dist/esm/core/agent/window/strategy.d.ts +181 -0
  140. package/dist/esm/core/agent/window/strategy.js +41 -0
  141. package/dist/esm/core/agent/window/strategy.js.map +1 -0
  142. package/dist/esm/core/agent/window/summarize.js.map +1 -0
  143. package/dist/esm/core/agent/window/turns.d.ts +108 -0
  144. package/dist/esm/core/agent/{compaction → window}/turns.js +48 -26
  145. package/dist/esm/core/agent/window/turns.js.map +1 -0
  146. package/dist/esm/core/agent/window/types.d.ts +263 -0
  147. package/dist/esm/core/agent/window/types.js +22 -0
  148. package/dist/esm/core/agent/window/types.js.map +1 -0
  149. package/dist/esm/core/pause.d.ts +42 -0
  150. package/dist/esm/core/pause.js +17 -0
  151. package/dist/esm/core/pause.js.map +1 -1
  152. package/dist/esm/events/dispatcher.d.ts +1 -1
  153. package/dist/esm/events/dispatcher.js.map +1 -1
  154. package/dist/esm/events/payloads.d.ts +26 -0
  155. package/dist/esm/events/registry.d.ts +5 -1
  156. package/dist/esm/events/registry.js +4 -0
  157. package/dist/esm/events/registry.js.map +1 -1
  158. package/dist/esm/index.d.ts +3 -2
  159. package/dist/esm/index.js +23 -6
  160. package/dist/esm/index.js.map +1 -1
  161. package/dist/esm/lib/mcp/mcpServe.js +39 -6
  162. package/dist/esm/lib/mcp/mcpServe.js.map +1 -1
  163. package/dist/esm/lib/mcp/types.d.ts +16 -0
  164. package/dist/esm/recorders/core/CompactionMeter.d.ts +25 -19
  165. package/dist/esm/recorders/core/CompactionMeter.js +27 -19
  166. package/dist/esm/recorders/core/CompactionMeter.js.map +1 -1
  167. package/dist/events/dispatcher.js.map +1 -1
  168. package/dist/events/registry.js +4 -0
  169. package/dist/events/registry.js.map +1 -1
  170. package/dist/index.js +40 -13
  171. package/dist/index.js.map +1 -1
  172. package/dist/lib/mcp/mcpServe.js +39 -6
  173. package/dist/lib/mcp/mcpServe.js.map +1 -1
  174. package/dist/recorders/core/CompactionMeter.js +27 -19
  175. package/dist/recorders/core/CompactionMeter.js.map +1 -1
  176. package/dist/types/conventions.d.ts +8 -6
  177. package/dist/types/conventions.d.ts.map +1 -1
  178. package/dist/types/core/Agent.d.ts +14 -6
  179. package/dist/types/core/Agent.d.ts.map +1 -1
  180. package/dist/types/core/RunnerBase.d.ts.map +1 -1
  181. package/dist/types/core/agent/AgentBuilder.d.ts +157 -4
  182. package/dist/types/core/agent/AgentBuilder.d.ts.map +1 -1
  183. package/dist/types/core/agent/buildAgentChart.d.ts +16 -9
  184. package/dist/types/core/agent/buildAgentChart.d.ts.map +1 -1
  185. package/dist/types/core/agent/middleware/errors.d.ts +52 -0
  186. package/dist/types/core/agent/middleware/errors.d.ts.map +1 -0
  187. package/dist/types/core/agent/middleware/index.d.ts +17 -0
  188. package/dist/types/core/agent/middleware/index.d.ts.map +1 -0
  189. package/dist/types/core/agent/middleware/ledger.d.ts +41 -0
  190. package/dist/types/core/agent/middleware/ledger.d.ts.map +1 -0
  191. package/dist/types/core/agent/middleware/outcomes.d.ts +46 -0
  192. package/dist/types/core/agent/middleware/outcomes.d.ts.map +1 -0
  193. package/dist/types/core/agent/middleware/runChain.d.ts +105 -0
  194. package/dist/types/core/agent/middleware/runChain.d.ts.map +1 -0
  195. package/dist/types/core/agent/middleware/types.d.ts +192 -0
  196. package/dist/types/core/agent/middleware/types.d.ts.map +1 -0
  197. package/dist/types/core/agent/stages/prepareFinal.d.ts +10 -0
  198. package/dist/types/core/agent/stages/prepareFinal.d.ts.map +1 -1
  199. package/dist/types/core/agent/stages/route.d.ts +29 -0
  200. package/dist/types/core/agent/stages/route.d.ts.map +1 -1
  201. package/dist/types/core/agent/stages/seed.d.ts +16 -1
  202. package/dist/types/core/agent/stages/seed.d.ts.map +1 -1
  203. package/dist/types/core/agent/stages/toolCalls.d.ts +23 -0
  204. package/dist/types/core/agent/stages/toolCalls.d.ts.map +1 -1
  205. package/dist/types/core/agent/stages/window.d.ts +64 -0
  206. package/dist/types/core/agent/stages/window.d.ts.map +1 -0
  207. package/dist/types/core/agent/types.d.ts +33 -8
  208. package/dist/types/core/agent/types.d.ts.map +1 -1
  209. package/dist/types/core/agent/window/errors.d.ts.map +1 -0
  210. package/dist/types/core/agent/window/index.d.ts +28 -0
  211. package/dist/types/core/agent/window/index.d.ts.map +1 -0
  212. package/dist/types/core/agent/window/notice.d.ts +47 -0
  213. package/dist/types/core/agent/window/notice.d.ts.map +1 -0
  214. package/dist/types/core/agent/window/options.d.ts +34 -0
  215. package/dist/types/core/agent/window/options.d.ts.map +1 -0
  216. package/dist/types/core/agent/window/removal.d.ts +23 -0
  217. package/dist/types/core/agent/window/removal.d.ts.map +1 -0
  218. package/dist/types/core/agent/window/strategies/drop.d.ts +55 -0
  219. package/dist/types/core/agent/window/strategies/drop.d.ts.map +1 -0
  220. package/dist/types/core/agent/window/strategies/slidingWindow.d.ts +49 -0
  221. package/dist/types/core/agent/window/strategies/slidingWindow.d.ts.map +1 -0
  222. package/dist/types/core/agent/window/strategies/summarizeOldest.d.ts +43 -0
  223. package/dist/types/core/agent/window/strategies/summarizeOldest.d.ts.map +1 -0
  224. package/dist/types/core/agent/window/strategies/tokenBudget.d.ts +48 -0
  225. package/dist/types/core/agent/window/strategies/tokenBudget.d.ts.map +1 -0
  226. package/dist/types/core/agent/window/strategy.d.ts +182 -0
  227. package/dist/types/core/agent/window/strategy.d.ts.map +1 -0
  228. package/dist/types/core/agent/window/summarize.d.ts.map +1 -0
  229. package/dist/types/core/agent/window/turns.d.ts +109 -0
  230. package/dist/types/core/agent/window/turns.d.ts.map +1 -0
  231. package/dist/types/core/agent/window/types.d.ts +264 -0
  232. package/dist/types/core/agent/window/types.d.ts.map +1 -0
  233. package/dist/types/core/pause.d.ts +42 -0
  234. package/dist/types/core/pause.d.ts.map +1 -1
  235. package/dist/types/events/dispatcher.d.ts +1 -1
  236. package/dist/types/events/dispatcher.d.ts.map +1 -1
  237. package/dist/types/events/payloads.d.ts +26 -0
  238. package/dist/types/events/payloads.d.ts.map +1 -1
  239. package/dist/types/events/registry.d.ts +5 -1
  240. package/dist/types/events/registry.d.ts.map +1 -1
  241. package/dist/types/index.d.ts +3 -2
  242. package/dist/types/index.d.ts.map +1 -1
  243. package/dist/types/lib/mcp/mcpServe.d.ts.map +1 -1
  244. package/dist/types/lib/mcp/types.d.ts +16 -0
  245. package/dist/types/lib/mcp/types.d.ts.map +1 -1
  246. package/dist/types/recorders/core/CompactionMeter.d.ts +25 -19
  247. package/dist/types/recorders/core/CompactionMeter.d.ts.map +1 -1
  248. package/package.json +1 -1
  249. package/dist/core/agent/compaction/errors.js.map +0 -1
  250. package/dist/core/agent/compaction/index.js +0 -24
  251. package/dist/core/agent/compaction/index.js.map +0 -1
  252. package/dist/core/agent/compaction/strategy.js +0 -152
  253. package/dist/core/agent/compaction/strategy.js.map +0 -1
  254. package/dist/core/agent/compaction/summarize.js.map +0 -1
  255. package/dist/core/agent/compaction/turns.js.map +0 -1
  256. package/dist/core/agent/compaction/types.js +0 -21
  257. package/dist/core/agent/compaction/types.js.map +0 -1
  258. package/dist/core/agent/stages/compact.js +0 -130
  259. package/dist/core/agent/stages/compact.js.map +0 -1
  260. package/dist/esm/core/agent/compaction/errors.js.map +0 -1
  261. package/dist/esm/core/agent/compaction/index.d.ts +0 -18
  262. package/dist/esm/core/agent/compaction/index.js +0 -18
  263. package/dist/esm/core/agent/compaction/index.js.map +0 -1
  264. package/dist/esm/core/agent/compaction/strategy.d.ts +0 -103
  265. package/dist/esm/core/agent/compaction/strategy.js +0 -148
  266. package/dist/esm/core/agent/compaction/strategy.js.map +0 -1
  267. package/dist/esm/core/agent/compaction/summarize.js.map +0 -1
  268. package/dist/esm/core/agent/compaction/turns.d.ts +0 -85
  269. package/dist/esm/core/agent/compaction/turns.js.map +0 -1
  270. package/dist/esm/core/agent/compaction/types.d.ts +0 -148
  271. package/dist/esm/core/agent/compaction/types.js +0 -20
  272. package/dist/esm/core/agent/compaction/types.js.map +0 -1
  273. package/dist/esm/core/agent/stages/compact.d.ts +0 -59
  274. package/dist/esm/core/agent/stages/compact.js +0 -126
  275. package/dist/esm/core/agent/stages/compact.js.map +0 -1
  276. package/dist/types/core/agent/compaction/errors.d.ts.map +0 -1
  277. package/dist/types/core/agent/compaction/index.d.ts +0 -19
  278. package/dist/types/core/agent/compaction/index.d.ts.map +0 -1
  279. package/dist/types/core/agent/compaction/strategy.d.ts +0 -104
  280. package/dist/types/core/agent/compaction/strategy.d.ts.map +0 -1
  281. package/dist/types/core/agent/compaction/summarize.d.ts.map +0 -1
  282. package/dist/types/core/agent/compaction/turns.d.ts +0 -86
  283. package/dist/types/core/agent/compaction/turns.d.ts.map +0 -1
  284. package/dist/types/core/agent/compaction/types.d.ts +0 -149
  285. package/dist/types/core/agent/compaction/types.d.ts.map +0 -1
  286. package/dist/types/core/agent/stages/compact.d.ts +0 -60
  287. package/dist/types/core/agent/stages/compact.d.ts.map +0 -1
  288. /package/dist/core/agent/{compaction → window}/errors.js +0 -0
  289. /package/dist/core/agent/{compaction → window}/summarize.js +0 -0
  290. /package/dist/esm/core/agent/{compaction → window}/errors.d.ts +0 -0
  291. /package/dist/esm/core/agent/{compaction → window}/errors.js +0 -0
  292. /package/dist/esm/core/agent/{compaction → window}/summarize.d.ts +0 -0
  293. /package/dist/esm/core/agent/{compaction → window}/summarize.js +0 -0
  294. /package/dist/types/core/agent/{compaction → window}/errors.d.ts +0 -0
  295. /package/dist/types/core/agent/{compaction → window}/summarize.d.ts +0 -0
@@ -0,0 +1,34 @@
1
+ /**
2
+ * window/options — validate a window strategy's options ONCE, at build time.
3
+ *
4
+ * Pattern: Guard functions returning a resolved config.
5
+ * Role: core/ layer. Every message here takes a `label`, because the same
6
+ * option bag arrives through two doors — `.compaction({...})` and
7
+ * `summarizeOldest({...})` — and an error should name the door the
8
+ * caller actually used. One implementation, so the two doors can
9
+ * never drift into validating differently.
10
+ * Emits: N/A.
11
+ *
12
+ * Everything fails at `.build()`, never mid-run. A window policy that turns
13
+ * out to be nonsense on iteration 40 of a paid run is a policy that cost you
14
+ * money to discover.
15
+ */
16
+ import type { CompactionOptions, ResolvedCompaction, SlidingWindowOptions, TokenBudgetOptions } from './types.js';
17
+ /** Default depth of the "never touch this" recent window. */
18
+ export declare const DEFAULT_KEEP_RECENT_TURNS = 6;
19
+ /**
20
+ * Validate `.compaction()` / `summarizeOldest()` options.
21
+ *
22
+ * @param label the door being used, so the error names it
23
+ */
24
+ export declare function resolveCompactionOptions(options: CompactionOptions, label: string): ResolvedCompaction;
25
+ /** Validate `slidingWindow()` options. */
26
+ export declare function resolveSlidingWindowOptions(options: SlidingWindowOptions, label: string): {
27
+ readonly keepRecentTurns: number;
28
+ };
29
+ /** Validate `tokenBudget()` options. */
30
+ export declare function resolveTokenBudgetOptions(options: TokenBudgetOptions, label: string): {
31
+ readonly thresholdTokens: number;
32
+ readonly keepRecentTurns: number;
33
+ };
34
+ //# sourceMappingURL=options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../../../../src/core/agent/window/options.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAEpB,6DAA6D;AAC7D,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAgC3C;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,iBAAiB,EAC1B,KAAK,EAAE,MAAM,GACZ,kBAAkB,CAyBpB;AAED,0CAA0C;AAC1C,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,oBAAoB,EAC7B,KAAK,EAAE,MAAM,GACZ;IAAE,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;CAAE,CAWtC;AAED,wCAAwC;AACxC,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,kBAAkB,EAC3B,KAAK,EAAE,MAAM,GACZ;IAAE,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;CAAE,CAMxE"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * window/removal — "these messages left" → the facts the ledger needs.
3
+ *
4
+ * Pattern: Pure function over the meter's provenance.
5
+ * Role: core/ layer. The stage binds this into every
6
+ * `WindowStrategyInput.removalFacts`, so a strategy can name what it
7
+ * removed without ever touching the meter — and cannot file a
8
+ * removal it is unable to name.
9
+ * Emits: N/A.
10
+ */
11
+ import type { MessageOrigin } from '../../../recorders/core/CompactionMeter.js';
12
+ import type { RemovalFacts } from './strategy.js';
13
+ /**
14
+ * Resolve which stages wrote the removed messages, and how long each lived.
15
+ *
16
+ * `survivalMs` is measured (`atMs - bornAtMs`), and is 0 — not a guess — when
17
+ * a message's birth is unknown, which happens only for a window seeded from
18
+ * outside this run.
19
+ */
20
+ export declare function removalFacts(origins: readonly MessageOrigin[], indices: readonly number[], atMs: number): RemovalFacts;
21
+ /** `[from, toExclusive)` as a list of indices. */
22
+ export declare function indexRange(from: number, toExclusive: number): number[];
23
+ //# sourceMappingURL=removal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"removal.d.ts","sourceRoot":"","sources":["../../../../../src/core/agent/window/removal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4CAA4C,CAAC;AAChF,OAAO,KAAK,EAAE,YAAY,EAAkB,MAAM,eAAe,CAAC;AAElE;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,SAAS,aAAa,EAAE,EACjC,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,IAAI,EAAE,MAAM,GACX,YAAY,CAcd;AAED,kDAAkD;AAClD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAItE"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * window/strategies/drop — the mechanic both drop strategies share.
3
+ *
4
+ * Pattern: One pure function over a `WindowStrategyInput`.
5
+ * Role: core/ layer. `slidingWindow` and `tokenBudget` differ ONLY in when
6
+ * they engage and what they file; what actually leaves the window is
7
+ * decided here, once, so a refusal reason means the same thing under
8
+ * both — and under compaction, which asks the same `planRemoval`.
9
+ * Emits: N/A.
10
+ *
11
+ * A drop makes no LLM call and writes no summary. What it must still do is
12
+ * keep the request valid and keep the record honest:
13
+ *
14
+ * • the span comes from the shared refusal engine, so an unanswered tool
15
+ * call, the paused tool, a pending check-in and the recent turns never
16
+ * leave, and each refusal is named;
17
+ * • when the span reaches the window's HEAD, an authored notice takes that
18
+ * position — the window must open on a user turn (see notice.ts), and a
19
+ * message we are forced to author should tell the truth;
20
+ * • when it does not, nothing is inserted: the original opening turn is
21
+ * still there, so there is no wire problem to solve.
22
+ */
23
+ import type { LLMMessage } from '../../../../adapters/types.js';
24
+ import type { WindowEviction, WindowStrategyInput } from '../strategy.js';
25
+ import type { WindowRefusal } from '../types.js';
26
+ /** What a drop attempt did, in the terms a record needs. */
27
+ export interface DropOutcome {
28
+ /** Every turn that refused to leave, named. */
29
+ readonly refusals: readonly WindowRefusal[];
30
+ /** The new window; absent when nothing was dropped. */
31
+ readonly window?: readonly LLMMessage[];
32
+ readonly rebase?: {
33
+ readonly headCount: number;
34
+ readonly keptTailCount: number;
35
+ readonly insertedAtMs?: number;
36
+ };
37
+ readonly removedStageIds: readonly string[];
38
+ readonly removedMessageCount: number;
39
+ readonly evictions: readonly WindowEviction[];
40
+ readonly windowCharsBefore: number;
41
+ readonly windowCharsAfter: number;
42
+ /** Turns in the window before / after. Counted from the segmentation. */
43
+ readonly turnsBefore: number;
44
+ readonly turnsAfter: number;
45
+ }
46
+ /**
47
+ * Drop the oldest contiguous removable span, if there is one.
48
+ *
49
+ * @param input the strategy's input, with the bound refusal engine
50
+ * @param keepRecentTurns how many trailing turns are off-limits
51
+ * @param strategyName named in the authored notice, so a reader of the
52
+ * window itself can tell which policy removed things
53
+ */
54
+ export declare function dropOldestSpan(input: WindowStrategyInput, keepRecentTurns: number, strategyName: string): DropOutcome;
55
+ //# sourceMappingURL=drop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drop.d.ts","sourceRoot":"","sources":["../../../../../../src/core/agent/window/strategies/drop.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAGhE,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,4DAA4D;AAC5D,MAAM,WAAW,WAAW;IAC1B,+CAA+C;IAC/C,QAAQ,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;IAC5C,uDAAuD;IACvD,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IACxC,QAAQ,CAAC,MAAM,CAAC,EAAE;QAChB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;QAC/B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;KAChC,CAAC;IACF,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,SAAS,EAAE,SAAS,cAAc,EAAE,CAAC;IAC9C,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,yEAAyE;IACzE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,mBAAmB,EAC1B,eAAe,EAAE,MAAM,EACvB,YAAY,EAAE,MAAM,GACnB,WAAW,CAsEb"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * slidingWindow — keep the last N turns, drop what is older.
3
+ *
4
+ * Pattern: WindowStrategy implementation. Its own module, registering
5
+ * nothing at import.
6
+ * Role: core/ layer.
7
+ * Emits: N/A — the stage emits, records and costs; this file decides.
8
+ *
9
+ * The market's simplest window policy (LangChain's `trim_messages`, the
10
+ * "last N messages" every framework ships). Two things are different here:
11
+ *
12
+ * 1. **It refuses by name.** It goes through the SAME turn segmentation and
13
+ * the SAME refusal engine as compaction, so it will not drop half of a
14
+ * `tool_use` / `tool_result` pair, will not drop an unanswered tool call
15
+ * whose answer may still arrive, will not drop the tool a paused run is
16
+ * waiting on or a pending check-in, and cannot touch the system
17
+ * envelope. Message-counting trimmers split those pairs and the vendor
18
+ * rejects the request; this one steps over them and says so in the
19
+ * record.
20
+ * 2. **It says what it dropped.** Every dropped message is an eviction
21
+ * event with its measured lifetime, and the record names the stage ids
22
+ * the messages came from. The turns themselves stay in the commit log,
23
+ * byte for byte.
24
+ *
25
+ * It triggers on turn COUNT, not tokens — so it needs no summarizer, makes no
26
+ * LLM call, and runs on ANY provider, including the ones that report no usage
27
+ * at all. Nothing here is unmeasurable, so nothing here throws.
28
+ */
29
+ import type { WindowStrategy } from '../strategy.js';
30
+ import type { SlidingWindowOptions } from '../types.js';
31
+ /** `WindowRecord.strategy` written by every record this strategy files. */
32
+ export declare const SLIDING_WINDOW = "sliding-window";
33
+ /**
34
+ * Keep the most recent `keepRecentTurns` turns in the live window and drop
35
+ * the older ones — except anything that refuses.
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * import { Agent, slidingWindow } from 'agentfootprint';
40
+ * import { ollama } from 'agentfootprint/llm-providers';
41
+ *
42
+ * // Works on a provider that reports no usage at all: the trigger is turns.
43
+ * const agent = Agent.create({ provider: ollama(), model: 'llama3' })
44
+ * .window(slidingWindow({ keepRecentTurns: 12 }))
45
+ * .build();
46
+ * ```
47
+ */
48
+ export declare function slidingWindow(options: SlidingWindowOptions): WindowStrategy;
49
+ //# sourceMappingURL=slidingWindow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slidingWindow.d.ts","sourceRoot":"","sources":["../../../../../../src/core/agent/window/strategies/slidingWindow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAIH,OAAO,KAAK,EAAE,cAAc,EAA6C,MAAM,gBAAgB,CAAC;AAChG,OAAO,KAAK,EAAE,oBAAoB,EAAuB,MAAM,aAAa,CAAC;AAE7E,2EAA2E;AAC3E,eAAO,MAAM,cAAc,mBAAmB,CAAC;AAE/C;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,cAAc,CAqC3E"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * summarizeOldest — fold the oldest foldable turns into one summary message.
3
+ *
4
+ * Pattern: WindowStrategy implementation. Its own module, importing nothing
5
+ * that registers anything, so a bundle that never mentions it never
6
+ * carries it (and never carries the summarizer machinery either).
7
+ * Role: core/ layer.
8
+ * Emits: N/A — the stage emits, records and costs; this file decides.
9
+ *
10
+ * This is what `.compaction({...})` configures, and the market's familiar
11
+ * move (Claude Code / the Claude Agent SDK call it compaction). What is
12
+ * different here is not the fold — it is that the fold is filed as a claim:
13
+ * a summary is a claim ABOUT the past, and the past itself stays in the
14
+ * commit log, byte for byte.
15
+ *
16
+ * Everything it decides, it explains. Every engaged path returns a record —
17
+ * including the paths that change nothing, which are the ones a person
18
+ * debugging an over-budget window actually needs.
19
+ */
20
+ import type { WindowStrategy } from '../strategy.js';
21
+ import type { CompactionOptions } from '../types.js';
22
+ /** `WindowRecord.strategy` written by every record this strategy files. */
23
+ export declare const SUMMARIZE_OLDEST = "summarize-oldest";
24
+ /**
25
+ * Fold the oldest contiguous run of foldable turns into one summary message,
26
+ * keeping the recent turns and stepping over anything unresolved.
27
+ *
28
+ * Triggered by COUNTED tokens: the last call's adapter-reported input tokens
29
+ * against `thresholdTokens`. A provider that reports no usage gets
30
+ * `CompactionUnmeasurableError` rather than an invented number.
31
+ *
32
+ * @example
33
+ * ```ts
34
+ * import { Agent, summarizeOldest } from 'agentfootprint';
35
+ *
36
+ * const agent = Agent.create({ provider: anthropic(), model: 'claude-sonnet-4-5' })
37
+ * .window(summarizeOldest({ thresholdTokens: 120_000, summarizer: anthropic() }))
38
+ * .build();
39
+ * // `.compaction({ ... })` is this exact line, spelled shorter.
40
+ * ```
41
+ */
42
+ export declare function summarizeOldest(options: CompactionOptions): WindowStrategy;
43
+ //# sourceMappingURL=summarizeOldest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summarizeOldest.d.ts","sourceRoot":"","sources":["../../../../../../src/core/agent/window/strategies/summarizeOldest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,OAAO,KAAK,EAAE,cAAc,EAA6C,MAAM,gBAAgB,CAAC;AAGhG,OAAO,KAAK,EAAE,iBAAiB,EAAmC,MAAM,aAAa,CAAC;AAEtF,2EAA2E;AAC3E,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AAEnD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,iBAAiB,GAAG,cAAc,CAiJ1E"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * tokenBudget — compaction's trigger discipline, without the summarizer.
3
+ *
4
+ * Pattern: WindowStrategy implementation. Its own module, registering
5
+ * nothing at import.
6
+ * Role: core/ layer.
7
+ * Emits: N/A — the stage emits, records and costs; this file decides.
8
+ *
9
+ * The market's other familiar policy: cap the window at a token budget
10
+ * (Mastra's `TokenLimiter` is the closest sibling). What is different here is
11
+ * the same thing that is different about compaction — the number is COUNTED,
12
+ * never guessed:
13
+ *
14
+ * • the trigger reads the input tokens the PROVIDER reported for the last
15
+ * call, not a character estimate and not a divide-by-four heuristic;
16
+ * • a provider that reports no usage gets `CompactionUnmeasurableError` by
17
+ * name, the same refusal `.compaction()` makes, rather than an invented
18
+ * window size or a configured budget that silently never applies.
19
+ *
20
+ * When over budget it drops the oldest contiguous removable span — the same
21
+ * span compaction would have folded, chosen by the same refusal engine — and
22
+ * writes no summary at all. Nothing is claimed about what left, because
23
+ * nothing was read: the record and the eviction events name it, and the
24
+ * commit log still has it verbatim.
25
+ *
26
+ * Use it over `summarizeOldest` when you would rather lose the old turns than
27
+ * pay a summarizer to paraphrase them, and over `slidingWindow` when the
28
+ * thing you are actually defending is a token bill rather than a turn depth.
29
+ */
30
+ import type { WindowStrategy } from '../strategy.js';
31
+ import type { TokenBudgetOptions } from '../types.js';
32
+ /** `WindowRecord.strategy` written by every record this strategy files. */
33
+ export declare const TOKEN_BUDGET = "token-budget";
34
+ /**
35
+ * Drop the oldest turns whenever the last call's adapter-reported input
36
+ * tokens exceed `thresholdTokens`.
37
+ *
38
+ * @example
39
+ * ```ts
40
+ * import { Agent, tokenBudget } from 'agentfootprint';
41
+ *
42
+ * const agent = Agent.create({ provider: anthropic(), model: 'claude-sonnet-4-5' })
43
+ * .window(tokenBudget({ thresholdTokens: 120_000 }))
44
+ * .build();
45
+ * ```
46
+ */
47
+ export declare function tokenBudget(options: TokenBudgetOptions): WindowStrategy;
48
+ //# sourceMappingURL=tokenBudget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokenBudget.d.ts","sourceRoot":"","sources":["../../../../../../src/core/agent/window/strategies/tokenBudget.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAKH,OAAO,KAAK,EAAE,cAAc,EAA6C,MAAM,gBAAgB,CAAC;AAChG,OAAO,KAAK,EAAE,kBAAkB,EAAqB,MAAM,aAAa,CAAC;AAEzE,2EAA2E;AAC3E,eAAO,MAAM,YAAY,iBAAiB,CAAC;AAE3C;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,cAAc,CA6CvE"}
@@ -0,0 +1,182 @@
1
+ /**
2
+ * window/strategy — PUBLIC. How a window strategy is shaped.
3
+ *
4
+ * Pattern: Strategy (GoF), with the dangerous half of the decision handed in
5
+ * pre-bound rather than left to the implementer to re-derive.
6
+ * Role: core/ layer. The window stage does the wiring — read the meter,
7
+ * write the window, emit, record, cost — and delegates the one
8
+ * interesting question to a strategy:
9
+ *
10
+ * given the segmented turns and what the provider actually
11
+ * counted → what should the window become, and what does the
12
+ * ledger need to be told about it?
13
+ *
14
+ * Emits: N/A. A strategy is pure decision + (optionally) its own LLM call;
15
+ * it never touches scope, never emits, and never writes. That is
16
+ * what makes it testable without a chart, and what keeps the
17
+ * "record everything you did" duty in ONE place (the stage) rather
18
+ * than duplicated per strategy.
19
+ *
20
+ * Three strategies ship — `summarizeOldest` (what `.compaction()`
21
+ * configures), `slidingWindow`, `tokenBudget` — and `.window(...)` takes any
22
+ * object that satisfies `WindowStrategy`.
23
+ *
24
+ * Two things are deliberately NOT left to the implementer:
25
+ *
26
+ * 1. **The refusal rules.** `planRemoval` arrives already bound to this
27
+ * iteration's turns and guards. A strategy cannot forget that an
28
+ * unanswered tool call must not leave the window, because it never gets
29
+ * the chance to decide that for itself — it asks, and it is told, with
30
+ * every refusal named. That is safety by construction, not by docs.
31
+ * 2. **Provenance.** `removalFacts` turns "these indices left" into the
32
+ * stage ids that wrote them and how long each lived. A strategy cannot
33
+ * file a removal it cannot name.
34
+ *
35
+ * The TRIGGER, by contrast, is entirely the strategy's own: `plan` is called
36
+ * at every ReAct iteration boundary and answers `undefined` when it did not
37
+ * engage. That is why `slidingWindow` can run on a provider that reports no
38
+ * usage at all while `summarizeOldest` and `tokenBudget` refuse by name.
39
+ */
40
+ import type { LLMMessage } from '../../../adapters/types.js';
41
+ import type { Turn, RemovalPlan } from './turns.js';
42
+ import type { WindowRecord } from './types.js';
43
+ /** One message leaving the window, with the facts an eviction event needs. */
44
+ export interface WindowEviction {
45
+ /** Index in the PRE-change window — the index the content hash was built on. */
46
+ readonly index: number;
47
+ /** How long it lived in the window. Exact; 0 when its birth is unknown. */
48
+ readonly survivalMs: number;
49
+ }
50
+ /** The provenance of a set of removed messages, as the ledger needs it. */
51
+ export interface RemovalFacts {
52
+ /** `runtimeStageId`s of the stages that appended those messages, in order. */
53
+ readonly removedStageIds: readonly string[];
54
+ /** One eviction per message, with its measured lifetime. */
55
+ readonly evictions: readonly WindowEviction[];
56
+ }
57
+ /** Everything a strategy is allowed to look at. */
58
+ export interface WindowStrategyInput {
59
+ /** The window as it stands, detached. */
60
+ readonly history: readonly LLMMessage[];
61
+ /** The same window, segmented into turns. */
62
+ readonly turns: readonly Turn[];
63
+ /**
64
+ * What the provider REPORTED for the last completed call. Counted, never
65
+ * guessed. `undefined` before the first call of the run — a strategy that
66
+ * acted on that would be guessing, which is the one thing this family
67
+ * refuses to do.
68
+ *
69
+ * `{ input: 0, output: 0 }` is a provider that reported NOTHING, not a call
70
+ * that cost nothing. A token-triggered strategy should throw
71
+ * `CompactionUnmeasurableError` there rather than invent a size.
72
+ */
73
+ readonly measured: {
74
+ readonly input: number;
75
+ readonly output: number;
76
+ } | undefined;
77
+ /** The ReAct iteration this decision belongs to. */
78
+ readonly iteration: number;
79
+ /** The agent's own model — the sensible default for a strategy that bills. */
80
+ readonly agentModel: string;
81
+ /** `provider.name` of the MAIN provider, for a refusal that names it. */
82
+ readonly providerName: string;
83
+ /** The run's cancellation signal, when there is one. */
84
+ readonly signal: AbortSignal | undefined;
85
+ /** Wall clock, injectable so a caller can pin `survivalMs`. */
86
+ readonly now: () => number;
87
+ /**
88
+ * THE shared refusal engine, bound to this iteration.
89
+ *
90
+ * Answers: which contiguous span of turns may leave, and every turn that
91
+ * refused, named. Never removes the system envelope, the last
92
+ * `keepRecentTurns` turns, an unanswered tool call, the paused tool, or a
93
+ * pending check-in.
94
+ *
95
+ * @param keepRecentTurns how many trailing turns are off-limits
96
+ * @param isExistingSummary optional predicate marking a turn that is a
97
+ * summary a previous fold wrote; when the whole span is one of those, the
98
+ * plan refuses with `only-existing-summary`. Pass it only if your strategy
99
+ * spends an LLM call — a drop has nothing to protect against.
100
+ */
101
+ readonly planRemoval: (keepRecentTurns: number, isExistingSummary?: (turn: Turn) => boolean) => RemovalPlan;
102
+ /**
103
+ * Turn removed message indices into the facts the ledger needs: which
104
+ * stages wrote them, and how long each lived in the window.
105
+ *
106
+ * @param indices indices in the PRE-change window that are leaving
107
+ * @param atMs the moment they leave (usually `input.now()`)
108
+ */
109
+ readonly removalFacts: (indices: readonly number[], atMs: number) => RemovalFacts;
110
+ }
111
+ /** What the stage should do next. */
112
+ export interface WindowStrategyResult {
113
+ /** The new window. Absent = leave the window alone. */
114
+ readonly window?: readonly LLMMessage[];
115
+ /**
116
+ * How the meter must re-align its provenance to the new window, which is
117
+ * `[...head, (one new message)?, ...tail]`. Present exactly when `window`
118
+ * is. `insertedAtMs` is the birth of the message the strategy put in the
119
+ * span's place — omit it when the strategy removed messages and inserted
120
+ * nothing.
121
+ */
122
+ readonly rebase?: {
123
+ readonly headCount: number;
124
+ readonly keptTailCount: number;
125
+ readonly insertedAtMs?: number;
126
+ };
127
+ /** What the ledger is told. Always present — an engaged visit explains itself. */
128
+ readonly record: WindowRecord;
129
+ /** Messages that left the window, for `context.evicted`. */
130
+ readonly evictions: readonly WindowEviction[];
131
+ /**
132
+ * The budget reading to report on `agentfootprint.context.budget_pressure`.
133
+ *
134
+ * OMIT IT when the strategy has no token budget. `slidingWindow` does: it
135
+ * triggers on turn count, and filling `capTokens` with a number nobody
136
+ * configured would be the invented figure this family refuses. No budget,
137
+ * no budget_pressure event.
138
+ */
139
+ readonly budgetPressure?: {
140
+ readonly capTokens: number;
141
+ readonly projectedTokens: number;
142
+ readonly planAction: 'evict' | 'summarize' | 'none';
143
+ };
144
+ /** A billed call the strategy made, for the cost channel. */
145
+ readonly spend?: {
146
+ readonly model: string;
147
+ readonly usage: {
148
+ readonly input: number;
149
+ readonly output: number;
150
+ };
151
+ };
152
+ /** A one-per-run dev warning the stage should print. */
153
+ readonly warning?: string;
154
+ }
155
+ /**
156
+ * A window strategy: what the live window should become at this iteration
157
+ * boundary, and what the record must say about the change.
158
+ *
159
+ * Pass one to `AgentBuilder.window(...)`. Exactly one per agent —
160
+ * `.compaction(...)` is the same door with `summarizeOldest` already in it.
161
+ */
162
+ export interface WindowStrategy {
163
+ /**
164
+ * Stable name — it is written onto every record this strategy files
165
+ * (`WindowRecord.strategy`), so a reader can tell which policy produced a
166
+ * window, and it names the strategy on the chart's `compact` stage.
167
+ */
168
+ readonly name: string;
169
+ /**
170
+ * Decide. Called at EVERY ReAct iteration boundary.
171
+ *
172
+ * Return `undefined` when this strategy did not engage — nothing was over
173
+ * budget, nothing was old enough, nothing has been counted yet. The ledger
174
+ * stays untouched and the run proceeds.
175
+ *
176
+ * Return a result for anything else, INCLUDING a visit that changed
177
+ * nothing because every candidate refused. Those are the visits a person
178
+ * debugging an oversized window actually needs.
179
+ */
180
+ plan(input: WindowStrategyInput): Promise<WindowStrategyResult | undefined>;
181
+ }
182
+ //# sourceMappingURL=strategy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strategy.d.ts","sourceRoot":"","sources":["../../../../../src/core/agent/window/strategy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summarize.d.ts","sourceRoot":"","sources":["../../../../../src/core/agent/window/summarize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAEvF,6EAA6E;AAC7E,eAAO,MAAM,sBAAsB,uBAAuB,CAAC;AAM3D;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,QAYzB,CAAC;AAcb,mEAAmE;AACnE,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,SAAS,UAAU,EAAE,GAAG,MAAM,CAExE;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE;IACL,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,GACA,UAAU,CAOZ;AAED,+DAA+D;AAC/D,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,UAAU,GAAG,SAAS,GAAG,OAAO,CAEvE;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;CACtC;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,WAAW,EACrB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,SAAS,UAAU,EAAE,EAC3B,MAAM,EAAE,WAAW,GAAG,SAAS,GAC9B,OAAO,CAAC,eAAe,CAAC,CAQ1B"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * window/turns — where a turn boundary is, and which turns may leave.
3
+ *
4
+ * Pattern: Pure functions over the window (no scope, no I/O, no clock).
5
+ * Role: core/ layer. THE refusal engine. Every window strategy — the three
6
+ * that ship, and any a consumer writes — decides what leaves the
7
+ * window by calling these functions and nothing else, because the
8
+ * whole safety argument of the family lives here:
9
+ *
10
+ * a removal that splits an assistant's `tool_use` from its
11
+ * `tool_result` produces a request the vendor rejects, and a
12
+ * removal that swallows an unanswered question destroys the
13
+ * referent of the answer that has not arrived yet.
14
+ *
15
+ * Strategies never import this module. `WindowStrategyInput` hands
16
+ * them `planRemoval` already bound to this iteration's turns and
17
+ * guards, so a strategy CANNOT skip the refusal rules — that is a
18
+ * property of the seam, not of the documentation.
19
+ * Emits: N/A.
20
+ *
21
+ * Testable on its own — see `test/core/window-turns.test.ts`.
22
+ */
23
+ import type { LLMMessage } from '../../../adapters/types.js';
24
+ import type { WindowRefusal, WindowRefusalReason } from './types.js';
25
+ /**
26
+ * One turn: a `user` / `assistant` / `system` message plus every `tool`
27
+ * message that answers it. Tool results belong to the assistant turn that
28
+ * requested them — that pairing is the thing a removal must never break.
29
+ */
30
+ export interface Turn {
31
+ /** Index of this turn in the segmentation. */
32
+ readonly index: number;
33
+ /** Index of the turn's FIRST message in the window. */
34
+ readonly start: number;
35
+ /** Number of messages in the turn. */
36
+ readonly length: number;
37
+ readonly messages: readonly LLMMessage[];
38
+ }
39
+ /**
40
+ * Segment a window into turns.
41
+ *
42
+ * A new turn starts at any non-`tool` message; `tool` messages join the turn
43
+ * in progress. A leading `tool` message (only reachable from a hand-built
44
+ * history) starts its own turn rather than being silently dropped.
45
+ */
46
+ export declare function segmentTurns(history: readonly LLMMessage[]): readonly Turn[];
47
+ /**
48
+ * Context a removal decision needs beyond the turn itself.
49
+ *
50
+ * Internal: the stage builds it from scope and binds it into the
51
+ * `planRemoval` a strategy is handed, so no strategy has to know it exists.
52
+ */
53
+ export interface RemovalGuards {
54
+ /** Every `toolCallId` answered anywhere in the window. */
55
+ readonly answeredCallIds: ReadonlySet<string>;
56
+ /** The tool call this run is paused on, when it is paused. */
57
+ readonly pausedToolCallId?: string;
58
+ /** True when the pause is a check-in (human consent) rather than askHuman. */
59
+ readonly pausedCheckIn?: boolean;
60
+ }
61
+ /** Every tool_call id that has a matching `role: 'tool'` message. */
62
+ export declare function answeredCallIds(history: readonly LLMMessage[]): ReadonlySet<string>;
63
+ /**
64
+ * Why this turn may NOT leave the window, or `undefined` when it may.
65
+ *
66
+ * Order matters only for which reason gets reported first; every check is
67
+ * independent. `paused-tool` / `pending-check-in` are separated from
68
+ * `unresolved-tool-call` on purpose: they are the same shape but a different
69
+ * fact about the world, and "we are waiting on a human" is what the person
70
+ * reading the trace needs to see.
71
+ */
72
+ export declare function refusalFor(turn: Turn, guards: RemovalGuards): WindowRefusalReason | undefined;
73
+ /** The span a removal will take, plus every refusal it had to name to get there. */
74
+ export interface RemovalPlan {
75
+ /** First turn index in the span; -1 when nothing may be removed. */
76
+ readonly from: number;
77
+ /** Last turn index in the span (inclusive); -1 when nothing may be removed. */
78
+ readonly to: number;
79
+ readonly refusals: readonly WindowRefusal[];
80
+ }
81
+ /**
82
+ * Choose the removal span: the LONGEST CONTIGUOUS run of removable candidate
83
+ * turns, starting at the oldest removable one.
84
+ *
85
+ * Contiguity is not fussiness — it is what keeps the conversation in order.
86
+ * A fold replaces its span with ONE summary message; if the span skipped over
87
+ * an unremovable turn, that turn would end up after a summary of things that
88
+ * happened before it. So an unremovable turn at the front is stepped over (the
89
+ * span "takes the next oldest instead") and an unremovable turn in the middle
90
+ * ends the span. Everything not removed keeps its position.
91
+ *
92
+ * The drop strategies take the same span for a second reason: it is what makes
93
+ * a refusal reason mean the same thing under every strategy. A turn that ends
94
+ * the span this iteration is retried the next one — by which time the tool
95
+ * result it was waiting on has usually arrived.
96
+ *
97
+ * @param turns the window's turn segmentation
98
+ * @param keepRecent how many trailing turns are off-limits
99
+ * @param guards what must not leave (unanswered calls, the pause)
100
+ * @param isExistingSummary optional: true for a turn that is a summary a prior
101
+ * fold wrote. When the whole span is one such turn, the plan refuses with
102
+ * `only-existing-summary` — re-summarizing a summary spends an LLM call to
103
+ * lose detail. The drop strategies omit it: a drop spends nothing, so there
104
+ * is nothing to protect against.
105
+ */
106
+ export declare function planRemoval(turns: readonly Turn[], keepRecent: number, guards: RemovalGuards, isExistingSummary?: (turn: Turn) => boolean): RemovalPlan;
107
+ /** Total characters of message content in a window. Exact; not tokens. */
108
+ export declare function windowChars(history: readonly LLMMessage[]): number;
109
+ //# sourceMappingURL=turns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turns.d.ts","sourceRoot":"","sources":["../../../../../src/core/agent/window/turns.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAErE;;;;GAIG;AACH,MAAM,WAAW,IAAI;IACnB,8CAA8C;IAC9C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,uDAAuD;IACvD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,sCAAsC;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,SAAS,UAAU,EAAE,CAAC;CAC1C;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,GAAG,SAAS,IAAI,EAAE,CAqB5E;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,0DAA0D;IAC1D,QAAQ,CAAC,eAAe,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC9C,8DAA8D;IAC9D,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,8EAA8E;IAC9E,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,qEAAqE;AACrE,wBAAgB,eAAe,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,GAAG,WAAW,CAAC,MAAM,CAAC,CAMnF;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,GAAG,mBAAmB,GAAG,SAAS,CAkB7F;AAED,oFAAoF;AACpF,MAAM,WAAW,WAAW;IAC1B,oEAAoE;IACpE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;CAC7C;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,SAAS,IAAI,EAAE,EACtB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,aAAa,EACrB,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,GAC1C,WAAW,CA8Cb;AAED,0EAA0E;AAC1E,wBAAgB,WAAW,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,GAAG,MAAM,CAIlE"}