agentfootprint 9.90.0 → 9.92.1
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/CHANGELOG.md +213 -0
- package/CLAUDE.md +1 -1
- package/ai-instructions/claude-code/SKILL.md +1 -1
- package/dist/core/Agent.js +23 -7
- package/dist/core/Agent.js.map +1 -1
- package/dist/core/LLMCall.js +62 -7
- package/dist/core/LLMCall.js.map +1 -1
- package/dist/core/agent/buildAgentMessageApiChart.js +36 -3
- package/dist/core/agent/buildAgentMessageApiChart.js.map +1 -1
- package/dist/core/agent/buildMessageApiChart.js +26 -3
- package/dist/core/agent/buildMessageApiChart.js.map +1 -1
- package/dist/core/agent/buildToolRegistry.js +90 -33
- package/dist/core/agent/buildToolRegistry.js.map +1 -1
- package/dist/core/agent/messageApiReceipt.js +77 -0
- package/dist/core/agent/messageApiReceipt.js.map +1 -0
- package/dist/core/agent/stages/callLLM.js +1 -5
- package/dist/core/agent/stages/callLLM.js.map +1 -1
- package/dist/core/agent/stages/toolCalls.js +176 -28
- package/dist/core/agent/stages/toolCalls.js.map +1 -1
- package/dist/core/slots/buildToolsSlot.js +209 -62
- package/dist/core/slots/buildToolsSlot.js.map +1 -1
- package/dist/esm/core/Agent.js +24 -8
- package/dist/esm/core/Agent.js.map +1 -1
- package/dist/esm/core/LLMCall.d.ts +18 -0
- package/dist/esm/core/LLMCall.js +63 -8
- package/dist/esm/core/LLMCall.js.map +1 -1
- package/dist/esm/core/agent/buildAgentMessageApiChart.d.ts +22 -0
- package/dist/esm/core/agent/buildAgentMessageApiChart.js +37 -4
- package/dist/esm/core/agent/buildAgentMessageApiChart.js.map +1 -1
- package/dist/esm/core/agent/buildMessageApiChart.d.ts +32 -0
- package/dist/esm/core/agent/buildMessageApiChart.js +27 -4
- package/dist/esm/core/agent/buildMessageApiChart.js.map +1 -1
- package/dist/esm/core/agent/buildToolRegistry.d.ts +80 -31
- package/dist/esm/core/agent/buildToolRegistry.js +90 -33
- package/dist/esm/core/agent/buildToolRegistry.js.map +1 -1
- package/dist/esm/core/agent/messageApiReceipt.d.ts +82 -0
- package/dist/esm/core/agent/messageApiReceipt.js +73 -0
- package/dist/esm/core/agent/messageApiReceipt.js.map +1 -0
- package/dist/esm/core/agent/stages/callLLM.js +3 -7
- package/dist/esm/core/agent/stages/callLLM.js.map +1 -1
- package/dist/esm/core/agent/stages/toolCalls.d.ts +43 -5
- package/dist/esm/core/agent/stages/toolCalls.js +174 -27
- package/dist/esm/core/agent/stages/toolCalls.js.map +1 -1
- package/dist/esm/core/agent/types.d.ts +15 -0
- package/dist/esm/core/slots/buildToolsSlot.d.ts +100 -0
- package/dist/esm/core/slots/buildToolsSlot.js +207 -61
- package/dist/esm/core/slots/buildToolsSlot.js.map +1 -1
- package/dist/esm/events/payloads.d.ts +92 -18
- 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/lib/time-travel/receipt.d.ts +45 -13
- package/dist/esm/lib/time-travel/receipt.js +41 -10
- package/dist/esm/lib/time-travel/receipt.js.map +1 -1
- package/dist/esm/lib/time-travel/servedView.d.ts +36 -35
- package/dist/esm/lib/time-travel/servedView.js +64 -43
- package/dist/esm/lib/time-travel/servedView.js.map +1 -1
- package/dist/events/registry.js +4 -0
- package/dist/events/registry.js.map +1 -1
- package/dist/lib/time-travel/receipt.js +43 -11
- package/dist/lib/time-travel/receipt.js.map +1 -1
- package/dist/lib/time-travel/servedView.js +64 -43
- package/dist/lib/time-travel/servedView.js.map +1 -1
- package/dist/types/core/Agent.d.ts.map +1 -1
- package/dist/types/core/LLMCall.d.ts +18 -0
- package/dist/types/core/LLMCall.d.ts.map +1 -1
- package/dist/types/core/agent/buildAgentMessageApiChart.d.ts +22 -0
- package/dist/types/core/agent/buildAgentMessageApiChart.d.ts.map +1 -1
- package/dist/types/core/agent/buildMessageApiChart.d.ts +32 -0
- package/dist/types/core/agent/buildMessageApiChart.d.ts.map +1 -1
- package/dist/types/core/agent/buildToolRegistry.d.ts +80 -31
- package/dist/types/core/agent/buildToolRegistry.d.ts.map +1 -1
- package/dist/types/core/agent/messageApiReceipt.d.ts +83 -0
- package/dist/types/core/agent/messageApiReceipt.d.ts.map +1 -0
- package/dist/types/core/agent/stages/callLLM.d.ts.map +1 -1
- package/dist/types/core/agent/stages/toolCalls.d.ts +43 -5
- package/dist/types/core/agent/stages/toolCalls.d.ts.map +1 -1
- package/dist/types/core/agent/types.d.ts +15 -0
- package/dist/types/core/agent/types.d.ts.map +1 -1
- package/dist/types/core/slots/buildToolsSlot.d.ts +100 -0
- package/dist/types/core/slots/buildToolsSlot.d.ts.map +1 -1
- package/dist/types/events/payloads.d.ts +92 -18
- 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/lib/time-travel/receipt.d.ts +45 -13
- package/dist/types/lib/time-travel/receipt.d.ts.map +1 -1
- package/dist/types/lib/time-travel/servedView.d.ts +36 -35
- package/dist/types/lib/time-travel/servedView.d.ts.map +1 -1
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -544,7 +544,7 @@ files `agentfootprint.tools.coverage_declared`; with
|
|
|
544
544
|
to the final answer, which is how a limit survives a model that would rather not
|
|
545
545
|
mention it.
|
|
546
546
|
|
|
547
|
-
### Observability —
|
|
547
|
+
### Observability — 111 typed events across 24 domains
|
|
548
548
|
|
|
549
549
|
```typescript
|
|
550
550
|
agent.on('agentfootprint.context.injected', (e) =>
|
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,219 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [9.92.1] - 2026-09-11
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **9.92.0 never reached npm; this release is the same code.** Its publish job
|
|
15
|
+
failed the docs site's deferred-demo gzip ceiling by 0.4 KB (421.0 KB against
|
|
16
|
+
420.6 KB): the interactive demo bundles the library itself, and 9.92.0's
|
|
17
|
+
tool-resolution family rides the same main-entry graph as the receipt family
|
|
18
|
+
did in 9.88.0. The ceiling is re-baselined ~2% over the measurement with the
|
|
19
|
+
reasoning beside the number, and the docs-truth report regenerated. No
|
|
20
|
+
library code changes between 9.92.0 and 9.92.1. This is the fourth raise of
|
|
21
|
+
that ceiling for a family the demo never calls; the dynamic-import fix named
|
|
22
|
+
in 9.61.0 is the next move rather than a fifth raise.
|
|
23
|
+
|
|
24
|
+
## [9.92.0] - 2026-09-11
|
|
25
|
+
|
|
26
|
+
**The offer and the answer are one party.** At every LLM call the model is
|
|
27
|
+
OFFERED a list of tool contracts (the wire; the receipt hashes each one), and
|
|
28
|
+
when it calls a name something ANSWERS. Until this release those two halves
|
|
29
|
+
could come from different parties for one name: the tools slot merges
|
|
30
|
+
`[static, provider, skill, step]` first-occurrence-wins, while dispatch
|
|
31
|
+
consulted the build-time registry first — so a provider's contract on the wire
|
|
32
|
+
was answered by a skill's `execute` (an INACTIVE skill's, even), a provider's
|
|
33
|
+
`skip_step` by the framework's (which then advanced the procedure on a call the
|
|
34
|
+
model made against somebody else's contract), and the report that exists for
|
|
35
|
+
this seam walked `activeInjections` and named the provider on epochs whose wire
|
|
36
|
+
carried the skill's contract. A claimant that lost both the wire and the
|
|
37
|
+
dispatch was simply dead, 22 rows of it in the divergence walk's baseline, with
|
|
38
|
+
nothing on the record. `docs/design/2026-09-the-offer-and-the-answer.md` states
|
|
39
|
+
the law; recorded-not-built entries 1, 2 and 3, the `claim-swallowed` bullet
|
|
40
|
+
under entry 1 and the 9.91.0 tools-slot follow-up are marked built.
|
|
41
|
+
|
|
42
|
+
**The law:** for every tool name on a call, exactly one party owns the OFFER and
|
|
43
|
+
the same party owns the ANSWER — or the record names the disagreement. Three
|
|
44
|
+
consequences, one example each:
|
|
45
|
+
|
|
46
|
+
- **Dispatch follows the offer.** `buildToolsSlot.ts` · `mergeWire` is the one
|
|
47
|
+
pass that produces the wire AND the record of who won each name
|
|
48
|
+
(`ServedToolParties`, closure-shared like `ProviderToolCache`, never scope
|
|
49
|
+
state); `toolCalls.ts` · `lookupTool` reads it first. A provider and a
|
|
50
|
+
never-activated scoped skill both claiming `shared_tool`: the wire carries
|
|
51
|
+
the provider's contract, the provider's tool answers, and the skill's
|
|
52
|
+
`execute` answers no call while the provider holds the name — nor after the
|
|
53
|
+
provider withdraws it, because the skill's contract was never what the
|
|
54
|
+
model read: that call is REFUSED as a recorded tool result (`toolCalls.ts`
|
|
55
|
+
· `notServedResult`). A name NOT on this epoch's wire — a held-out step
|
|
56
|
+
tool, a parked map's tool, a scoped tool named from a restored transcript —
|
|
57
|
+
still dispatches (the capability law's held-out clause, `epoch-laws.test.ts`
|
|
58
|
+
1(a)–(e)), but only to the party the model LAST read the name under
|
|
59
|
+
(`ServedToolParties.lastServed`) or the name's only holder when it was never
|
|
60
|
+
served; every such dispatch is on the record as the new
|
|
61
|
+
`agentfootprint.tools.answered_off_wire` (`{ toolName, toolCallId,
|
|
62
|
+
iteration, answeredBy, answeredById? }`). A pause that re-dispatches on
|
|
63
|
+
resume (a middleware ask, a check-in, a credential consent) carries the
|
|
64
|
+
served party on its checkpoint (`pausedToolParty`, pause-path-only), so a
|
|
65
|
+
resume in a FRESH Agent instance — empty closure, no Compose — cannot fall
|
|
66
|
+
back to the build-time map's first holder either.
|
|
67
|
+
- **The report's subject is the wire.** `agentfootprint.tools.shadowed` now
|
|
68
|
+
fires once per contested name per iteration when two contracts COMPETED for
|
|
69
|
+
the wire, and `schemaFrom`/`dispatchTo` both name the wire's party — they
|
|
70
|
+
agree by construction. A stepped skill and a provider sharing a name draw
|
|
71
|
+
`skill 'desk-stepped'` in both halves on every epoch, never `'provider'`.
|
|
72
|
+
The vocabulary gained `'framework'` (`ToolNameChannel`), so an auto-attach
|
|
73
|
+
is named as itself.
|
|
74
|
+
- **A dead claim is reported.** New `agentfootprint.tools.claim_swallowed`
|
|
75
|
+
(`ToolsClaimSwallowedPayload`: `{ toolName, iteration, lostBy, lostById?,
|
|
76
|
+
wonBy, wonById? }`, names only) fires once per iteration for every party
|
|
77
|
+
whose claim to a name is held by somebody else — whether its contract
|
|
78
|
+
competed (an active skill against a provider) or never reached the merge
|
|
79
|
+
(the same skill while inactive; a provider tool whose name a static
|
|
80
|
+
`.tool()` owns; the framework's `skip_step` between tenures). Identity is by
|
|
81
|
+
IMPLEMENTATION: two skills sharing one `Tool` reference (documented-legal)
|
|
82
|
+
are one claim and draw nothing. Now 111 typed events across 24 domains.
|
|
83
|
+
|
|
84
|
+
**`skip_step` is a claimant like any other** (`buildToolRegistry.ts` ·
|
|
85
|
+
`toolClaimants`, the registry's new list of every build-time claimant per
|
|
86
|
+
name — a list, not a winner). Its schema still merges last, so it rides the
|
|
87
|
+
wire only when nobody else put the name forward; when a provider serves
|
|
88
|
+
`skip_step`, the provider's tool answers and the step bookkeeping keys on the
|
|
89
|
+
framework's own instance having answered (`toolCalls.ts` ·
|
|
90
|
+
`frameworkSkipStepAnswered`) — the procedure does not advance. The build-time
|
|
91
|
+
refusals (a static `.tool()` or a skill tool named `skip_step`/`present`) stand.
|
|
92
|
+
|
|
93
|
+
**`buildAgentMessageApiChart` hands the model the declared tool set on every
|
|
94
|
+
turn.** Its tools-slot mount now says `arrayMerge: ArrayMergeMode.Replace`, as
|
|
95
|
+
the agent charts always did; turn 2 no longer serves `['weather','weather']`.
|
|
96
|
+
|
|
97
|
+
**Byte-identity for every run with no name collision.**
|
|
98
|
+
`test/core/tools/byte-identity.test.ts` drives fifteen collision-free shapes
|
|
99
|
+
(both agent react modes, a skill-graph hop, a stepped skill, a parked map, the
|
|
100
|
+
wrap-up, a tool-forced output, three provider shapes, two skills sharing one
|
|
101
|
+
`Tool` reference, `LLMCall`, both message-API charts) and compares `commitLog`
|
|
102
|
+
and `servedAt(k)` against references under `test/core/tools/reference/`
|
|
103
|
+
generated on the 9.91.0 tree. All fifteen are identical; the
|
|
104
|
+
receipt-conformance suite is unchanged and green on all four chart shapes.
|
|
105
|
+
|
|
106
|
+
**The divergence walk, re-recorded — and widened.** Every `contract-swap`
|
|
107
|
+
row (12) and every `report-misattributed` row (10) is GONE and ratcheted so
|
|
108
|
+
it cannot reopen quietly; the `claim-swallowed` family is 35 rows, every one
|
|
109
|
+
carrying what `tools.claim_swallowed` said about it. The walk gained the
|
|
110
|
+
cross-epoch × collision cases it never had (walk D: a provider withdrawing a
|
|
111
|
+
name an inactive skill also holds; a fresh-instance resume of a provider's
|
|
112
|
+
call) and a kind for the held-out dispatch the law keeps, `answered-off-wire`
|
|
113
|
+
(4 rows, each carrying the event). The harness moved to
|
|
114
|
+
`test/core/agent/toolDivergenceWalk.harness.ts` so the reproductions in
|
|
115
|
+
`test/core/tools/offer-and-answer.test.ts` — the entries' own, verbatim, each
|
|
116
|
+
red on 9.91.0, plus the review's own shapes — drive the same configurations.
|
|
117
|
+
|
|
118
|
+
**Consumer-facing changes, stated plainly.** (1) A provider tool that shares a
|
|
119
|
+
name with a skill tool now RUNS where the skill's used to — the contract the
|
|
120
|
+
model read is the one that answers. (2) `tools.shadowed` fires on
|
|
121
|
+
configurations that were silent (a provider against a static `.tool()` or a
|
|
122
|
+
framework auto-attach) and no longer names `'provider'` as `schemaFrom` where
|
|
123
|
+
the wire carried the skill's contract; `dispatchTo` now equals `schemaFrom`.
|
|
124
|
+
(3) Two new events, `tools.claim_swallowed` and `tools.answered_off_wire`.
|
|
125
|
+
(4) A call to a name that left the wire, whose last-served party can no longer
|
|
126
|
+
answer, is refused with a recorded result where it used to be answered by
|
|
127
|
+
whichever party the build-time map held first; the same sentence answers a
|
|
128
|
+
provider-served call resumed in a fresh instance (where it used to read
|
|
129
|
+
`Unknown tool`). (5) Two stale comments in `buildToolsSlot.ts` and
|
|
130
|
+
`buildToolRegistry.ts` corrected in the same diff; `Agent.ts`'s "fresh chart
|
|
131
|
+
per run()" comment corrected — the chart is built once at construction.
|
|
132
|
+
|
|
133
|
+
## [9.91.0] - 2026-09-10
|
|
134
|
+
|
|
135
|
+
**Every chart that serves a model now mints a receipt.** A receipt is the proof
|
|
136
|
+
of what the model was actually handed, minted at the call and committed in the
|
|
137
|
+
bundle the call already writes — and until this release exactly ONE stage minted
|
|
138
|
+
one. Three other charts in this library handed a model a request and left
|
|
139
|
+
`no-receipt-on-chart` on every view they produced, so a reader of an `LLMCall`
|
|
140
|
+
or messageAPI recording could only ever see Reconstructed, never Verified.
|
|
141
|
+
|
|
142
|
+
Two reasons were on the record for that. **Neither survived.** The first — that
|
|
143
|
+
`Receipt.cache.transform` has no honest value on a chart running no cache
|
|
144
|
+
strategy — was already refuted in 9.88.0 and left refuted in the source: an
|
|
145
|
+
`Agent` with a pass-through strategy records `'unchanged'` today, and the value
|
|
146
|
+
is true for the same reason where no strategy exists at all, because *the
|
|
147
|
+
request that went out IS the request that was assembled*. **No fourth enum value
|
|
148
|
+
was added.** The second — the salt — never applied to `LLMCall`, which owns its
|
|
149
|
+
executor and mints a run id exactly as `Agent` does. It DOES apply to the two
|
|
150
|
+
messageAPI charts, and that was verified rather than assumed: footprintjs stamps
|
|
151
|
+
`TraversalContext.runId` on recorder events, not on a stage's scope; there is no
|
|
152
|
+
`$runId` on `ScopeFacade`; `ExecutionEnv` is a fixed type carrying `traceId` and
|
|
153
|
+
no run id. A chart builder run on somebody else's executor genuinely cannot
|
|
154
|
+
invent the value — so it is a dep, and a chart given none mints NOTHING rather
|
|
155
|
+
than salting every hash with an empty string.
|
|
156
|
+
|
|
157
|
+
### Added
|
|
158
|
+
|
|
159
|
+
- **`LLMCall` mints a receipt** (`LLMCall.ts` · `callLLM`), salted with the run
|
|
160
|
+
id `createExecutor` already mints per run — read at CALL time, not closed over
|
|
161
|
+
at build time, so the second run of the same `LLMCall` is not salted with the
|
|
162
|
+
first run's value. `servedAt` on an `LLMCall` recording now carries
|
|
163
|
+
`basis.model`, `params` and the cache verdict, and stops raising
|
|
164
|
+
`no-receipt-on-chart`.
|
|
165
|
+
- **`LLMCallOptions.recordReceipt`** — the twin of `AgentOptions.recordReceipt`,
|
|
166
|
+
same field, same contract, default ON. `false` declines the mint (one
|
|
167
|
+
commit-log value and a SHA-256 per piece, per message, per tool schema);
|
|
168
|
+
`servedAt` still rebuilds the view and declares the missing witness.
|
|
169
|
+
- **`MessageApiChartDeps.getRunId` / `AgentMessageApiChartDeps.getRunId`** —
|
|
170
|
+
supply the run id and the chart mints on every turn; omit it and it mints
|
|
171
|
+
none. `src/core/agent/messageApiReceipt.ts` owns that rule for both charts,
|
|
172
|
+
because the two are deliberate twins and a mint written out in each is two
|
|
173
|
+
chances to disagree about what the model was handed.
|
|
174
|
+
- **`receipt.ts` · `receiptPieces`** — the injection-record → receipt-piece map,
|
|
175
|
+
which was about to have four copies. One owner, calling the same
|
|
176
|
+
`contributingPieces` the system-prompt join calls, so a piece cannot be on the
|
|
177
|
+
receipt and absent from the string.
|
|
178
|
+
|
|
179
|
+
### Fixed
|
|
180
|
+
|
|
181
|
+
- **`servedAt` reported an EMPTY tool list on a call that served tools.**
|
|
182
|
+
`servedView.ts` · `viewOf` read the served list from `dynamicToolSchemas`
|
|
183
|
+
alone. The agent charts map the tools slot's output onto that key at the mount
|
|
184
|
+
boundary; the messageAPI charts carry it out under the slot's own name — so a
|
|
185
|
+
`buildAgentMessageApiChart` view said `tools.names: []` about a call that
|
|
186
|
+
served one. An empty list is not an omission, it is a DENIAL, and it went
|
|
187
|
+
unnoticed for as long as no receipt existed to contradict it. The read is now
|
|
188
|
+
a fallback chain (the agent key first, so no agent recording changes), the
|
|
189
|
+
same shape the conversation has had since 9.88.0. Red before, on
|
|
190
|
+
`test/lib/time-travel/receipt-conformance.test.ts` · *the tool the model was
|
|
191
|
+
served is hashed by the receipt AND rebuilt from the log*.
|
|
192
|
+
|
|
193
|
+
### Changed
|
|
194
|
+
|
|
195
|
+
- **`SERVED_GAPS['no-receipt-on-chart']` is unchanged, and still true.** Its
|
|
196
|
+
printed sentence never named a chart, so nothing in it went false; the
|
|
197
|
+
MECHANISM comment beside it now names the shapes that still reach it — a
|
|
198
|
+
messageAPI chart handed no run id, a run that declined with `recordReceipt:
|
|
199
|
+
false`, a recording made before 9.88.0, and a consumer's own `call-llm` stage,
|
|
200
|
+
which this library does not mint for. The cause `'no-receipt-committed'` is
|
|
201
|
+
still driven by a REAL run in both walks; the driver moved from an `LLMCall`
|
|
202
|
+
(which now mints) to a messageAPI chart with no run id.
|
|
203
|
+
- **The composed request is assembled once per chart.** Each of the three
|
|
204
|
+
charts now builds ONE `LLMRequest` object and both sends it and fingerprints
|
|
205
|
+
it, and each routes its conversation through `stripFrameworkFields` — the
|
|
206
|
+
third rule of the one assembly — so the mint and the rebuild cannot drift.
|
|
207
|
+
Every other byte those charts commit is unchanged: measured by dumping each
|
|
208
|
+
chart's commit log, its per-bundle keys and its final state before and after,
|
|
209
|
+
and diffing (identical apart from the new `receipt` key).
|
|
210
|
+
|
|
211
|
+
### Docs
|
|
212
|
+
|
|
213
|
+
- `src/lib/time-travel/README.md` — a "Which charts mint a receipt" table (chart
|
|
214
|
+
→ mints? → the salt) with the builder example, and every measurement that
|
|
215
|
+
named an `LLMCall` view as receipt-less retaken on the shape that still is.
|
|
216
|
+
- `docs-next` `debug/time-travel.mdx` — the same section for the site. No new
|
|
217
|
+
route.
|
|
218
|
+
- `docs/design/2026-09-recorded-not-built.md` — entry 8's reproduction retaken
|
|
219
|
+
(it still stands; only its driver moved) and an appendix marking the standing
|
|
220
|
+
no-mint fact BUILT in 9.91.0, with the reasons that died and the one that
|
|
221
|
+
survives.
|
|
222
|
+
|
|
10
223
|
## [9.90.0] - 2026-09-10
|
|
11
224
|
|
|
12
225
|
**The recording carries its own milestones.** Until now a stored run could not
|
package/CLAUDE.md
CHANGED
|
@@ -154,7 +154,7 @@ Traps: `src/observability/` holds the finder IMPLEMENTATIONS (canonical home; `d
|
|
|
154
154
|
- **Embedder fingerprint** (8.9.0) → `Embedder.id` (optional; every shipped embedder sets one, and NONE include dims — the store appends `@<dims>` itself, so an id carrying its own size double-stamps) + `indexDocuments` defaulting `embedderId` to it + `SqliteVectorStore.reconcileFingerprint` (the only comparison site). Rule: dimensions ALWAYS decide, model ids decide only when BOTH sides named themselves — refusing on an absent name would block the majority of callers who never pass `embedderId`.
|
|
155
155
|
- **Retrieval record** (8.8.0) → FOUR stages write one object in sequence: `loadRelevant` (candidates+scores+threshold verdicts) → `pickByBudget` (re-marks admitted→over-budget/over-max-entries) → `formatDefault` (`promptFragment` + `promptPosition`) → the read mount's outputMapper lifts it to root as `retrievalEvidence_<id>`. `memoryRecallInjections` then splits ONE recall into one ActiveInjection PER CHUNK — guarded by a byte-equality check (`fragments.join('\n\n') === systemContent`) that falls back to the single injection rather than change the prompt. `rank` (score order) and `promptPosition` (picker order) are DIFFERENT and both load-bearing: joining fragments in rank order reproduces the right bytes in a sequence the model never saw.
|
|
156
156
|
- **AgentState** → all 8 stages/ files, both builders' mappers, memory-wire STRING-TYPED keys ('runIdentity'/'turnNumber'/… buildAgentChart.ts:177-180 — not refactor-safe), finalizeResult's `reliabilityFail*`/`policyHalt*` reads (rename silently kills the typed errors).
|
|
157
|
-
- **events/** →
|
|
157
|
+
- **events/** → 111 typed events across 24 domains (counts anti-drift-tested against this file — update BOTH when adding events): ALL_EVENT_TYPES exhaustiveness tests, DomainWildcard hand-list, ~42 importers (recorders, strategies, stream, commentary).
|
|
158
158
|
- **Run-configuration manifest (9.41.0)** → `agentfootprint.agent.run_configured`, the JOIN KEY that turns N runs into N labelled ARMS: one event naming the adapters/strategies in play (provider+model, reactMode, each memory's declared strategy/retrieval/embedder, window, graph posture+classifier, evidence posture, artifacts-present). Composed by the PURE `core/agent/runManifest.ts`, dispatched from `Agent.emitRunManifest()` at the END of `createExecutor` — the ONE funnel `run()` AND `resume()` share, both of which mint a fresh runId. Direct `dispatcher.dispatch` with a STATED pseudo-stage (`run-configured#0`), the `emitToolSessionReport` precedent — there is no stage yet, and `minimalMeta()` would make the one joinable-by-design event unjoinable. TWO laws, both tested: NAMES ONLY (a store is reported PRESENT and unnamed rather than identified by a directory/endpoint — `MemoryStore` and `ArtifactStore` declare no id), and ABSENT means "not configured", never a guessed `'default'`. Graph presence is read off `skillGraphNextSkill`, NOT `skillGraphCascade` (a 9.16-style mount sets no cascade and would read as "no graph"). `MemoryDefinition` gained `strategy`/`retrieval`/`embedderId` for it — declared names the compiled pipeline had closed over, the `store`-in-the-open precedent.
|
|
159
159
|
- **adapters/types.ts LLMMessage/LLMRequest** → 62 importers: tool_use round-trip (toolCalls.ts:115-135), wire assembly (callLLM.ts:150-160), providers, cache strategies, security/extractSequence, reliability loop.
|
|
160
160
|
- **Cache** → strategy registration is a MODULE SIDE EFFECT (src/index.ts:15-17); an entry point skipping that import silently falls back to NoOp. Resolved once per Agent at construction (Agent.ts:347).
|
|
@@ -252,7 +252,7 @@ const agent = Agent.create({ provider, model })
|
|
|
252
252
|
agent.on('agentfootprint.context.evaluated', (e) => console.log(e.payload.activeIds));
|
|
253
253
|
```
|
|
254
254
|
|
|
255
|
-
**
|
|
255
|
+
**111 typed events across 24 domains.** Two subscription shapes and no third:
|
|
256
256
|
`'*'` (every event) and `'agentfootprint.<domain>.*'` (one domain). **`'agentfootprint.*'`
|
|
257
257
|
is not a pattern** — TypeScript rejects it, and at runtime it would match nothing.
|
|
258
258
|
|
package/dist/core/Agent.js
CHANGED
|
@@ -2980,7 +2980,7 @@ class Agent extends RunnerBase_js_1.RunnerBase {
|
|
|
2980
2980
|
// auto-attached `present` tool when a store is attached, 9.22.0) +
|
|
2981
2981
|
// skill-supplied tools (with autoActivate scoping); validates
|
|
2982
2982
|
// name uniqueness; produces the dispatch map.
|
|
2983
|
-
const { registryByName, toolSchemas, toolDeclaringSkills } = (0, buildToolRegistry_js_1.buildToolRegistry)(registry, this.injections, {
|
|
2983
|
+
const { registryByName, toolSchemas, toolDeclaringSkills, toolClaimants } = (0, buildToolRegistry_js_1.buildToolRegistry)(registry, this.injections, {
|
|
2984
2984
|
hasArtifactStore: artifactStore !== undefined,
|
|
2985
2985
|
});
|
|
2986
2986
|
// A statically registered tool that declares `wants` on an agent with no
|
|
@@ -3137,13 +3137,25 @@ class Agent extends RunnerBase_js_1.RunnerBase {
|
|
|
3137
3137
|
const messagesSubflow = (0, buildMessagesSlot_js_1.buildMessagesSlot)({
|
|
3138
3138
|
...(budget?.messages !== undefined && { budgetCap: budget.messages }),
|
|
3139
3139
|
});
|
|
3140
|
-
//
|
|
3141
|
-
//
|
|
3142
|
-
//
|
|
3143
|
-
//
|
|
3144
|
-
//
|
|
3145
|
-
//
|
|
3140
|
+
// Cache shared between buildToolsSlot (writer, each iteration) and
|
|
3141
|
+
// buildToolCallsHandler (reader, same iteration). Holds the resolved
|
|
3142
|
+
// Tool[] from `provider.list(ctx)` so dispatch doesn't re-invoke `list()`
|
|
3143
|
+
// — vital for async network providers.
|
|
3144
|
+
//
|
|
3145
|
+
// LIFETIME, stated correctly (9.92.0): the chart is built ONCE, at
|
|
3146
|
+
// construction (`initChart`), and reused by every `run()` and `resume()`
|
|
3147
|
+
// of this Agent — so this cache and the record below outlive a run. They
|
|
3148
|
+
// are safe because one Agent runs one turn at a time and the slot
|
|
3149
|
+
// overwrites them every iteration before dispatch reads them. What that
|
|
3150
|
+
// does NOT cover is a resume in a FRESH instance, whose closure is empty
|
|
3151
|
+
// and whose Compose never re-runs before the resumed dispatch — which is
|
|
3152
|
+
// why the pause paths carry `pausedToolParty` on the checkpoint.
|
|
3146
3153
|
const providerToolCache = { current: [] };
|
|
3154
|
+
// Who put each name on the wire (9.92.0) — the same closure-shared shape,
|
|
3155
|
+
// written by the tools slot's merge and read by dispatch so the party
|
|
3156
|
+
// whose contract the model read is the party that answers. `lastServed`
|
|
3157
|
+
// is the run's memory of the same fact, for a name that left the wire.
|
|
3158
|
+
const servedTools = { current: new Map(), lastServed: new Map() };
|
|
3147
3159
|
const readSkillFor = this.readSkillOfferFor();
|
|
3148
3160
|
// Per-role skill visibility. The RESOLVER is handed to the tools slot, which
|
|
3149
3161
|
// is the fact's one owner: it resolves the ids once per iteration and
|
|
@@ -3225,6 +3237,8 @@ class Agent extends RunnerBase_js_1.RunnerBase {
|
|
|
3225
3237
|
integrityLedger: this.integrityLedgerHolder,
|
|
3226
3238
|
...(this.externalToolProvider && { toolProvider: this.externalToolProvider }),
|
|
3227
3239
|
...(this.externalToolProvider && { providerToolCache }),
|
|
3240
|
+
toolClaimants,
|
|
3241
|
+
servedTools,
|
|
3228
3242
|
...(readSkillFor && { readSkillFor }),
|
|
3229
3243
|
...(hiddenSkillIds && { hiddenSkillIds }),
|
|
3230
3244
|
...(budget?.tools !== undefined && { budgetCap: budget.tools }),
|
|
@@ -3397,6 +3411,8 @@ class Agent extends RunnerBase_js_1.RunnerBase {
|
|
|
3397
3411
|
}),
|
|
3398
3412
|
...(this.externalToolProvider && { externalToolProvider: this.externalToolProvider }),
|
|
3399
3413
|
...(this.externalToolProvider && { providerToolCache }),
|
|
3414
|
+
servedTools,
|
|
3415
|
+
toolClaimants,
|
|
3400
3416
|
...(permissionChecker && { permissionChecker }),
|
|
3401
3417
|
...(credentialProvider && { credentialProvider }),
|
|
3402
3418
|
// The claim-check store (9.21.0). Absent → not one new line runs in
|