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.
- package/AGENTS.md +1 -1
- package/CLAUDE.md +2 -2
- package/ai-instructions/claude-code/SKILL.md +1 -1
- package/dist/conventions.js +8 -6
- package/dist/conventions.js.map +1 -1
- package/dist/core/Agent.js +81 -27
- package/dist/core/Agent.js.map +1 -1
- package/dist/core/RunnerBase.js +16 -1
- package/dist/core/RunnerBase.js.map +1 -1
- package/dist/core/agent/AgentBuilder.js +209 -43
- package/dist/core/agent/AgentBuilder.js.map +1 -1
- package/dist/core/agent/buildAgentChart.js +8 -8
- package/dist/core/agent/buildAgentChart.js.map +1 -1
- package/dist/core/agent/buildDynamicAgentChart.js +6 -6
- package/dist/core/agent/buildDynamicAgentChart.js.map +1 -1
- package/dist/core/agent/middleware/errors.js +54 -0
- package/dist/core/agent/middleware/errors.js.map +1 -0
- package/dist/core/agent/middleware/index.js +23 -0
- package/dist/core/agent/middleware/index.js.map +1 -0
- package/dist/core/agent/middleware/ledger.js +61 -0
- package/dist/core/agent/middleware/ledger.js.map +1 -0
- package/dist/core/agent/middleware/outcomes.js +66 -0
- package/dist/core/agent/middleware/outcomes.js.map +1 -0
- package/dist/core/agent/middleware/runChain.js +144 -0
- package/dist/core/agent/middleware/runChain.js.map +1 -0
- package/dist/core/agent/middleware/types.js +41 -0
- package/dist/core/agent/middleware/types.js.map +1 -0
- package/dist/core/agent/stages/prepareFinal.js +10 -0
- package/dist/core/agent/stages/prepareFinal.js.map +1 -1
- package/dist/core/agent/stages/route.js +62 -1
- package/dist/core/agent/stages/route.js.map +1 -1
- package/dist/core/agent/stages/seed.js +130 -85
- package/dist/core/agent/stages/seed.js.map +1 -1
- package/dist/core/agent/stages/toolCalls.js +195 -8
- package/dist/core/agent/stages/toolCalls.js.map +1 -1
- package/dist/core/agent/stages/window.js +141 -0
- package/dist/core/agent/stages/window.js.map +1 -0
- package/dist/core/agent/window/errors.js.map +1 -0
- package/dist/core/agent/window/index.js +36 -0
- package/dist/core/agent/window/index.js.map +1 -0
- package/dist/core/agent/window/notice.js +57 -0
- package/dist/core/agent/window/notice.js.map +1 -0
- package/dist/core/agent/window/options.js +93 -0
- package/dist/core/agent/window/options.js.map +1 -0
- package/dist/core/agent/window/removal.js +45 -0
- package/dist/core/agent/window/removal.js.map +1 -0
- package/dist/core/agent/window/strategies/drop.js +106 -0
- package/dist/core/agent/window/strategies/drop.js.map +1 -0
- package/dist/core/agent/window/strategies/slidingWindow.js +87 -0
- package/dist/core/agent/window/strategies/slidingWindow.js.map +1 -0
- package/dist/core/agent/window/strategies/summarizeOldest.js +178 -0
- package/dist/core/agent/window/strategies/summarizeOldest.js.map +1 -0
- package/dist/core/agent/window/strategies/tokenBudget.js +95 -0
- package/dist/core/agent/window/strategies/tokenBudget.js.map +1 -0
- package/dist/core/agent/window/strategy.js +42 -0
- package/dist/core/agent/window/strategy.js.map +1 -0
- package/dist/core/agent/window/summarize.js.map +1 -0
- package/dist/core/agent/{compaction → window}/turns.js +50 -28
- package/dist/core/agent/window/turns.js.map +1 -0
- package/dist/core/agent/window/types.js +23 -0
- package/dist/core/agent/window/types.js.map +1 -0
- package/dist/core/pause.js +19 -1
- package/dist/core/pause.js.map +1 -1
- package/dist/esm/conventions.d.ts +8 -6
- package/dist/esm/conventions.js +8 -6
- package/dist/esm/conventions.js.map +1 -1
- package/dist/esm/core/Agent.d.ts +14 -6
- package/dist/esm/core/Agent.js +82 -28
- package/dist/esm/core/Agent.js.map +1 -1
- package/dist/esm/core/RunnerBase.js +16 -1
- package/dist/esm/core/RunnerBase.js.map +1 -1
- package/dist/esm/core/agent/AgentBuilder.d.ts +157 -4
- package/dist/esm/core/agent/AgentBuilder.js +209 -43
- package/dist/esm/core/agent/AgentBuilder.js.map +1 -1
- package/dist/esm/core/agent/buildAgentChart.d.ts +16 -9
- package/dist/esm/core/agent/buildAgentChart.js +8 -8
- package/dist/esm/core/agent/buildAgentChart.js.map +1 -1
- package/dist/esm/core/agent/buildDynamicAgentChart.js +6 -6
- package/dist/esm/core/agent/buildDynamicAgentChart.js.map +1 -1
- package/dist/esm/core/agent/middleware/errors.d.ts +51 -0
- package/dist/esm/core/agent/middleware/errors.js +50 -0
- package/dist/esm/core/agent/middleware/errors.js.map +1 -0
- package/dist/esm/core/agent/middleware/index.d.ts +16 -0
- package/dist/esm/core/agent/middleware/index.js +16 -0
- package/dist/esm/core/agent/middleware/index.js.map +1 -0
- package/dist/esm/core/agent/middleware/ledger.d.ts +40 -0
- package/dist/esm/core/agent/middleware/ledger.js +57 -0
- package/dist/esm/core/agent/middleware/ledger.js.map +1 -0
- package/dist/esm/core/agent/middleware/outcomes.d.ts +45 -0
- package/dist/esm/core/agent/middleware/outcomes.js +60 -0
- package/dist/esm/core/agent/middleware/outcomes.js.map +1 -0
- package/dist/esm/core/agent/middleware/runChain.d.ts +104 -0
- package/dist/esm/core/agent/middleware/runChain.js +139 -0
- package/dist/esm/core/agent/middleware/runChain.js.map +1 -0
- package/dist/esm/core/agent/middleware/types.d.ts +191 -0
- package/dist/esm/core/agent/middleware/types.js +40 -0
- package/dist/esm/core/agent/middleware/types.js.map +1 -0
- package/dist/esm/core/agent/stages/prepareFinal.d.ts +10 -0
- package/dist/esm/core/agent/stages/prepareFinal.js +10 -0
- package/dist/esm/core/agent/stages/prepareFinal.js.map +1 -1
- package/dist/esm/core/agent/stages/route.d.ts +29 -0
- package/dist/esm/core/agent/stages/route.js +60 -0
- package/dist/esm/core/agent/stages/route.js.map +1 -1
- package/dist/esm/core/agent/stages/seed.d.ts +16 -1
- package/dist/esm/core/agent/stages/seed.js +130 -85
- package/dist/esm/core/agent/stages/seed.js.map +1 -1
- package/dist/esm/core/agent/stages/toolCalls.d.ts +23 -0
- package/dist/esm/core/agent/stages/toolCalls.js +195 -8
- package/dist/esm/core/agent/stages/toolCalls.js.map +1 -1
- package/dist/esm/core/agent/stages/window.d.ts +63 -0
- package/dist/esm/core/agent/stages/window.js +137 -0
- package/dist/esm/core/agent/stages/window.js.map +1 -0
- package/dist/esm/core/agent/types.d.ts +33 -8
- package/dist/esm/core/agent/window/errors.js.map +1 -0
- package/dist/esm/core/agent/window/index.d.ts +27 -0
- package/dist/esm/core/agent/window/index.js +25 -0
- package/dist/esm/core/agent/window/index.js.map +1 -0
- package/dist/esm/core/agent/window/notice.d.ts +46 -0
- package/dist/esm/core/agent/window/notice.js +52 -0
- package/dist/esm/core/agent/window/notice.js.map +1 -0
- package/dist/esm/core/agent/window/options.d.ts +33 -0
- package/dist/esm/core/agent/window/options.js +87 -0
- package/dist/esm/core/agent/window/options.js.map +1 -0
- package/dist/esm/core/agent/window/removal.d.ts +22 -0
- package/dist/esm/core/agent/window/removal.js +40 -0
- package/dist/esm/core/agent/window/removal.js.map +1 -0
- package/dist/esm/core/agent/window/strategies/drop.d.ts +54 -0
- package/dist/esm/core/agent/window/strategies/drop.js +102 -0
- package/dist/esm/core/agent/window/strategies/drop.js.map +1 -0
- package/dist/esm/core/agent/window/strategies/slidingWindow.d.ts +48 -0
- package/dist/esm/core/agent/window/strategies/slidingWindow.js +83 -0
- package/dist/esm/core/agent/window/strategies/slidingWindow.js.map +1 -0
- package/dist/esm/core/agent/window/strategies/summarizeOldest.d.ts +42 -0
- package/dist/esm/core/agent/window/strategies/summarizeOldest.js +174 -0
- package/dist/esm/core/agent/window/strategies/summarizeOldest.js.map +1 -0
- package/dist/esm/core/agent/window/strategies/tokenBudget.d.ts +47 -0
- package/dist/esm/core/agent/window/strategies/tokenBudget.js +91 -0
- package/dist/esm/core/agent/window/strategies/tokenBudget.js.map +1 -0
- package/dist/esm/core/agent/window/strategy.d.ts +181 -0
- package/dist/esm/core/agent/window/strategy.js +41 -0
- package/dist/esm/core/agent/window/strategy.js.map +1 -0
- package/dist/esm/core/agent/window/summarize.js.map +1 -0
- package/dist/esm/core/agent/window/turns.d.ts +108 -0
- package/dist/esm/core/agent/{compaction → window}/turns.js +48 -26
- package/dist/esm/core/agent/window/turns.js.map +1 -0
- package/dist/esm/core/agent/window/types.d.ts +263 -0
- package/dist/esm/core/agent/window/types.js +22 -0
- package/dist/esm/core/agent/window/types.js.map +1 -0
- package/dist/esm/core/pause.d.ts +42 -0
- package/dist/esm/core/pause.js +17 -0
- package/dist/esm/core/pause.js.map +1 -1
- package/dist/esm/events/dispatcher.d.ts +1 -1
- package/dist/esm/events/dispatcher.js.map +1 -1
- package/dist/esm/events/payloads.d.ts +26 -0
- package/dist/esm/events/registry.d.ts +5 -1
- package/dist/esm/events/registry.js +4 -0
- package/dist/esm/events/registry.js.map +1 -1
- package/dist/esm/index.d.ts +3 -2
- package/dist/esm/index.js +23 -6
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/mcp/mcpServe.js +39 -6
- package/dist/esm/lib/mcp/mcpServe.js.map +1 -1
- package/dist/esm/lib/mcp/types.d.ts +16 -0
- package/dist/esm/recorders/core/CompactionMeter.d.ts +25 -19
- package/dist/esm/recorders/core/CompactionMeter.js +27 -19
- package/dist/esm/recorders/core/CompactionMeter.js.map +1 -1
- package/dist/events/dispatcher.js.map +1 -1
- package/dist/events/registry.js +4 -0
- package/dist/events/registry.js.map +1 -1
- package/dist/index.js +40 -13
- package/dist/index.js.map +1 -1
- package/dist/lib/mcp/mcpServe.js +39 -6
- package/dist/lib/mcp/mcpServe.js.map +1 -1
- package/dist/recorders/core/CompactionMeter.js +27 -19
- package/dist/recorders/core/CompactionMeter.js.map +1 -1
- package/dist/types/conventions.d.ts +8 -6
- package/dist/types/conventions.d.ts.map +1 -1
- package/dist/types/core/Agent.d.ts +14 -6
- package/dist/types/core/Agent.d.ts.map +1 -1
- package/dist/types/core/RunnerBase.d.ts.map +1 -1
- package/dist/types/core/agent/AgentBuilder.d.ts +157 -4
- package/dist/types/core/agent/AgentBuilder.d.ts.map +1 -1
- package/dist/types/core/agent/buildAgentChart.d.ts +16 -9
- package/dist/types/core/agent/buildAgentChart.d.ts.map +1 -1
- package/dist/types/core/agent/middleware/errors.d.ts +52 -0
- package/dist/types/core/agent/middleware/errors.d.ts.map +1 -0
- package/dist/types/core/agent/middleware/index.d.ts +17 -0
- package/dist/types/core/agent/middleware/index.d.ts.map +1 -0
- package/dist/types/core/agent/middleware/ledger.d.ts +41 -0
- package/dist/types/core/agent/middleware/ledger.d.ts.map +1 -0
- package/dist/types/core/agent/middleware/outcomes.d.ts +46 -0
- package/dist/types/core/agent/middleware/outcomes.d.ts.map +1 -0
- package/dist/types/core/agent/middleware/runChain.d.ts +105 -0
- package/dist/types/core/agent/middleware/runChain.d.ts.map +1 -0
- package/dist/types/core/agent/middleware/types.d.ts +192 -0
- package/dist/types/core/agent/middleware/types.d.ts.map +1 -0
- package/dist/types/core/agent/stages/prepareFinal.d.ts +10 -0
- package/dist/types/core/agent/stages/prepareFinal.d.ts.map +1 -1
- package/dist/types/core/agent/stages/route.d.ts +29 -0
- package/dist/types/core/agent/stages/route.d.ts.map +1 -1
- package/dist/types/core/agent/stages/seed.d.ts +16 -1
- package/dist/types/core/agent/stages/seed.d.ts.map +1 -1
- package/dist/types/core/agent/stages/toolCalls.d.ts +23 -0
- package/dist/types/core/agent/stages/toolCalls.d.ts.map +1 -1
- package/dist/types/core/agent/stages/window.d.ts +64 -0
- package/dist/types/core/agent/stages/window.d.ts.map +1 -0
- package/dist/types/core/agent/types.d.ts +33 -8
- package/dist/types/core/agent/types.d.ts.map +1 -1
- package/dist/types/core/agent/window/errors.d.ts.map +1 -0
- package/dist/types/core/agent/window/index.d.ts +28 -0
- package/dist/types/core/agent/window/index.d.ts.map +1 -0
- package/dist/types/core/agent/window/notice.d.ts +47 -0
- package/dist/types/core/agent/window/notice.d.ts.map +1 -0
- package/dist/types/core/agent/window/options.d.ts +34 -0
- package/dist/types/core/agent/window/options.d.ts.map +1 -0
- package/dist/types/core/agent/window/removal.d.ts +23 -0
- package/dist/types/core/agent/window/removal.d.ts.map +1 -0
- package/dist/types/core/agent/window/strategies/drop.d.ts +55 -0
- package/dist/types/core/agent/window/strategies/drop.d.ts.map +1 -0
- package/dist/types/core/agent/window/strategies/slidingWindow.d.ts +49 -0
- package/dist/types/core/agent/window/strategies/slidingWindow.d.ts.map +1 -0
- package/dist/types/core/agent/window/strategies/summarizeOldest.d.ts +43 -0
- package/dist/types/core/agent/window/strategies/summarizeOldest.d.ts.map +1 -0
- package/dist/types/core/agent/window/strategies/tokenBudget.d.ts +48 -0
- package/dist/types/core/agent/window/strategies/tokenBudget.d.ts.map +1 -0
- package/dist/types/core/agent/window/strategy.d.ts +182 -0
- package/dist/types/core/agent/window/strategy.d.ts.map +1 -0
- package/dist/types/core/agent/window/summarize.d.ts.map +1 -0
- package/dist/types/core/agent/window/turns.d.ts +109 -0
- package/dist/types/core/agent/window/turns.d.ts.map +1 -0
- package/dist/types/core/agent/window/types.d.ts +264 -0
- package/dist/types/core/agent/window/types.d.ts.map +1 -0
- package/dist/types/core/pause.d.ts +42 -0
- package/dist/types/core/pause.d.ts.map +1 -1
- package/dist/types/events/dispatcher.d.ts +1 -1
- package/dist/types/events/dispatcher.d.ts.map +1 -1
- package/dist/types/events/payloads.d.ts +26 -0
- package/dist/types/events/payloads.d.ts.map +1 -1
- package/dist/types/events/registry.d.ts +5 -1
- package/dist/types/events/registry.d.ts.map +1 -1
- package/dist/types/index.d.ts +3 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/lib/mcp/mcpServe.d.ts.map +1 -1
- package/dist/types/lib/mcp/types.d.ts +16 -0
- package/dist/types/lib/mcp/types.d.ts.map +1 -1
- package/dist/types/recorders/core/CompactionMeter.d.ts +25 -19
- package/dist/types/recorders/core/CompactionMeter.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/core/agent/compaction/errors.js.map +0 -1
- package/dist/core/agent/compaction/index.js +0 -24
- package/dist/core/agent/compaction/index.js.map +0 -1
- package/dist/core/agent/compaction/strategy.js +0 -152
- package/dist/core/agent/compaction/strategy.js.map +0 -1
- package/dist/core/agent/compaction/summarize.js.map +0 -1
- package/dist/core/agent/compaction/turns.js.map +0 -1
- package/dist/core/agent/compaction/types.js +0 -21
- package/dist/core/agent/compaction/types.js.map +0 -1
- package/dist/core/agent/stages/compact.js +0 -130
- package/dist/core/agent/stages/compact.js.map +0 -1
- package/dist/esm/core/agent/compaction/errors.js.map +0 -1
- package/dist/esm/core/agent/compaction/index.d.ts +0 -18
- package/dist/esm/core/agent/compaction/index.js +0 -18
- package/dist/esm/core/agent/compaction/index.js.map +0 -1
- package/dist/esm/core/agent/compaction/strategy.d.ts +0 -103
- package/dist/esm/core/agent/compaction/strategy.js +0 -148
- package/dist/esm/core/agent/compaction/strategy.js.map +0 -1
- package/dist/esm/core/agent/compaction/summarize.js.map +0 -1
- package/dist/esm/core/agent/compaction/turns.d.ts +0 -85
- package/dist/esm/core/agent/compaction/turns.js.map +0 -1
- package/dist/esm/core/agent/compaction/types.d.ts +0 -148
- package/dist/esm/core/agent/compaction/types.js +0 -20
- package/dist/esm/core/agent/compaction/types.js.map +0 -1
- package/dist/esm/core/agent/stages/compact.d.ts +0 -59
- package/dist/esm/core/agent/stages/compact.js +0 -126
- package/dist/esm/core/agent/stages/compact.js.map +0 -1
- package/dist/types/core/agent/compaction/errors.d.ts.map +0 -1
- package/dist/types/core/agent/compaction/index.d.ts +0 -19
- package/dist/types/core/agent/compaction/index.d.ts.map +0 -1
- package/dist/types/core/agent/compaction/strategy.d.ts +0 -104
- package/dist/types/core/agent/compaction/strategy.d.ts.map +0 -1
- package/dist/types/core/agent/compaction/summarize.d.ts.map +0 -1
- package/dist/types/core/agent/compaction/turns.d.ts +0 -86
- package/dist/types/core/agent/compaction/turns.d.ts.map +0 -1
- package/dist/types/core/agent/compaction/types.d.ts +0 -149
- package/dist/types/core/agent/compaction/types.d.ts.map +0 -1
- package/dist/types/core/agent/stages/compact.d.ts +0 -60
- package/dist/types/core/agent/stages/compact.d.ts.map +0 -1
- /package/dist/core/agent/{compaction → window}/errors.js +0 -0
- /package/dist/core/agent/{compaction → window}/summarize.js +0 -0
- /package/dist/esm/core/agent/{compaction → window}/errors.d.ts +0 -0
- /package/dist/esm/core/agent/{compaction → window}/errors.js +0 -0
- /package/dist/esm/core/agent/{compaction → window}/summarize.d.ts +0 -0
- /package/dist/esm/core/agent/{compaction → window}/summarize.js +0 -0
- /package/dist/types/core/agent/{compaction → window}/errors.d.ts +0 -0
- /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"}
|