agentfootprint 7.16.0 → 7.17.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/dist/conventions.js +8 -6
- package/dist/conventions.js.map +1 -1
- package/dist/core/Agent.js +31 -26
- package/dist/core/Agent.js.map +1 -1
- package/dist/core/agent/AgentBuilder.js +93 -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/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/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 +6 -6
- package/dist/esm/core/Agent.js +31 -26
- package/dist/esm/core/Agent.js.map +1 -1
- package/dist/esm/core/agent/AgentBuilder.d.ts +60 -4
- package/dist/esm/core/agent/AgentBuilder.js +93 -43
- package/dist/esm/core/agent/AgentBuilder.js.map +1 -1
- package/dist/esm/core/agent/buildAgentChart.d.ts +14 -7
- 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/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 +15 -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/index.d.ts +1 -1
- package/dist/esm/index.js +10 -5
- package/dist/esm/index.js.map +1 -1
- 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/index.js +17 -7
- package/dist/index.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 +6 -6
- package/dist/types/core/Agent.d.ts.map +1 -1
- package/dist/types/core/agent/AgentBuilder.d.ts +60 -4
- package/dist/types/core/agent/AgentBuilder.d.ts.map +1 -1
- package/dist/types/core/agent/buildAgentChart.d.ts +14 -7
- package/dist/types/core/agent/buildAgentChart.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 +15 -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/index.d.ts +1 -1
- package/dist/types/index.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,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* slidingWindow — keep the last N turns, drop what is older.
|
|
4
|
+
*
|
|
5
|
+
* Pattern: WindowStrategy implementation. Its own module, registering
|
|
6
|
+
* nothing at import.
|
|
7
|
+
* Role: core/ layer.
|
|
8
|
+
* Emits: N/A — the stage emits, records and costs; this file decides.
|
|
9
|
+
*
|
|
10
|
+
* The market's simplest window policy (LangChain's `trim_messages`, the
|
|
11
|
+
* "last N messages" every framework ships). Two things are different here:
|
|
12
|
+
*
|
|
13
|
+
* 1. **It refuses by name.** It goes through the SAME turn segmentation and
|
|
14
|
+
* the SAME refusal engine as compaction, so it will not drop half of a
|
|
15
|
+
* `tool_use` / `tool_result` pair, will not drop an unanswered tool call
|
|
16
|
+
* whose answer may still arrive, will not drop the tool a paused run is
|
|
17
|
+
* waiting on or a pending check-in, and cannot touch the system
|
|
18
|
+
* envelope. Message-counting trimmers split those pairs and the vendor
|
|
19
|
+
* rejects the request; this one steps over them and says so in the
|
|
20
|
+
* record.
|
|
21
|
+
* 2. **It says what it dropped.** Every dropped message is an eviction
|
|
22
|
+
* event with its measured lifetime, and the record names the stage ids
|
|
23
|
+
* the messages came from. The turns themselves stay in the commit log,
|
|
24
|
+
* byte for byte.
|
|
25
|
+
*
|
|
26
|
+
* It triggers on turn COUNT, not tokens — so it needs no summarizer, makes no
|
|
27
|
+
* LLM call, and runs on ANY provider, including the ones that report no usage
|
|
28
|
+
* at all. Nothing here is unmeasurable, so nothing here throws.
|
|
29
|
+
*/
|
|
30
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
|
+
exports.slidingWindow = exports.SLIDING_WINDOW = void 0;
|
|
32
|
+
const drop_js_1 = require("./drop.js");
|
|
33
|
+
const options_js_1 = require("../options.js");
|
|
34
|
+
/** `WindowRecord.strategy` written by every record this strategy files. */
|
|
35
|
+
exports.SLIDING_WINDOW = 'sliding-window';
|
|
36
|
+
/**
|
|
37
|
+
* Keep the most recent `keepRecentTurns` turns in the live window and drop
|
|
38
|
+
* the older ones — except anything that refuses.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* import { Agent, slidingWindow } from 'agentfootprint';
|
|
43
|
+
* import { ollama } from 'agentfootprint/llm-providers';
|
|
44
|
+
*
|
|
45
|
+
* // Works on a provider that reports no usage at all: the trigger is turns.
|
|
46
|
+
* const agent = Agent.create({ provider: ollama(), model: 'llama3' })
|
|
47
|
+
* .window(slidingWindow({ keepRecentTurns: 12 }))
|
|
48
|
+
* .build();
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
function slidingWindow(options) {
|
|
52
|
+
const config = (0, options_js_1.resolveSlidingWindowOptions)(options, 'slidingWindow');
|
|
53
|
+
return {
|
|
54
|
+
name: exports.SLIDING_WINDOW,
|
|
55
|
+
async plan(input) {
|
|
56
|
+
// Did not engage: the window is already within its target depth. No
|
|
57
|
+
// record — the ledger tracks what this strategy DID, not every time it
|
|
58
|
+
// looked and there was nothing to do.
|
|
59
|
+
if (input.turns.length <= config.keepRecentTurns)
|
|
60
|
+
return undefined;
|
|
61
|
+
const outcome = (0, drop_js_1.dropOldestSpan)(input, config.keepRecentTurns, exports.SLIDING_WINDOW);
|
|
62
|
+
const record = {
|
|
63
|
+
strategy: exports.SLIDING_WINDOW,
|
|
64
|
+
iteration: input.iteration,
|
|
65
|
+
keepRecentTurns: config.keepRecentTurns,
|
|
66
|
+
removedStageIds: outcome.removedStageIds,
|
|
67
|
+
removedMessageCount: outcome.removedMessageCount,
|
|
68
|
+
windowCharsBefore: outcome.windowCharsBefore,
|
|
69
|
+
windowCharsAfter: outcome.windowCharsAfter,
|
|
70
|
+
turnsBefore: outcome.turnsBefore,
|
|
71
|
+
turnsAfter: outcome.turnsAfter,
|
|
72
|
+
refusals: outcome.refusals,
|
|
73
|
+
};
|
|
74
|
+
// No `budgetPressure`: this strategy has no token budget. Reporting a
|
|
75
|
+
// cap nobody configured would be the invented number the family exists
|
|
76
|
+
// to refuse — so it reports evictions and stays quiet about budgets.
|
|
77
|
+
return {
|
|
78
|
+
...(outcome.window !== undefined && { window: outcome.window }),
|
|
79
|
+
...(outcome.rebase !== undefined && { rebase: outcome.rebase }),
|
|
80
|
+
record,
|
|
81
|
+
evictions: outcome.evictions,
|
|
82
|
+
};
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
exports.slidingWindow = slidingWindow;
|
|
87
|
+
//# sourceMappingURL=slidingWindow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slidingWindow.js","sourceRoot":"","sources":["../../../../../src/core/agent/window/strategies/slidingWindow.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;;;AAEH,uCAA2C;AAC3C,8CAA4D;AAI5D,2EAA2E;AAC9D,QAAA,cAAc,GAAG,gBAAgB,CAAC;AAE/C;;;;;;;;;;;;;;GAcG;AACH,SAAgB,aAAa,CAAC,OAA6B;IACzD,MAAM,MAAM,GAAG,IAAA,wCAA2B,EAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAErE,OAAO;QACL,IAAI,EAAE,sBAAc;QAEpB,KAAK,CAAC,IAAI,CAAC,KAA0B;YACnC,oEAAoE;YACpE,uEAAuE;YACvE,sCAAsC;YACtC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,IAAI,MAAM,CAAC,eAAe;gBAAE,OAAO,SAAS,CAAC;YAEnE,MAAM,OAAO,GAAG,IAAA,wBAAc,EAAC,KAAK,EAAE,MAAM,CAAC,eAAe,EAAE,sBAAc,CAAC,CAAC;YAC9E,MAAM,MAAM,GAAwB;gBAClC,QAAQ,EAAE,sBAAc;gBACxB,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,eAAe,EAAE,MAAM,CAAC,eAAe;gBACvC,eAAe,EAAE,OAAO,CAAC,eAAe;gBACxC,mBAAmB,EAAE,OAAO,CAAC,mBAAmB;gBAChD,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;gBAC5C,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;gBAC1C,WAAW,EAAE,OAAO,CAAC,WAAW;gBAChC,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,QAAQ,EAAE,OAAO,CAAC,QAAQ;aAC3B,CAAC;YAEF,sEAAsE;YACtE,uEAAuE;YACvE,qEAAqE;YACrE,OAAO;gBACL,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;gBAC/D,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;gBAC/D,MAAM;gBACN,SAAS,EAAE,OAAO,CAAC,SAAS;aAC7B,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC;AArCD,sCAqCC"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* summarizeOldest — fold the oldest foldable turns into one summary message.
|
|
4
|
+
*
|
|
5
|
+
* Pattern: WindowStrategy implementation. Its own module, importing nothing
|
|
6
|
+
* that registers anything, so a bundle that never mentions it never
|
|
7
|
+
* carries it (and never carries the summarizer machinery either).
|
|
8
|
+
* Role: core/ layer.
|
|
9
|
+
* Emits: N/A — the stage emits, records and costs; this file decides.
|
|
10
|
+
*
|
|
11
|
+
* This is what `.compaction({...})` configures, and the market's familiar
|
|
12
|
+
* move (Claude Code / the Claude Agent SDK call it compaction). What is
|
|
13
|
+
* different here is not the fold — it is that the fold is filed as a claim:
|
|
14
|
+
* a summary is a claim ABOUT the past, and the past itself stays in the
|
|
15
|
+
* commit log, byte for byte.
|
|
16
|
+
*
|
|
17
|
+
* Everything it decides, it explains. Every engaged path returns a record —
|
|
18
|
+
* including the paths that change nothing, which are the ones a person
|
|
19
|
+
* debugging an over-budget window actually needs.
|
|
20
|
+
*/
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.summarizeOldest = exports.SUMMARIZE_OLDEST = void 0;
|
|
23
|
+
const errors_js_1 = require("../errors.js");
|
|
24
|
+
const options_js_1 = require("../options.js");
|
|
25
|
+
const removal_js_1 = require("../removal.js");
|
|
26
|
+
const summarize_js_1 = require("../summarize.js");
|
|
27
|
+
const turns_js_1 = require("../turns.js");
|
|
28
|
+
/** `WindowRecord.strategy` written by every record this strategy files. */
|
|
29
|
+
exports.SUMMARIZE_OLDEST = 'summarize-oldest';
|
|
30
|
+
/**
|
|
31
|
+
* Fold the oldest contiguous run of foldable turns into one summary message,
|
|
32
|
+
* keeping the recent turns and stepping over anything unresolved.
|
|
33
|
+
*
|
|
34
|
+
* Triggered by COUNTED tokens: the last call's adapter-reported input tokens
|
|
35
|
+
* against `thresholdTokens`. A provider that reports no usage gets
|
|
36
|
+
* `CompactionUnmeasurableError` rather than an invented number.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```ts
|
|
40
|
+
* import { Agent, summarizeOldest } from 'agentfootprint';
|
|
41
|
+
*
|
|
42
|
+
* const agent = Agent.create({ provider: anthropic(), model: 'claude-sonnet-4-5' })
|
|
43
|
+
* .window(summarizeOldest({ thresholdTokens: 120_000, summarizer: anthropic() }))
|
|
44
|
+
* .build();
|
|
45
|
+
* // `.compaction({ ... })` is this exact line, spelled shorter.
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
function summarizeOldest(options) {
|
|
49
|
+
const config = (0, options_js_1.resolveCompactionOptions)(options, 'summarizeOldest');
|
|
50
|
+
return {
|
|
51
|
+
name: exports.SUMMARIZE_OLDEST,
|
|
52
|
+
async plan(input) {
|
|
53
|
+
const { history, turns, iteration, measured } = input;
|
|
54
|
+
// Iteration 1: nothing has been sent, so nothing has been counted. A
|
|
55
|
+
// compactor that acted here would be guessing.
|
|
56
|
+
if (measured === undefined)
|
|
57
|
+
return undefined;
|
|
58
|
+
if (measured.input === 0 && measured.output === 0) {
|
|
59
|
+
throw new errors_js_1.CompactionUnmeasurableError(input.providerName);
|
|
60
|
+
}
|
|
61
|
+
if (measured.input <= config.thresholdTokens)
|
|
62
|
+
return undefined;
|
|
63
|
+
const model = config.model ?? input.agentModel;
|
|
64
|
+
const charsBefore = (0, turns_js_1.windowChars)(history);
|
|
65
|
+
const base = {
|
|
66
|
+
strategy: exports.SUMMARIZE_OLDEST,
|
|
67
|
+
iteration,
|
|
68
|
+
measuredTokens: measured.input,
|
|
69
|
+
thresholdTokens: config.thresholdTokens,
|
|
70
|
+
overBudget: true,
|
|
71
|
+
windowCharsBefore: charsBefore,
|
|
72
|
+
};
|
|
73
|
+
const unchanged = (refusals, extra = {}) => ({
|
|
74
|
+
record: {
|
|
75
|
+
...base,
|
|
76
|
+
removedStageIds: [],
|
|
77
|
+
removedMessageCount: 0,
|
|
78
|
+
foldedStageIds: [],
|
|
79
|
+
foldedMessageCount: 0,
|
|
80
|
+
windowCharsAfter: charsBefore,
|
|
81
|
+
summaryChars: 0,
|
|
82
|
+
refusals,
|
|
83
|
+
...extra,
|
|
84
|
+
},
|
|
85
|
+
evictions: [],
|
|
86
|
+
budgetPressure: {
|
|
87
|
+
capTokens: config.thresholdTokens,
|
|
88
|
+
projectedTokens: measured.input,
|
|
89
|
+
planAction: 'none',
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
const plan = input.planRemoval(config.keepRecentTurns, (turn) => (0, summarize_js_1.isCompactedSummary)(turn.messages[0]));
|
|
93
|
+
if (plan.from === -1) {
|
|
94
|
+
// Nothing foldable. The window stays over budget and the run proceeds
|
|
95
|
+
// — reported, not silently truncated.
|
|
96
|
+
return unchanged(plan.refusals);
|
|
97
|
+
}
|
|
98
|
+
const spanStart = turns[plan.from].start;
|
|
99
|
+
const spanEnd = turns[plan.to].start + turns[plan.to].length;
|
|
100
|
+
const head = history.slice(0, spanStart);
|
|
101
|
+
const span = history.slice(spanStart, spanEnd);
|
|
102
|
+
const tail = history.slice(spanEnd);
|
|
103
|
+
// A broken summarizer must not take down the run.
|
|
104
|
+
let summary;
|
|
105
|
+
try {
|
|
106
|
+
const result = await (0, summarize_js_1.runSummarizer)(config.summarizer, model, span, input.signal);
|
|
107
|
+
summary = {
|
|
108
|
+
text: result.text,
|
|
109
|
+
usage: { input: result.usage.input, output: result.usage.output },
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
return {
|
|
114
|
+
...unchanged([
|
|
115
|
+
{ reason: 'summarizer-failed', turnIndex: plan.from, messageIndex: spanStart },
|
|
116
|
+
...plan.refusals,
|
|
117
|
+
]),
|
|
118
|
+
warning: `the summarizer threw, so nothing was folded this iteration and the window ` +
|
|
119
|
+
`stays over budget (${measured.input} tokens vs a threshold of ` +
|
|
120
|
+
`${config.thresholdTokens}). The run continues. Cause: ` +
|
|
121
|
+
`${err instanceof Error ? err.message : String(err)}`,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
const summaryMessage = (0, summarize_js_1.buildSummaryMessage)(summary.text, {
|
|
125
|
+
foldedMessageCount: span.length,
|
|
126
|
+
iteration,
|
|
127
|
+
model,
|
|
128
|
+
});
|
|
129
|
+
const spend = { model, usage: summary.usage };
|
|
130
|
+
// Would the fold actually help? A summary plus its authored frame can be
|
|
131
|
+
// LONGER than a handful of short turns; folding then spends a call to
|
|
132
|
+
// grow the window and lose detail at the same time. Both sides are
|
|
133
|
+
// measured in chars — one unit, an exact comparison, not a token guess.
|
|
134
|
+
if (summaryMessage.content.length >= (0, turns_js_1.windowChars)(span)) {
|
|
135
|
+
return {
|
|
136
|
+
...unchanged([
|
|
137
|
+
{ reason: 'summary-not-smaller', turnIndex: plan.from, messageIndex: spanStart },
|
|
138
|
+
...plan.refusals,
|
|
139
|
+
], { summaryChars: summaryMessage.content.length, summarizerTokens: summary.usage }),
|
|
140
|
+
spend, // the call still happened, so it still counts
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
const foldedAtMs = input.now();
|
|
144
|
+
const facts = input.removalFacts((0, removal_js_1.indexRange)(spanStart, spanEnd), foldedAtMs);
|
|
145
|
+
const window = [...head, summaryMessage, ...tail];
|
|
146
|
+
const record = {
|
|
147
|
+
...base,
|
|
148
|
+
removedStageIds: facts.removedStageIds,
|
|
149
|
+
removedMessageCount: span.length,
|
|
150
|
+
// The 7.16 names for the two values above, kept and deprecated.
|
|
151
|
+
foldedStageIds: facts.removedStageIds,
|
|
152
|
+
foldedMessageCount: span.length,
|
|
153
|
+
windowCharsAfter: (0, turns_js_1.windowChars)(window),
|
|
154
|
+
summaryChars: summaryMessage.content.length,
|
|
155
|
+
summarizerTokens: summary.usage,
|
|
156
|
+
refusals: plan.refusals,
|
|
157
|
+
};
|
|
158
|
+
return {
|
|
159
|
+
window,
|
|
160
|
+
rebase: {
|
|
161
|
+
headCount: head.length,
|
|
162
|
+
keptTailCount: tail.length,
|
|
163
|
+
insertedAtMs: foldedAtMs,
|
|
164
|
+
},
|
|
165
|
+
record,
|
|
166
|
+
evictions: facts.evictions,
|
|
167
|
+
budgetPressure: {
|
|
168
|
+
capTokens: config.thresholdTokens,
|
|
169
|
+
projectedTokens: measured.input,
|
|
170
|
+
planAction: 'summarize',
|
|
171
|
+
},
|
|
172
|
+
spend,
|
|
173
|
+
};
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
exports.summarizeOldest = summarizeOldest;
|
|
178
|
+
//# sourceMappingURL=summarizeOldest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summarizeOldest.js","sourceRoot":"","sources":["../../../../../src/core/agent/window/strategies/summarizeOldest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* tokenBudget — compaction's trigger discipline, without the summarizer.
|
|
4
|
+
*
|
|
5
|
+
* Pattern: WindowStrategy implementation. Its own module, registering
|
|
6
|
+
* nothing at import.
|
|
7
|
+
* Role: core/ layer.
|
|
8
|
+
* Emits: N/A — the stage emits, records and costs; this file decides.
|
|
9
|
+
*
|
|
10
|
+
* The market's other familiar policy: cap the window at a token budget
|
|
11
|
+
* (Mastra's `TokenLimiter` is the closest sibling). What is different here is
|
|
12
|
+
* the same thing that is different about compaction — the number is COUNTED,
|
|
13
|
+
* never guessed:
|
|
14
|
+
*
|
|
15
|
+
* • the trigger reads the input tokens the PROVIDER reported for the last
|
|
16
|
+
* call, not a character estimate and not a divide-by-four heuristic;
|
|
17
|
+
* • a provider that reports no usage gets `CompactionUnmeasurableError` by
|
|
18
|
+
* name, the same refusal `.compaction()` makes, rather than an invented
|
|
19
|
+
* window size or a configured budget that silently never applies.
|
|
20
|
+
*
|
|
21
|
+
* When over budget it drops the oldest contiguous removable span — the same
|
|
22
|
+
* span compaction would have folded, chosen by the same refusal engine — and
|
|
23
|
+
* writes no summary at all. Nothing is claimed about what left, because
|
|
24
|
+
* nothing was read: the record and the eviction events name it, and the
|
|
25
|
+
* commit log still has it verbatim.
|
|
26
|
+
*
|
|
27
|
+
* Use it over `summarizeOldest` when you would rather lose the old turns than
|
|
28
|
+
* pay a summarizer to paraphrase them, and over `slidingWindow` when the
|
|
29
|
+
* thing you are actually defending is a token bill rather than a turn depth.
|
|
30
|
+
*/
|
|
31
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
|
+
exports.tokenBudget = exports.TOKEN_BUDGET = void 0;
|
|
33
|
+
const drop_js_1 = require("./drop.js");
|
|
34
|
+
const errors_js_1 = require("../errors.js");
|
|
35
|
+
const options_js_1 = require("../options.js");
|
|
36
|
+
/** `WindowRecord.strategy` written by every record this strategy files. */
|
|
37
|
+
exports.TOKEN_BUDGET = 'token-budget';
|
|
38
|
+
/**
|
|
39
|
+
* Drop the oldest turns whenever the last call's adapter-reported input
|
|
40
|
+
* tokens exceed `thresholdTokens`.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* import { Agent, tokenBudget } from 'agentfootprint';
|
|
45
|
+
*
|
|
46
|
+
* const agent = Agent.create({ provider: anthropic(), model: 'claude-sonnet-4-5' })
|
|
47
|
+
* .window(tokenBudget({ thresholdTokens: 120_000 }))
|
|
48
|
+
* .build();
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
function tokenBudget(options) {
|
|
52
|
+
const config = (0, options_js_1.resolveTokenBudgetOptions)(options, 'tokenBudget');
|
|
53
|
+
return {
|
|
54
|
+
name: exports.TOKEN_BUDGET,
|
|
55
|
+
async plan(input) {
|
|
56
|
+
const { measured } = input;
|
|
57
|
+
// Iteration 1: nothing has been sent, so nothing has been counted.
|
|
58
|
+
if (measured === undefined)
|
|
59
|
+
return undefined;
|
|
60
|
+
// Counted, not guessed — the same wall compaction hits, by the same name.
|
|
61
|
+
if (measured.input === 0 && measured.output === 0) {
|
|
62
|
+
throw new errors_js_1.CompactionUnmeasurableError(input.providerName);
|
|
63
|
+
}
|
|
64
|
+
if (measured.input <= config.thresholdTokens)
|
|
65
|
+
return undefined;
|
|
66
|
+
const outcome = (0, drop_js_1.dropOldestSpan)(input, config.keepRecentTurns, exports.TOKEN_BUDGET);
|
|
67
|
+
const record = {
|
|
68
|
+
strategy: exports.TOKEN_BUDGET,
|
|
69
|
+
iteration: input.iteration,
|
|
70
|
+
measuredTokens: measured.input,
|
|
71
|
+
thresholdTokens: config.thresholdTokens,
|
|
72
|
+
overBudget: true,
|
|
73
|
+
keepRecentTurns: config.keepRecentTurns,
|
|
74
|
+
removedStageIds: outcome.removedStageIds,
|
|
75
|
+
removedMessageCount: outcome.removedMessageCount,
|
|
76
|
+
windowCharsBefore: outcome.windowCharsBefore,
|
|
77
|
+
windowCharsAfter: outcome.windowCharsAfter,
|
|
78
|
+
refusals: outcome.refusals,
|
|
79
|
+
};
|
|
80
|
+
return {
|
|
81
|
+
...(outcome.window !== undefined && { window: outcome.window }),
|
|
82
|
+
...(outcome.rebase !== undefined && { rebase: outcome.rebase }),
|
|
83
|
+
record,
|
|
84
|
+
evictions: outcome.evictions,
|
|
85
|
+
budgetPressure: {
|
|
86
|
+
capTokens: config.thresholdTokens,
|
|
87
|
+
projectedTokens: measured.input,
|
|
88
|
+
planAction: outcome.removedMessageCount > 0 ? 'evict' : 'none',
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
exports.tokenBudget = tokenBudget;
|
|
95
|
+
//# sourceMappingURL=tokenBudget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenBudget.js","sourceRoot":"","sources":["../../../../../src/core/agent/window/strategies/tokenBudget.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;;;AAEH,uCAA2C;AAC3C,4CAA2D;AAC3D,8CAA0D;AAI1D,2EAA2E;AAC9D,QAAA,YAAY,GAAG,cAAc,CAAC;AAE3C;;;;;;;;;;;;GAYG;AACH,SAAgB,WAAW,CAAC,OAA2B;IACrD,MAAM,MAAM,GAAG,IAAA,sCAAyB,EAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IAEjE,OAAO;QACL,IAAI,EAAE,oBAAY;QAElB,KAAK,CAAC,IAAI,CAAC,KAA0B;YACnC,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;YAE3B,mEAAmE;YACnE,IAAI,QAAQ,KAAK,SAAS;gBAAE,OAAO,SAAS,CAAC;YAC7C,0EAA0E;YAC1E,IAAI,QAAQ,CAAC,KAAK,KAAK,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAClD,MAAM,IAAI,uCAA2B,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YAC5D,CAAC;YACD,IAAI,QAAQ,CAAC,KAAK,IAAI,MAAM,CAAC,eAAe;gBAAE,OAAO,SAAS,CAAC;YAE/D,MAAM,OAAO,GAAG,IAAA,wBAAc,EAAC,KAAK,EAAE,MAAM,CAAC,eAAe,EAAE,oBAAY,CAAC,CAAC;YAC5E,MAAM,MAAM,GAAsB;gBAChC,QAAQ,EAAE,oBAAY;gBACtB,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,cAAc,EAAE,QAAQ,CAAC,KAAK;gBAC9B,eAAe,EAAE,MAAM,CAAC,eAAe;gBACvC,UAAU,EAAE,IAAI;gBAChB,eAAe,EAAE,MAAM,CAAC,eAAe;gBACvC,eAAe,EAAE,OAAO,CAAC,eAAe;gBACxC,mBAAmB,EAAE,OAAO,CAAC,mBAAmB;gBAChD,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;gBAC5C,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;gBAC1C,QAAQ,EAAE,OAAO,CAAC,QAAQ;aAC3B,CAAC;YAEF,OAAO;gBACL,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;gBAC/D,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;gBAC/D,MAAM;gBACN,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,cAAc,EAAE;oBACd,SAAS,EAAE,MAAM,CAAC,eAAe;oBACjC,eAAe,EAAE,QAAQ,CAAC,KAAK;oBAC/B,UAAU,EAAE,OAAO,CAAC,mBAAmB,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;iBAC/D;aACF,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC;AA7CD,kCA6CC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* window/strategy — PUBLIC. How a window strategy is shaped.
|
|
4
|
+
*
|
|
5
|
+
* Pattern: Strategy (GoF), with the dangerous half of the decision handed in
|
|
6
|
+
* pre-bound rather than left to the implementer to re-derive.
|
|
7
|
+
* Role: core/ layer. The window stage does the wiring — read the meter,
|
|
8
|
+
* write the window, emit, record, cost — and delegates the one
|
|
9
|
+
* interesting question to a strategy:
|
|
10
|
+
*
|
|
11
|
+
* given the segmented turns and what the provider actually
|
|
12
|
+
* counted → what should the window become, and what does the
|
|
13
|
+
* ledger need to be told about it?
|
|
14
|
+
*
|
|
15
|
+
* Emits: N/A. A strategy is pure decision + (optionally) its own LLM call;
|
|
16
|
+
* it never touches scope, never emits, and never writes. That is
|
|
17
|
+
* what makes it testable without a chart, and what keeps the
|
|
18
|
+
* "record everything you did" duty in ONE place (the stage) rather
|
|
19
|
+
* than duplicated per strategy.
|
|
20
|
+
*
|
|
21
|
+
* Three strategies ship — `summarizeOldest` (what `.compaction()`
|
|
22
|
+
* configures), `slidingWindow`, `tokenBudget` — and `.window(...)` takes any
|
|
23
|
+
* object that satisfies `WindowStrategy`.
|
|
24
|
+
*
|
|
25
|
+
* Two things are deliberately NOT left to the implementer:
|
|
26
|
+
*
|
|
27
|
+
* 1. **The refusal rules.** `planRemoval` arrives already bound to this
|
|
28
|
+
* iteration's turns and guards. A strategy cannot forget that an
|
|
29
|
+
* unanswered tool call must not leave the window, because it never gets
|
|
30
|
+
* the chance to decide that for itself — it asks, and it is told, with
|
|
31
|
+
* every refusal named. That is safety by construction, not by docs.
|
|
32
|
+
* 2. **Provenance.** `removalFacts` turns "these indices left" into the
|
|
33
|
+
* stage ids that wrote them and how long each lived. A strategy cannot
|
|
34
|
+
* file a removal it cannot name.
|
|
35
|
+
*
|
|
36
|
+
* The TRIGGER, by contrast, is entirely the strategy's own: `plan` is called
|
|
37
|
+
* at every ReAct iteration boundary and answers `undefined` when it did not
|
|
38
|
+
* engage. That is why `slidingWindow` can run on a provider that reports no
|
|
39
|
+
* usage at all while `summarizeOldest` and `tokenBudget` refuse by name.
|
|
40
|
+
*/
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
//# sourceMappingURL=strategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strategy.js","sourceRoot":"","sources":["../../../../src/core/agent/window/strategy.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summarize.js","sourceRoot":"","sources":["../../../../src/core/agent/window/summarize.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,19 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* window/turns — where a turn boundary is, and which turns may leave.
|
|
4
4
|
*
|
|
5
5
|
* Pattern: Pure functions over the window (no scope, no I/O, no clock).
|
|
6
|
-
* Role: core/ layer.
|
|
7
|
-
* a
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
6
|
+
* Role: core/ layer. THE refusal engine. Every window strategy — the three
|
|
7
|
+
* that ship, and any a consumer writes — decides what leaves the
|
|
8
|
+
* window by calling these functions and nothing else, because the
|
|
9
|
+
* whole safety argument of the family lives here:
|
|
10
|
+
*
|
|
11
|
+
* a removal that splits an assistant's `tool_use` from its
|
|
12
|
+
* `tool_result` produces a request the vendor rejects, and a
|
|
13
|
+
* removal that swallows an unanswered question destroys the
|
|
14
|
+
* referent of the answer that has not arrived yet.
|
|
15
|
+
*
|
|
16
|
+
* Strategies never import this module. `WindowStrategyInput` hands
|
|
17
|
+
* them `planRemoval` already bound to this iteration's turns and
|
|
18
|
+
* guards, so a strategy CANNOT skip the refusal rules — that is a
|
|
19
|
+
* property of the seam, not of the documentation.
|
|
11
20
|
* Emits: N/A.
|
|
12
21
|
*
|
|
13
|
-
* Testable on its own — see `test/core/
|
|
22
|
+
* Testable on its own — see `test/core/window-turns.test.ts`.
|
|
14
23
|
*/
|
|
15
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
-
exports.windowChars = exports.
|
|
25
|
+
exports.windowChars = exports.planRemoval = exports.refusalFor = exports.answeredCallIds = exports.segmentTurns = void 0;
|
|
17
26
|
/**
|
|
18
27
|
* Segment a window into turns.
|
|
19
28
|
*
|
|
@@ -54,7 +63,7 @@ function answeredCallIds(history) {
|
|
|
54
63
|
}
|
|
55
64
|
exports.answeredCallIds = answeredCallIds;
|
|
56
65
|
/**
|
|
57
|
-
* Why this turn may NOT
|
|
66
|
+
* Why this turn may NOT leave the window, or `undefined` when it may.
|
|
58
67
|
*
|
|
59
68
|
* Order matters only for which reason gets reported first; every check is
|
|
60
69
|
* independent. `paused-tool` / `pending-check-in` are separated from
|
|
@@ -62,22 +71,22 @@ exports.answeredCallIds = answeredCallIds;
|
|
|
62
71
|
* fact about the world, and "we are waiting on a human" is what the person
|
|
63
72
|
* reading the trace needs to see.
|
|
64
73
|
*/
|
|
65
|
-
function refusalFor(turn,
|
|
74
|
+
function refusalFor(turn, guards) {
|
|
66
75
|
for (const msg of turn.messages) {
|
|
67
76
|
if (msg.role === 'system')
|
|
68
77
|
return 'system-envelope';
|
|
69
78
|
}
|
|
70
|
-
const paused =
|
|
79
|
+
const paused = guards.pausedToolCallId;
|
|
71
80
|
if (paused !== undefined && paused.length > 0) {
|
|
72
81
|
for (const msg of turn.messages) {
|
|
73
82
|
const holdsPaused = msg.toolCallId === paused || (msg.toolCalls ?? []).some((tc) => tc.id === paused);
|
|
74
83
|
if (holdsPaused)
|
|
75
|
-
return
|
|
84
|
+
return guards.pausedCheckIn === true ? 'pending-check-in' : 'paused-tool';
|
|
76
85
|
}
|
|
77
86
|
}
|
|
78
87
|
for (const msg of turn.messages) {
|
|
79
88
|
for (const call of msg.toolCalls ?? []) {
|
|
80
|
-
if (!
|
|
89
|
+
if (!guards.answeredCallIds.has(call.id))
|
|
81
90
|
return 'unresolved-tool-call';
|
|
82
91
|
}
|
|
83
92
|
}
|
|
@@ -85,22 +94,31 @@ function refusalFor(turn, ctx) {
|
|
|
85
94
|
}
|
|
86
95
|
exports.refusalFor = refusalFor;
|
|
87
96
|
/**
|
|
88
|
-
* Choose the
|
|
89
|
-
* turns, starting at the oldest
|
|
97
|
+
* Choose the removal span: the LONGEST CONTIGUOUS run of removable candidate
|
|
98
|
+
* turns, starting at the oldest removable one.
|
|
90
99
|
*
|
|
91
100
|
* Contiguity is not fussiness — it is what keeps the conversation in order.
|
|
92
101
|
* A fold replaces its span with ONE summary message; if the span skipped over
|
|
93
|
-
* an
|
|
94
|
-
* happened before it. So an
|
|
95
|
-
*
|
|
96
|
-
* ends the span. Everything not
|
|
102
|
+
* an unremovable turn, that turn would end up after a summary of things that
|
|
103
|
+
* happened before it. So an unremovable turn at the front is stepped over (the
|
|
104
|
+
* span "takes the next oldest instead") and an unremovable turn in the middle
|
|
105
|
+
* ends the span. Everything not removed keeps its position.
|
|
106
|
+
*
|
|
107
|
+
* The drop strategies take the same span for a second reason: it is what makes
|
|
108
|
+
* a refusal reason mean the same thing under every strategy. A turn that ends
|
|
109
|
+
* the span this iteration is retried the next one — by which time the tool
|
|
110
|
+
* result it was waiting on has usually arrived.
|
|
97
111
|
*
|
|
98
|
-
* @param turns
|
|
99
|
-
* @param keepRecent
|
|
100
|
-
* @param
|
|
101
|
-
* @param
|
|
112
|
+
* @param turns the window's turn segmentation
|
|
113
|
+
* @param keepRecent how many trailing turns are off-limits
|
|
114
|
+
* @param guards what must not leave (unanswered calls, the pause)
|
|
115
|
+
* @param isExistingSummary optional: true for a turn that is a summary a prior
|
|
116
|
+
* fold wrote. When the whole span is one such turn, the plan refuses with
|
|
117
|
+
* `only-existing-summary` — re-summarizing a summary spends an LLM call to
|
|
118
|
+
* lose detail. The drop strategies omit it: a drop spends nothing, so there
|
|
119
|
+
* is nothing to protect against.
|
|
102
120
|
*/
|
|
103
|
-
function
|
|
121
|
+
function planRemoval(turns, keepRecent, guards, isExistingSummary) {
|
|
104
122
|
const refusals = [];
|
|
105
123
|
const candidateCount = Math.max(0, turns.length - keepRecent);
|
|
106
124
|
for (let i = candidateCount; i < turns.length; i++) {
|
|
@@ -114,7 +132,7 @@ function planFold(turns, keepRecent, ctx, isSummaryTurn) {
|
|
|
114
132
|
let to = -1;
|
|
115
133
|
for (let i = 0; i < candidateCount; i++) {
|
|
116
134
|
const turn = turns[i];
|
|
117
|
-
const reason = refusalFor(turn,
|
|
135
|
+
const reason = refusalFor(turn, guards);
|
|
118
136
|
if (reason === undefined) {
|
|
119
137
|
if (from === -1)
|
|
120
138
|
from = i;
|
|
@@ -123,12 +141,16 @@ function planFold(turns, keepRecent, ctx, isSummaryTurn) {
|
|
|
123
141
|
}
|
|
124
142
|
before.push({ reason, turnIndex: i, messageIndex: turn.start });
|
|
125
143
|
if (from !== -1)
|
|
126
|
-
break; // an
|
|
144
|
+
break; // an unremovable turn ENDS the span
|
|
127
145
|
}
|
|
128
146
|
// A span that is nothing but one existing summary is not worth a call:
|
|
129
147
|
// re-summarizing a summary spends tokens to lose detail and names nothing
|
|
130
148
|
// new. It becomes foldable again as soon as a real turn joins it.
|
|
131
|
-
|
|
149
|
+
const summaryOnly = isExistingSummary !== undefined &&
|
|
150
|
+
from !== -1 &&
|
|
151
|
+
from === to &&
|
|
152
|
+
isExistingSummary(turns[from]);
|
|
153
|
+
if (summaryOnly) {
|
|
132
154
|
return {
|
|
133
155
|
from: -1,
|
|
134
156
|
to: -1,
|
|
@@ -141,7 +163,7 @@ function planFold(turns, keepRecent, ctx, isSummaryTurn) {
|
|
|
141
163
|
}
|
|
142
164
|
return { from, to, refusals: [...before, ...refusals] };
|
|
143
165
|
}
|
|
144
|
-
exports.
|
|
166
|
+
exports.planRemoval = planRemoval;
|
|
145
167
|
/** Total characters of message content in a window. Exact; not tokens. */
|
|
146
168
|
function windowChars(history) {
|
|
147
169
|
let total = 0;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turns.js","sourceRoot":"","sources":["../../../../src/core/agent/window/turns.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* window/types — what each window strategy accepts, and what it writes into
|
|
4
|
+
* the ledger.
|
|
5
|
+
*
|
|
6
|
+
* Pattern: Value objects (no behavior) + resolved-config types.
|
|
7
|
+
* Role: core/ layer. The law this whole folder exists to keep is stated
|
|
8
|
+
* once, here, because every other file implements a piece of it:
|
|
9
|
+
* **a window strategy edits the WINDOW, never the LEDGER.**
|
|
10
|
+
* Emits: N/A (types only).
|
|
11
|
+
*
|
|
12
|
+
* The window is `scope.history` — the array `call-llm` hands the provider.
|
|
13
|
+
* The ledger is footprintjs's commit log, which is append-only: the turns a
|
|
14
|
+
* strategy removes from the window were committed by `seed#0` /
|
|
15
|
+
* `tool-calls#N` BEFORE the removal and stay in those bundles byte-identical
|
|
16
|
+
* forever. A strategy therefore cannot destroy history even in principle; it
|
|
17
|
+
* can only stop re-sending it. A summary is a CLAIM about the past, so it is
|
|
18
|
+
* filed as a claim — its own recorded step, naming every `runtimeStageId` it
|
|
19
|
+
* folded. A drop is an ABSENCE, and it is filed the same way: the record and
|
|
20
|
+
* the eviction events name what left, by id.
|
|
21
|
+
*/
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/core/agent/window/types.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG"}
|