agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
45 lines • 2.43 kB
JavaScript
;
/**
* window/strategy — PUBLIC. How a window strategy is shaped.
*
* Pattern: Strategy (GoF), with the dangerous half of the decision handed in
* pre-bound rather than left to the implementer to re-derive.
* Role: core/ layer. The window stage does the wiring — read the meter,
* write the window, emit, record, cost — and delegates the one
* interesting question to a strategy:
*
* given the segmented turns and what the provider actually
* counted → what should the window become, and what does the
* ledger need to be told about it?
*
* Emits: N/A. A strategy is pure decision + (optionally) its own LLM call;
* it never touches scope, never emits, and never writes. That is
* what makes it testable without a chart, and what keeps the
* "record everything you did" duty in ONE place (the stage) rather
* than duplicated per strategy.
*
* Three strategies ship — `summarizeOldest` (what `.compaction()`
* configures), `slidingWindow`, `tokenBudget` — and `.window(...)` takes any
* object that satisfies `WindowStrategy`.
*
* Two things are deliberately NOT left to the implementer:
*
* 1. **The refusal rules.** `planRemoval` arrives already bound to this
* iteration's turns and guards. A strategy cannot forget that an
* unanswered tool call must not leave the window — or that the CURRENT
* REQUEST never does (9.55.0) — because it never gets the chance to
* decide that for itself: it asks, and it is told, with every refusal
* named. That is safety by construction, not by docs. It is also why a
* rule added there arrives in every strategy at once, including the ones
* consumers wrote before the rule existed.
* 2. **Provenance.** `removalFacts` turns "these indices left" into the
* stage ids that wrote them and how long each lived. A strategy cannot
* file a removal it cannot name.
*
* The TRIGGER, by contrast, is entirely the strategy's own: `plan` is called
* at every ReAct iteration boundary and answers `undefined` when it did not
* engage. That is why `slidingWindow` can run on a provider that reports no
* usage at all while `summarizeOldest` and `tokenBudget` refuse by name.
*/
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=strategy.js.map