agentfootprint 9.92.1 → 9.94.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/CHANGELOG.md +198 -0
- package/README.md +2 -1
- package/dist/core/Agent.js +15 -0
- package/dist/core/Agent.js.map +1 -1
- package/dist/core/LLMCall.js +6 -4
- package/dist/core/LLMCall.js.map +1 -1
- package/dist/core/agent/AgentBuilder.js +2 -2
- package/dist/core/agent/AgentBuilder.js.map +1 -1
- package/dist/core/agent/messageApiReceipt.js +1 -0
- package/dist/core/agent/messageApiReceipt.js.map +1 -1
- package/dist/core/agent/stages/callLLM.js +18 -7
- package/dist/core/agent/stages/callLLM.js.map +1 -1
- package/dist/core/agent/stages/window.js +12 -2
- package/dist/core/agent/stages/window.js.map +1 -1
- package/dist/core/agent/window/evictedTurns.js +60 -0
- package/dist/core/agent/window/evictedTurns.js.map +1 -0
- package/dist/esm/core/Agent.d.ts +4 -0
- package/dist/esm/core/Agent.js +15 -0
- package/dist/esm/core/Agent.js.map +1 -1
- package/dist/esm/core/LLMCall.js +6 -4
- package/dist/esm/core/LLMCall.js.map +1 -1
- package/dist/esm/core/agent/AgentBuilder.js +1 -1
- package/dist/esm/core/agent/AgentBuilder.js.map +1 -1
- package/dist/esm/core/agent/messageApiReceipt.d.ts +3 -1
- package/dist/esm/core/agent/messageApiReceipt.js +1 -0
- package/dist/esm/core/agent/messageApiReceipt.js.map +1 -1
- package/dist/esm/core/agent/stages/callLLM.d.ts +9 -0
- package/dist/esm/core/agent/stages/callLLM.js +18 -7
- package/dist/esm/core/agent/stages/callLLM.js.map +1 -1
- package/dist/esm/core/agent/stages/window.d.ts +8 -0
- package/dist/esm/core/agent/stages/window.js +12 -2
- package/dist/esm/core/agent/stages/window.js.map +1 -1
- package/dist/esm/core/agent/window/evictedTurns.d.ts +52 -0
- package/dist/esm/core/agent/window/evictedTurns.js +56 -0
- package/dist/esm/core/agent/window/evictedTurns.js.map +1 -0
- package/dist/esm/lib/time-travel/receipt.d.ts +71 -28
- package/dist/esm/lib/time-travel/receipt.js +33 -17
- package/dist/esm/lib/time-travel/receipt.js.map +1 -1
- package/dist/esm/lib/time-travel/servedView.d.ts +31 -22
- package/dist/esm/lib/time-travel/servedView.js +78 -43
- package/dist/esm/lib/time-travel/servedView.js.map +1 -1
- package/dist/esm/lib/trace-toolpack/lazyToolpack.d.ts +2 -2
- package/dist/esm/lib/trace-toolpack/lazyToolpack.js +5 -3
- package/dist/esm/lib/trace-toolpack/lazyToolpack.js.map +1 -1
- package/dist/esm/lib/trace-toolpack/selfExplain.d.ts +17 -0
- package/dist/esm/lib/trace-toolpack/selfExplain.js +53 -5
- package/dist/esm/lib/trace-toolpack/selfExplain.js.map +1 -1
- package/dist/esm/lib/trace-toolpack/traceToolNames.d.ts +37 -0
- package/dist/esm/lib/trace-toolpack/traceToolNames.js +51 -0
- package/dist/esm/lib/trace-toolpack/traceToolNames.js.map +1 -0
- package/dist/esm/lib/trace-toolpack/traceToolpack.d.ts +5 -7
- package/dist/esm/lib/trace-toolpack/traceToolpack.js +5 -19
- package/dist/esm/lib/trace-toolpack/traceToolpack.js.map +1 -1
- package/dist/esm/package.json +1 -1
- package/dist/lib/time-travel/receipt.js +33 -17
- package/dist/lib/time-travel/receipt.js.map +1 -1
- package/dist/lib/time-travel/servedView.js +78 -43
- package/dist/lib/time-travel/servedView.js.map +1 -1
- package/dist/lib/trace-toolpack/lazyToolpack.js +3 -4
- package/dist/lib/trace-toolpack/lazyToolpack.js.map +1 -1
- package/dist/lib/trace-toolpack/selfExplain.js +54 -6
- package/dist/lib/trace-toolpack/selfExplain.js.map +1 -1
- package/dist/lib/trace-toolpack/traceToolNames.js +54 -0
- package/dist/lib/trace-toolpack/traceToolNames.js.map +1 -0
- package/dist/lib/trace-toolpack/traceToolpack.js +6 -19
- package/dist/lib/trace-toolpack/traceToolpack.js.map +1 -1
- package/dist/types/core/Agent.d.ts +4 -0
- package/dist/types/core/Agent.d.ts.map +1 -1
- package/dist/types/core/LLMCall.d.ts.map +1 -1
- package/dist/types/core/agent/messageApiReceipt.d.ts +3 -1
- package/dist/types/core/agent/messageApiReceipt.d.ts.map +1 -1
- package/dist/types/core/agent/stages/callLLM.d.ts +9 -0
- package/dist/types/core/agent/stages/callLLM.d.ts.map +1 -1
- package/dist/types/core/agent/stages/window.d.ts +8 -0
- package/dist/types/core/agent/stages/window.d.ts.map +1 -1
- package/dist/types/core/agent/window/evictedTurns.d.ts +53 -0
- package/dist/types/core/agent/window/evictedTurns.d.ts.map +1 -0
- package/dist/types/lib/time-travel/receipt.d.ts +71 -28
- package/dist/types/lib/time-travel/receipt.d.ts.map +1 -1
- package/dist/types/lib/time-travel/servedView.d.ts +31 -22
- package/dist/types/lib/time-travel/servedView.d.ts.map +1 -1
- package/dist/types/lib/trace-toolpack/lazyToolpack.d.ts +2 -2
- package/dist/types/lib/trace-toolpack/lazyToolpack.d.ts.map +1 -1
- package/dist/types/lib/trace-toolpack/selfExplain.d.ts +17 -0
- package/dist/types/lib/trace-toolpack/selfExplain.d.ts.map +1 -1
- package/dist/types/lib/trace-toolpack/traceToolNames.d.ts +38 -0
- package/dist/types/lib/trace-toolpack/traceToolNames.d.ts.map +1 -0
- package/dist/types/lib/trace-toolpack/traceToolpack.d.ts +5 -7
- package/dist/types/lib/trace-toolpack/traceToolpack.d.ts.map +1 -1
- package/package.json +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,204 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [9.94.0] - 2026-09-11
|
|
11
|
+
|
|
12
|
+
**An optional family is loaded when its option is enabled, never before.** What
|
|
13
|
+
`import { Agent, defineTool } from 'agentfootprint'` costs a browser consumer
|
|
14
|
+
is the library's DEFAULT graph, not its whole surface — and for four releases
|
|
15
|
+
it was not: the docs site's demo chunk grew 394 → 421 KB gzip across 9.61,
|
|
16
|
+
9.78, 9.88 and 9.92 for families the demo never calls, and two publishes
|
|
17
|
+
(9.87.0, 9.92.0) were lost to that ceiling. Measured on this commit, same
|
|
18
|
+
webpack build: the demo chunk 421.3 → 382.4 KB gzip (−38.9 KB, 16 → 15 async
|
|
19
|
+
assets; the library's own chunk 199.6 → 171.4 KB), and a plain esbuild bundle
|
|
20
|
+
of the root import 219.3 → 199.7 KB gzip (−19.6 KB, 717.7 → 658.2 KB minified).
|
|
21
|
+
Two root causes, both in the library, so every consumer gets the same cut. A
|
|
22
|
+
minor rather than a patch because a public provider's `list()` changes shape on
|
|
23
|
+
one iteration (below), and because every bundled consumer's output changes.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- **`.selfExplain()` mounts the trace toolpack lazily.** The toolpack —
|
|
28
|
+
eleven tools over a finished trace, at 47 KB minified the largest single
|
|
29
|
+
module in the package — was on the default graph because `AgentBuilder`
|
|
30
|
+
imported it for `TRACE_TOOL_NAMES`, the list of names it reserves at
|
|
31
|
+
`build()`, and `buildSelfExplainToolProvider` composed the pack eagerly.
|
|
32
|
+
WHY: an agent that never calls `.selfExplain()` was shipping the debugger;
|
|
33
|
+
one that does was shipping it before a single turn had run. Now the names
|
|
34
|
+
live in `lib/trace-toolpack/traceToolNames.ts` (with
|
|
35
|
+
`NO_COMPLETED_RUN_MESSAGE`, the other fact needed before the pack exists —
|
|
36
|
+
both still re-exported from their old modules), and the inline provider
|
|
37
|
+
reaches the pack through `import()` on the first iteration the self-explain
|
|
38
|
+
skill is ACTIVE: not at `build()`, not on a turn where nobody asked why,
|
|
39
|
+
never for an agent without the option. A bundler splits it into its own
|
|
40
|
+
chunk; Node loads it through the same `require`, one microtask later. The
|
|
41
|
+
one visible change: on an active iteration the inline provider's `list(ctx)`
|
|
42
|
+
answers a `Promise<Tool[]>` where it answered an array — the shape
|
|
43
|
+
`ToolProvider.list` has always allowed and the composed provider already
|
|
44
|
+
used; the idle iteration is still a synchronous `[]`, so the tools slot's
|
|
45
|
+
fast path is untouched. Provider id, the reserved-name refusal, delegate
|
|
46
|
+
mode and every trace tool are unchanged.
|
|
47
|
+
`test/lib/trace-toolpack/lazyMount.test.ts` pins load-when-active (the
|
|
48
|
+
module is evaluated exactly once, on that iteration), end-to-end answering
|
|
49
|
+
through the lazy path, and cold-mount = warm-mount on the recorded events,
|
|
50
|
+
catalogs and answers.
|
|
51
|
+
```ts
|
|
52
|
+
const agent = Agent.create({ provider, model }).tool(lookup).selfExplain().build();
|
|
53
|
+
await agent.run({ message: 'Refund order A-1001?' }); // pack not loaded
|
|
54
|
+
await agent.run({ message: 'Why did you approve it?' }); // loads on the iteration read_skill opened it
|
|
55
|
+
```
|
|
56
|
+
- **The ESM build now carries `sideEffects`.** A bundler reads that flag from
|
|
57
|
+
the CLOSEST package.json to the module it is deciding about, and
|
|
58
|
+
`dist/esm/package.json` — written at postbuild to mark the build
|
|
59
|
+
`type:module` — was a bare `{"type":"module"}`. WHY: the root's honest
|
|
60
|
+
`sideEffects` list therefore never reached a single ESM module; webpack,
|
|
61
|
+
Vite and esbuild had to presume every file under `dist/esm` might run
|
|
62
|
+
something at load, keep each one a barrel named, and could only strip the
|
|
63
|
+
pure declarations inside — which is also why a dynamic `import()` of a
|
|
64
|
+
module a barrel re-exports (the toolpack, through the `/observe` door the
|
|
65
|
+
lens imports) never split into its own chunk. `scripts/postbuild-esm.mjs`
|
|
66
|
+
now copies the root list across, rebased (`scripts/lib/esmSideEffects.mjs`;
|
|
67
|
+
`test/esm-packaging.test.ts` pins the shipped file against the same rule).
|
|
68
|
+
The list was widened only where it is TRUE: `./dist/index.js` /
|
|
69
|
+
`./dist/esm/index.js` (the root entry imports the three cache strategies for
|
|
70
|
+
their `registerCacheStrategy` calls) and `**/lib/injection-engine/index.js`
|
|
71
|
+
(the barrel imports `devWarnHost` to bind footprintjs's dev flag) — a barrel
|
|
72
|
+
marked side-effect-free is a barrel a bundler may skip, imports and all.
|
|
73
|
+
`test/lib/trace-toolpack/browserGraph.test.ts` proves at the code-split
|
|
74
|
+
graph that the toolpack is off the root entry's sync closure, still
|
|
75
|
+
reachable behind a `dynamic-import` edge, statically present on `/observe`
|
|
76
|
+
by design, and that every registration survives (the three strategies on
|
|
77
|
+
the root entry, the dev-warn host on `/context`). footprintjs's own
|
|
78
|
+
`dist/esm/package.json` has carried its flag all along; this follows it.
|
|
79
|
+
|
|
80
|
+
### Docs
|
|
81
|
+
|
|
82
|
+
- `docs-next/scripts/check-site-budget.mjs`: the LAW above the demo ceiling
|
|
83
|
+
(an optional family loads when its option is enabled; the demo bundle
|
|
84
|
+
measures the default graph), the two families this release could not move
|
|
85
|
+
and why — the integrity checks run inside synchronous stage helpers and one
|
|
86
|
+
(`wireViolationsOf`) is unconditional; the observability recorders sit
|
|
87
|
+
behind `enable.flowchart()` / `enable.localObservability()`, which return
|
|
88
|
+
synchronously — and the ceiling LOWERED 429.4 → 390.0 KB (~2% over 382.4).
|
|
89
|
+
`DOCS_WEBPACK_STATS=1` on the docs build writes per-module webpack stats and
|
|
90
|
+
`docs-next/scripts/demo-chunk-modules.mjs` names what the demo chunk
|
|
91
|
+
carries, so the next raise is argued per module, not per ceiling.
|
|
92
|
+
- README "Tree-shakeable & ESM-first" and docs/debug/self-explain: the rule,
|
|
93
|
+
the example, the fences.
|
|
94
|
+
|
|
95
|
+
## [9.93.0] - 2026-09-11
|
|
96
|
+
|
|
97
|
+
**The receipt says which strategy, and what the window dropped.** Four of the
|
|
98
|
+
seven standing recorded-not-built entries close, one is verified rather than
|
|
99
|
+
rebuilt, and one is assessed and half-built. Every item below is a behaviour
|
|
100
|
+
change to a shipped record — a new receipt key on every minting chart, a gap
|
|
101
|
+
that stops firing on three of them, a field that starts being written — which
|
|
102
|
+
is why this is a minor and not a patch. Nothing that had no name collision, no
|
|
103
|
+
window and no cache strategy records a different byte except the one new key.
|
|
104
|
+
|
|
105
|
+
### Added
|
|
106
|
+
|
|
107
|
+
- **`Receipt.cache.strategy: string | null`** — WHICH cache strategy the
|
|
108
|
+
request went through (its registry `providerName`; `'*'` is the built-in
|
|
109
|
+
pass-through every agent runs), or `null` where none stood between assembly
|
|
110
|
+
and the port. WHY: `cache.transform: 'unchanged'` is the honest verdict both
|
|
111
|
+
when a strategy returned what it was given and when there was no strategy at
|
|
112
|
+
all, so the served view had no way to know a rewrite was impossible and
|
|
113
|
+
raised `cache-transform` on every view — including `LLMCall` and the two
|
|
114
|
+
message-API charts, where a reader was told what a cache strategy may have
|
|
115
|
+
done beside a call none could touch (entry 8). No fourth `transform` value
|
|
116
|
+
was added; the fact is its own field, minted by the one owner
|
|
117
|
+
(`buildReceipt` refuses to mint without it). A receipt from before this
|
|
118
|
+
release has no key, and a reader treats that as "cannot say", never as
|
|
119
|
+
`null`.
|
|
120
|
+
```ts
|
|
121
|
+
receiptAt(agent.getSnapshot()!, 1)!.cache.strategy; // '*' — an agent on the mock provider
|
|
122
|
+
receiptAt(llmCall.getSnapshot()!, 1)!.cache.strategy; // null — nothing between assembly and the port
|
|
123
|
+
```
|
|
124
|
+
- **`Receipt.omittedForAttention` is written** — by the agent chart's window
|
|
125
|
+
stage, for every turn it evicts for budget at an iteration's head. WHY: the
|
|
126
|
+
field was declared in 9.88.0 for "why did the model not know that?" and
|
|
127
|
+
excused as "no chart in this library supplies it" (entry 9) — a measurement
|
|
128
|
+
that had looked at the slots, which drop nothing, and not at the window,
|
|
129
|
+
which does (`context.evicted`, `reason: 'budget'`), and never wrote it. The
|
|
130
|
+
window hands what left to the call-llm mint on an in-memory handle
|
|
131
|
+
(`window/evictedTurns.ts`), the seam the compaction meter already crosses —
|
|
132
|
+
never a scope read, which on every windowless run would be a tracked read of
|
|
133
|
+
an absent key and a phantom context source per loop. Each hash is the
|
|
134
|
+
evicted turn's own `messages.entries[].hash`, so a drop on epoch k's receipt
|
|
135
|
+
pairs with the turn as an earlier receipt served it — the pairing law,
|
|
136
|
+
driven on a real sliding window. Absent now means nothing was dropped before
|
|
137
|
+
that call. The field left `UNGAPPED_FIELDS` and is named by
|
|
138
|
+
`no-receipt-on-chart`, the one gap that can lose it. An agent without a
|
|
139
|
+
window hands both stages the deps they always had.
|
|
140
|
+
```ts
|
|
141
|
+
const agent = Agent.create({ provider, model }).system('bot').tool(lookup)
|
|
142
|
+
.window(slidingWindow({ keepRecentTurns: 1 })).build();
|
|
143
|
+
await agent.run({ message: 'go' });
|
|
144
|
+
receiptAt(agent.getSnapshot()!, 3)!.omittedForAttention; // { count: 2, hashes: [...] } — the pair that left at this head
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Changed
|
|
148
|
+
|
|
149
|
+
- **`cache-transform` is raised only where a rewrite was possible** — where
|
|
150
|
+
the receipt names a strategy, or where no receipt can say (a receipt-less
|
|
151
|
+
view, a pre-9.93.0 receipt, a refused shape). WHY: entry 8 — a sentence
|
|
152
|
+
about what a strategy may have done was printed where none could run. Only a
|
|
153
|
+
receipt that SAYS `null` lifts it; absence still raises, so this is not the
|
|
154
|
+
inference-from-absence the entry refused. Measured: `LLMCall` and both
|
|
155
|
+
message-API charts with a run id now read `['provider-defaults']`; the
|
|
156
|
+
receipt-less message-API view still reads
|
|
157
|
+
`['no-receipt-on-chart', 'cache-transform']`, honestly. The printed sentence
|
|
158
|
+
is unchanged and every clause of it still holds where it prints.
|
|
159
|
+
```ts
|
|
160
|
+
servedAt(llmCall.getSnapshot()!, 1)!.gaps.map((g) => g.gap); // ['provider-defaults'] (was ['cache-transform', 'provider-defaults'])
|
|
161
|
+
```
|
|
162
|
+
- **`cache-transform` names `tools.forced`, `tools.withheld` and
|
|
163
|
+
`cache.strategy`** — fourteen fields, the whole request the strategy holds
|
|
164
|
+
(`params` alone stays off, read past it). WHY: entry 7 — both `tools`
|
|
165
|
+
fields are written from assembly's own decision and never from
|
|
166
|
+
`preparedRequest`, so a strategy that drops the forced answer tool from
|
|
167
|
+
`request.tools` leaves a receipt whose `tools.forced` names a tool the port
|
|
168
|
+
never carried, and the gap did not warn. Driven: an unforcing strategy on a
|
|
169
|
+
`'tool-forced'` agent — wire has no tool and no forcing, receipt says
|
|
170
|
+
`tools.forced: 'respond_with_schema'` and `params.toolChoice` absent, the
|
|
171
|
+
gap names the half that describes the decision. Reading them off the
|
|
172
|
+
prepared request instead was NOT done: that would describe a different fact
|
|
173
|
+
under the same name.
|
|
174
|
+
- **The receipt-conformance law checks the cache verdict outright where no
|
|
175
|
+
strategy ran** — `transform: 'unchanged'`, `transformHash: null`,
|
|
176
|
+
`markersApplied: []`, and no `cache-transform` excuse; where one ran, the gap
|
|
177
|
+
must excuse the unrebuildable fields as before.
|
|
178
|
+
- **Byte-identity references regenerated** (`test/core/tools/reference/`),
|
|
179
|
+
with the whole delta against the 9.92.1 set on record in the test's header:
|
|
180
|
+
the new `cache.strategy` key on every minting fixture, the gap's longer
|
|
181
|
+
field list on every agent view, and the gap leaving the three no-strategy
|
|
182
|
+
views. No message, tool or other key moved on any fixture.
|
|
183
|
+
|
|
184
|
+
### Verified
|
|
185
|
+
|
|
186
|
+
- **Recorded-not-built entries 4 and 5 hold under the 9.92.0 law** and are
|
|
187
|
+
marked built (verified 2026-09-11 against the 9.92.1 `dist`, before any edit
|
|
188
|
+
of this release). `.selfExplain()`'s `run_overview` against an always-visible
|
|
189
|
+
skill, a never-activated scoped skill and a stepped skill: dispatch follows
|
|
190
|
+
the offer on every epoch (the never-activated skill no longer answers the
|
|
191
|
+
framework's own contract — the framework does), `tools.shadowed` names the
|
|
192
|
+
wire's party and never `provider(skill-scoped:self-explain)`, and the losing
|
|
193
|
+
claim is named by `tools.claim_swallowed` on every epoch it lost. The
|
|
194
|
+
reservation this entry names is deliberately untouched; the measured output
|
|
195
|
+
is pasted on the entries and pinned as `offer-and-answer.test.ts` §7.
|
|
196
|
+
|
|
197
|
+
### Assessed
|
|
198
|
+
|
|
199
|
+
- **Entry 10 ("an assertion can be weaker than its clause") is split, and the
|
|
200
|
+
mechanical half is built.** Every clause in `gap-sentences.test.ts` declares
|
|
201
|
+
the fields it is about; a seam hands its assertion a view or receipt with
|
|
202
|
+
one declared field altered, then removed; a contract requires the assertion
|
|
203
|
+
to fail under at least one. The first run found one insensitivity and it is
|
|
204
|
+
fixed. What remains is the quantifier half — a clause about "every field" or
|
|
205
|
+
"both chart shapes" asserted on fewer runs — which needs per-clause hand
|
|
206
|
+
work and is named on the entry rather than faked by a mechanism.
|
|
207
|
+
|
|
10
208
|
## [9.92.1] - 2026-09-11
|
|
11
209
|
|
|
12
210
|
### Fixed
|
package/README.md
CHANGED
|
@@ -975,8 +975,9 @@ Import one thing, ship one thing. agentfootprint is built so your bundle grows o
|
|
|
975
975
|
- **Per-file modules + honest `sideEffects`.** The dist is emitted file-by-file (never pre-bundled), so bundlers drop every export you don't touch. A small `import { defineTool }` doesn't pull in the Agent runtime, injection engine, memory stores, or LLM providers.
|
|
976
976
|
- **Ten doors, named for what you're doing.** `agentfootprint` · `/providers` (plug in a backend) · `/memory` (state that outlives a turn) · `/observe` (everything that watches) · `/context` (how context gets assembled) · `/resilience` (when the call fails) · `/security` (who may do what) · `/hosting` (behind a wire) · `/events` (the typed wire vocabulary) · `/cache` (prompt caching). 8.0.0 consolidated 26 internals-named subpaths into these; every old path still resolves for all of 8.x.
|
|
977
977
|
- **Lazy peer-deps.** Heavyweight integrations load their SDK **only when you instantiate them** — importing agentfootprint never bundles `@anthropic-ai/sdk`, `ioredis`, the AWS SDKs, or the MCP SDK unless you actually use that adapter.
|
|
978
|
+
- **Optional families load when their option is enabled, never before.** What `import { Agent, defineTool }` costs is the library's *default graph*, not its whole surface. `.selfExplain()`'s trace toolpack — eleven tools over a finished trace, the largest single module in the package — is reached through a dynamic `import()` on the first iteration the self-explain skill is active; an agent that never enables it never ships it, and a bundler splits it into its own chunk. (A door that exists to hand you the debugger, `/observe`, carries it eagerly on purpose.)
|
|
978
979
|
|
|
979
|
-
**Proven, not promised.** A CI smoke test bundles a minimal `import { defineTool }` and asserts the Agent runtime, injection engine, memory stores, and providers are pruned; a second test loads the main barrel and every subpath as true ESM and verifies the lazy-adapter loader works under ESM (`createRequire`, not a bare `require`). See [`test/esm-packaging.test.ts`](test/esm-packaging.test.ts).
|
|
980
|
+
**Proven, not promised.** A CI smoke test bundles a minimal `import { defineTool }` and asserts the Agent runtime, injection engine, memory stores, and providers are pruned; a second test loads the main barrel and every subpath as true ESM and verifies the lazy-adapter loader works under ESM (`createRequire`, not a bare `require`). See [`test/esm-packaging.test.ts`](test/esm-packaging.test.ts). A third walks the code-split graph of the root entry and fails if the trace toolpack ever returns to its sync closure — [`test/lib/trace-toolpack/browserGraph.test.ts`](test/lib/trace-toolpack/browserGraph.test.ts); the docs site's own demo chunk is ratcheted against the same default graph in [`docs-next/scripts/check-site-budget.mjs`](docs-next/scripts/check-site-budget.mjs).
|
|
980
981
|
|
|
981
982
|
---
|
|
982
983
|
|
package/dist/core/Agent.js
CHANGED
|
@@ -50,6 +50,7 @@ const ReliabilityRecorder_js_1 = require("../recorders/core/ReliabilityRecorder.
|
|
|
50
50
|
const ResilienceRecorder_js_1 = require("../recorders/core/ResilienceRecorder.js");
|
|
51
51
|
const CheckInRecorder_js_1 = require("../recorders/core/CheckInRecorder.js");
|
|
52
52
|
const CompactionMeter_js_1 = require("../recorders/core/CompactionMeter.js");
|
|
53
|
+
const evictedTurns_js_1 = require("./agent/window/evictedTurns.js");
|
|
53
54
|
const durabilityBarrier_js_1 = require("./durabilityBarrier.js");
|
|
54
55
|
const toolSessions_js_1 = require("./toolSessions.js");
|
|
55
56
|
const eventMeta_js_1 = require("../bridge/eventMeta.js");
|
|
@@ -264,6 +265,10 @@ class Agent extends RunnerBase_js_1.RunnerBase {
|
|
|
264
265
|
/** The instrument the window stage reads mid-run (adapter-reported usage +
|
|
265
266
|
* per-message provenance). Only ever created alongside a strategy. */
|
|
266
267
|
compactionMeterHandle;
|
|
268
|
+
/** The window stage's seam to the receipt (9.93.0): what left the window at
|
|
269
|
+
* this iteration's head, read by the call-llm mint in the same iteration.
|
|
270
|
+
* Only ever created alongside a strategy, like the meter. */
|
|
271
|
+
evictedTurnsHandle;
|
|
267
272
|
/** Snapshot read-tracking policy (#18/#14) — forwarded to the internal
|
|
268
273
|
* executor. Agent default is `'summary'` (cheap markers), NOT
|
|
269
274
|
* footprintjs's `'full'`. See AgentOptions.readTracking. */
|
|
@@ -612,6 +617,7 @@ class Agent extends RunnerBase_js_1.RunnerBase {
|
|
|
612
617
|
if (windowStrategy !== undefined) {
|
|
613
618
|
this.windowStrategy = windowStrategy;
|
|
614
619
|
this.compactionMeterHandle = (0, CompactionMeter_js_1.compactionMeter)();
|
|
620
|
+
this.evictedTurnsHandle = (0, evictedTurns_js_1.createEvictedTurnsHandle)();
|
|
615
621
|
}
|
|
616
622
|
// The two governance chains. Empty arrays (not undefined) so every read
|
|
617
623
|
// site is a plain `.length > 0` test rather than an optional dance.
|
|
@@ -2221,6 +2227,9 @@ class Agent extends RunnerBase_js_1.RunnerBase {
|
|
|
2221
2227
|
// `conversationId` is deliberately not carried: it is a thread, not a
|
|
2222
2228
|
// person, and `sessionId` beside it is the fact the transport delivered.
|
|
2223
2229
|
const actor = runOptions?.identity ?? this.lastRunIdentity;
|
|
2230
|
+
// A fresh run starts with no evictions filed — the previous run's last
|
|
2231
|
+
// visit must not be read as this run's (`window/evictedTurns.ts`).
|
|
2232
|
+
this.evictedTurnsHandle?.clear();
|
|
2224
2233
|
this.currentRunContext = {
|
|
2225
2234
|
runStartMs: Date.now(),
|
|
2226
2235
|
runId: (0, RunnerBase_js_1.makeRunId)(),
|
|
@@ -3253,6 +3262,9 @@ class Agent extends RunnerBase_js_1.RunnerBase {
|
|
|
3253
3262
|
// …and its off switch. Value-conditional, so an agent on the default
|
|
3254
3263
|
// hands `callLLM` exactly the dep bag it always did.
|
|
3255
3264
|
...(this.recordReceiptValue === false && { recordReceipt: false }),
|
|
3265
|
+
// …and the window's evictions for `omittedForAttention` (9.93.0) — only
|
|
3266
|
+
// an agent with a window strategy has any, and only it hands the seam.
|
|
3267
|
+
...(this.evictedTurnsHandle !== undefined && { evictedTurns: this.evictedTurnsHandle }),
|
|
3256
3268
|
provider,
|
|
3257
3269
|
model,
|
|
3258
3270
|
...(temperature !== undefined && { temperature }),
|
|
@@ -3327,6 +3339,9 @@ class Agent extends RunnerBase_js_1.RunnerBase {
|
|
|
3327
3339
|
run: (0, window_js_1.buildWindowStage)({
|
|
3328
3340
|
strategy: this.windowStrategy,
|
|
3329
3341
|
meter: this.compactionMeterHandle,
|
|
3342
|
+
...(this.evictedTurnsHandle !== undefined && {
|
|
3343
|
+
evictedTurns: this.evictedTurnsHandle,
|
|
3344
|
+
}),
|
|
3330
3345
|
agentModel: model,
|
|
3331
3346
|
providerName: provider.name,
|
|
3332
3347
|
getRunId: () => this.currentRunContext?.runId,
|