agentfootprint 8.0.0 → 8.2.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.
Files changed (148) hide show
  1. package/AGENTS.md +14 -9
  2. package/README.md +11 -7
  3. package/ai-instructions/claude-code/SKILL.md +1 -1
  4. package/ai-instructions/clinerules +1 -1
  5. package/ai-instructions/copilot-instructions.md +1 -1
  6. package/ai-instructions/cursor/agentfootprint.md +1 -1
  7. package/ai-instructions/kiro/agentfootprint.md +1 -1
  8. package/ai-instructions/windsurfrules +1 -1
  9. package/dist/adapters/llm/OllamaProvider.js +628 -0
  10. package/dist/adapters/llm/OllamaProvider.js.map +1 -0
  11. package/dist/adapters/llm/OpenAIProvider.js +12 -21
  12. package/dist/adapters/llm/OpenAIProvider.js.map +1 -1
  13. package/dist/adapters/llm/createProvider.js +35 -6
  14. package/dist/adapters/llm/createProvider.js.map +1 -1
  15. package/dist/core/Agent.js +44 -1
  16. package/dist/core/Agent.js.map +1 -1
  17. package/dist/core/agent/stages/seed.js +10 -0
  18. package/dist/core/agent/stages/seed.js.map +1 -1
  19. package/dist/core/agent/stages/window.js +21 -0
  20. package/dist/core/agent/stages/window.js.map +1 -1
  21. package/dist/core/agent/window/errors.js +4 -3
  22. package/dist/core/agent/window/errors.js.map +1 -1
  23. package/dist/core/agent/window/folded.js +98 -0
  24. package/dist/core/agent/window/folded.js.map +1 -0
  25. package/dist/core/agent/window/index.js +9 -1
  26. package/dist/core/agent/window/index.js.map +1 -1
  27. package/dist/core/agent/window/options.js +18 -2
  28. package/dist/core/agent/window/options.js.map +1 -1
  29. package/dist/core/agent/window/strategies/slidingWindow.js +2 -2
  30. package/dist/core/agent/window/strategies/summarizeOldest.js +25 -2
  31. package/dist/core/agent/window/strategies/summarizeOldest.js.map +1 -1
  32. package/dist/core/agent/window/summarize.js +27 -1
  33. package/dist/core/agent/window/summarize.js.map +1 -1
  34. package/dist/core/agent/window/types.js +6 -0
  35. package/dist/core/agent/window/types.js.map +1 -1
  36. package/dist/core/runCheckpoint.js +9 -1
  37. package/dist/core/runCheckpoint.js.map +1 -1
  38. package/dist/esm/adapters/llm/OllamaProvider.d.ts +182 -0
  39. package/dist/esm/adapters/llm/OllamaProvider.js +622 -0
  40. package/dist/esm/adapters/llm/OllamaProvider.js.map +1 -0
  41. package/dist/esm/adapters/llm/OpenAIProvider.d.ts +0 -12
  42. package/dist/esm/adapters/llm/OpenAIProvider.js +11 -19
  43. package/dist/esm/adapters/llm/OpenAIProvider.js.map +1 -1
  44. package/dist/esm/adapters/llm/createProvider.d.ts +25 -8
  45. package/dist/esm/adapters/llm/createProvider.js +35 -6
  46. package/dist/esm/adapters/llm/createProvider.js.map +1 -1
  47. package/dist/esm/core/Agent.d.ts +17 -0
  48. package/dist/esm/core/Agent.js +44 -1
  49. package/dist/esm/core/Agent.js.map +1 -1
  50. package/dist/esm/core/agent/stages/seed.d.ts +11 -0
  51. package/dist/esm/core/agent/stages/seed.js +10 -0
  52. package/dist/esm/core/agent/stages/seed.js.map +1 -1
  53. package/dist/esm/core/agent/stages/window.d.ts +13 -0
  54. package/dist/esm/core/agent/stages/window.js +21 -0
  55. package/dist/esm/core/agent/stages/window.js.map +1 -1
  56. package/dist/esm/core/agent/types.d.ts +15 -1
  57. package/dist/esm/core/agent/window/errors.js +4 -3
  58. package/dist/esm/core/agent/window/errors.js.map +1 -1
  59. package/dist/esm/core/agent/window/folded.d.ts +90 -0
  60. package/dist/esm/core/agent/window/folded.js +92 -0
  61. package/dist/esm/core/agent/window/folded.js.map +1 -0
  62. package/dist/esm/core/agent/window/index.d.ts +7 -1
  63. package/dist/esm/core/agent/window/index.js +6 -0
  64. package/dist/esm/core/agent/window/index.js.map +1 -1
  65. package/dist/esm/core/agent/window/options.d.ts +7 -1
  66. package/dist/esm/core/agent/window/options.js +17 -1
  67. package/dist/esm/core/agent/window/options.js.map +1 -1
  68. package/dist/esm/core/agent/window/strategies/slidingWindow.d.ts +2 -2
  69. package/dist/esm/core/agent/window/strategies/slidingWindow.js +2 -2
  70. package/dist/esm/core/agent/window/strategies/summarizeOldest.d.ts +4 -2
  71. package/dist/esm/core/agent/window/strategies/summarizeOldest.js +25 -2
  72. package/dist/esm/core/agent/window/strategies/summarizeOldest.js.map +1 -1
  73. package/dist/esm/core/agent/window/strategy.d.ts +26 -1
  74. package/dist/esm/core/agent/window/summarize.d.ts +11 -0
  75. package/dist/esm/core/agent/window/summarize.js +27 -1
  76. package/dist/esm/core/agent/window/summarize.js.map +1 -1
  77. package/dist/esm/core/agent/window/types.d.ts +106 -1
  78. package/dist/esm/core/agent/window/types.js +6 -0
  79. package/dist/esm/core/agent/window/types.js.map +1 -1
  80. package/dist/esm/core/runCheckpoint.d.ts +32 -1
  81. package/dist/esm/core/runCheckpoint.js +9 -1
  82. package/dist/esm/core/runCheckpoint.js.map +1 -1
  83. package/dist/esm/index.d.ts +1 -1
  84. package/dist/esm/index.js +6 -1
  85. package/dist/esm/index.js.map +1 -1
  86. package/dist/esm/providers.d.ts +13 -5
  87. package/dist/esm/providers.js +13 -5
  88. package/dist/esm/providers.js.map +1 -1
  89. package/dist/esm/thinking/OllamaThinkingHandler.d.ts +60 -0
  90. package/dist/esm/thinking/OllamaThinkingHandler.js +107 -0
  91. package/dist/esm/thinking/OllamaThinkingHandler.js.map +1 -0
  92. package/dist/esm/thinking/index.d.ts +1 -0
  93. package/dist/esm/thinking/index.js +1 -0
  94. package/dist/esm/thinking/index.js.map +1 -1
  95. package/dist/esm/thinking/registry.js +2 -0
  96. package/dist/esm/thinking/registry.js.map +1 -1
  97. package/dist/index.js +9 -2
  98. package/dist/index.js.map +1 -1
  99. package/dist/providers.js +16 -6
  100. package/dist/providers.js.map +1 -1
  101. package/dist/thinking/OllamaThinkingHandler.js +111 -0
  102. package/dist/thinking/OllamaThinkingHandler.js.map +1 -0
  103. package/dist/thinking/index.js +4 -1
  104. package/dist/thinking/index.js.map +1 -1
  105. package/dist/thinking/registry.js +2 -0
  106. package/dist/thinking/registry.js.map +1 -1
  107. package/dist/types/adapters/llm/OllamaProvider.d.ts +183 -0
  108. package/dist/types/adapters/llm/OllamaProvider.d.ts.map +1 -0
  109. package/dist/types/adapters/llm/OpenAIProvider.d.ts +0 -12
  110. package/dist/types/adapters/llm/OpenAIProvider.d.ts.map +1 -1
  111. package/dist/types/adapters/llm/createProvider.d.ts +25 -8
  112. package/dist/types/adapters/llm/createProvider.d.ts.map +1 -1
  113. package/dist/types/core/Agent.d.ts +17 -0
  114. package/dist/types/core/Agent.d.ts.map +1 -1
  115. package/dist/types/core/agent/stages/seed.d.ts +11 -0
  116. package/dist/types/core/agent/stages/seed.d.ts.map +1 -1
  117. package/dist/types/core/agent/stages/window.d.ts +13 -0
  118. package/dist/types/core/agent/stages/window.d.ts.map +1 -1
  119. package/dist/types/core/agent/types.d.ts +15 -1
  120. package/dist/types/core/agent/types.d.ts.map +1 -1
  121. package/dist/types/core/agent/window/errors.d.ts.map +1 -1
  122. package/dist/types/core/agent/window/folded.d.ts +91 -0
  123. package/dist/types/core/agent/window/folded.d.ts.map +1 -0
  124. package/dist/types/core/agent/window/index.d.ts +7 -1
  125. package/dist/types/core/agent/window/index.d.ts.map +1 -1
  126. package/dist/types/core/agent/window/options.d.ts +7 -1
  127. package/dist/types/core/agent/window/options.d.ts.map +1 -1
  128. package/dist/types/core/agent/window/strategies/slidingWindow.d.ts +2 -2
  129. package/dist/types/core/agent/window/strategies/summarizeOldest.d.ts +4 -2
  130. package/dist/types/core/agent/window/strategies/summarizeOldest.d.ts.map +1 -1
  131. package/dist/types/core/agent/window/strategy.d.ts +26 -1
  132. package/dist/types/core/agent/window/strategy.d.ts.map +1 -1
  133. package/dist/types/core/agent/window/summarize.d.ts +11 -0
  134. package/dist/types/core/agent/window/summarize.d.ts.map +1 -1
  135. package/dist/types/core/agent/window/types.d.ts +106 -1
  136. package/dist/types/core/agent/window/types.d.ts.map +1 -1
  137. package/dist/types/core/runCheckpoint.d.ts +32 -1
  138. package/dist/types/core/runCheckpoint.d.ts.map +1 -1
  139. package/dist/types/index.d.ts +1 -1
  140. package/dist/types/index.d.ts.map +1 -1
  141. package/dist/types/providers.d.ts +13 -5
  142. package/dist/types/providers.d.ts.map +1 -1
  143. package/dist/types/thinking/OllamaThinkingHandler.d.ts +61 -0
  144. package/dist/types/thinking/OllamaThinkingHandler.d.ts.map +1 -0
  145. package/dist/types/thinking/index.d.ts +1 -0
  146. package/dist/types/thinking/index.d.ts.map +1 -1
  147. package/dist/types/thinking/registry.d.ts.map +1 -1
  148. package/package.json +3 -1
@@ -14,6 +14,12 @@
14
14
  * runtimeStageId whose messages left. A compacted (or trimmed) run is still a
15
15
  * provable run.
16
16
  *
17
+ * A commit log is memory, though, and a conversation outlives the process that
18
+ * held it. So a strategy may also hand back `folded` spans — the durable form
19
+ * of the same fact — and this stage commits them to `scope.foldedSpans`, which
20
+ * `agent.checkpoint()` carries onto the conversation. A compacted CONVERSATION
21
+ * is still a provable conversation, in the next process and the one after.
22
+ *
17
23
  * This file is deliberately all WIRING. The decision — what the window should
18
24
  * become — lives behind `WindowStrategy` (window/strategy.ts, public since
19
25
  * 7.17), so the duty to record, emit and cost what happened stays in exactly
@@ -52,6 +58,13 @@ export interface WindowStageDeps {
52
58
  readonly agentModel: string;
53
59
  /** The MAIN provider's name, for a refusal that names it. */
54
60
  readonly providerName: string;
61
+ /**
62
+ * The current run's id, read per run (the stage is built once, at chart
63
+ * build time, and outlives every run it serves). A strategy that retains
64
+ * what it removed stamps this on the span, so a stored conversation can say
65
+ * which run's commit log used to hold those messages.
66
+ */
67
+ readonly getRunId?: () => string | undefined;
55
68
  /** Optional pricing adapter, so a summarizer call is costed like any other. */
56
69
  readonly pricingTable?: PricingTable;
57
70
  /** Optional cumulative USD cap per run. */
@@ -14,6 +14,12 @@
14
14
  * runtimeStageId whose messages left. A compacted (or trimmed) run is still a
15
15
  * provable run.
16
16
  *
17
+ * A commit log is memory, though, and a conversation outlives the process that
18
+ * held it. So a strategy may also hand back `folded` spans — the durable form
19
+ * of the same fact — and this stage commits them to `scope.foldedSpans`, which
20
+ * `agent.checkpoint()` carries onto the conversation. A compacted CONVERSATION
21
+ * is still a provable conversation, in the next process and the one after.
22
+ *
17
23
  * This file is deliberately all WIRING. The decision — what the window should
18
24
  * become — lives behind `WindowStrategy` (window/strategy.ts, public since
19
25
  * 7.17), so the duty to record, emit and cost what happened stays in exactly
@@ -71,6 +77,9 @@ export function buildWindowStage(deps) {
71
77
  turns,
72
78
  measured: metered === undefined ? undefined : { input: metered.input, output: metered.output },
73
79
  iteration: scope.iteration ?? 1,
80
+ // 'unknown' rather than a fabricated id: a span that cannot name its run
81
+ // should say so, not invent a plausible-looking answer.
82
+ runId: deps.getRunId?.() ?? 'unknown',
74
83
  agentModel: deps.agentModel,
75
84
  providerName: deps.providerName,
76
85
  signal: scope.$getEnv?.()?.signal,
@@ -93,6 +102,18 @@ export function buildWindowStage(deps) {
93
102
  }
94
103
  const prior = scope.compactions ?? [];
95
104
  scope.compactions = [...prior, result.record];
105
+ // The durable half, written in the SAME commit as the window change and
106
+ // the record above. That co-location is the guarantee: there is no state,
107
+ // and no failure, in which messages left the window and the record of what
108
+ // they were did not follow them — no second transaction to fail, no I/O to
109
+ // time out, nothing to roll back. A strategy that removed nothing (or
110
+ // replaced nothing) omits `folded`, and then this key is never written,
111
+ // so an agent whose strategy does not retain commits exactly the keys it
112
+ // always did.
113
+ if (result.folded !== undefined && result.folded.length > 0) {
114
+ const priorFolds = scope.foldedSpans ?? [];
115
+ scope.foldedSpans = [...priorFolds, ...result.folded];
116
+ }
96
117
  // One eviction per message that left, in the slot vocabulary consumers
97
118
  // already subscribe to. The hash uses the SAME formula the messages slot
98
119
  // used to report the piece as injected, so evicted and injected refer to
@@ -1 +1 @@
1
- {"version":3,"file":"window.js","sourceRoot":"","sources":["../../../../../src/core/agent/stages/window.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"window.js","sourceRoot":"","sources":["../../../../../src/core/agent/stages/window.ts"],"names":[],"mappings":"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"}
@@ -18,7 +18,7 @@ import type { CredentialProvider } from '../../identity/types.js';
18
18
  import type { ToolArgValidationMode } from './toolArgsValidation.js';
19
19
  import type { ThinkingBlock } from '../../thinking/types.js';
20
20
  import type { ReliabilityScope } from '../../reliability/types.js';
21
- import type { WindowRecord } from './window/types.js';
21
+ import type { FoldedSpan, WindowRecord } from './window/types.js';
22
22
  import type { MessagesDelivery } from './delivery/types.js';
23
23
  import type { MiddlewareDecision } from './middleware/types.js';
24
24
  import type { OutputAttempt } from './outputEnforcement.js';
@@ -475,6 +475,20 @@ export interface AgentState {
475
475
  * than break every reader for a better word. Narrow a record by its
476
476
  * `strategy` field, not by the key it lives under. */
477
477
  compactions?: readonly WindowRecord[];
478
+ /** The DURABLE half of the same law: one span per fold, carrying what the
479
+ * summary stands for and — under `retain: 'conversation'`, the default —
480
+ * the folded messages themselves.
481
+ *
482
+ * `compactions` is a record of what a RUN did and dies with the run's
483
+ * commit log. This is what a CONVERSATION carries: `agent.checkpoint()`
484
+ * copies it onto `AgentRunCheckpoint.folded`, `resumeOnError` restores it,
485
+ * and so a standing agent's spans accumulate across every turn, every
486
+ * restart and every deploy.
487
+ *
488
+ * Written only when a strategy actually replaced messages with something
489
+ * that stands for them (today: `summarizeOldest`). Absent otherwise, so an
490
+ * agent that never folds commits exactly the keys it always did. */
491
+ foldedSpans?: readonly FoldedSpan[];
478
492
  /** Set when a `PermissionChecker` returns `{ result: 'halt', ... }`.
479
493
  * `Agent.run()` reads these at the API boundary and throws a typed
480
494
  * `PolicyHaltError` carrying the same context — the chart $break's
@@ -27,9 +27,10 @@ export class CompactionUnmeasurableError extends Error {
27
27
  `tokens for the last call, so the window cannot be measured against thresholdTokens. ` +
28
28
  `Compaction refuses rather than guess the size of the window or leave a configured ` +
29
29
  `budget silently unenforced. Fixes: use a provider that reports usage (anthropic, ` +
30
- `openai, bedrock and the mock provider all do), or remove .compaction() from this agent. ` +
31
- `Note that some OpenAI-compatible endpoints (Ollama, vLLM) do not send usage while ` +
32
- `streaming.`);
30
+ `openai, bedrock, ollama and the mock provider all do), or remove .compaction() from ` +
31
+ `this agent. Note that an OpenAI-COMPATIBLE endpoint reached through openai({ baseURL }) ` +
32
+ `may not send usage while streaming — for a local model, ollama() talks the native API ` +
33
+ `and always reports it.`);
33
34
  this.provider = provider;
34
35
  }
35
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../../../src/core/agent/window/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,2BAA4B,SAAQ,KAAK;IAClC,IAAI,GAAG,6BAA6B,CAAC;IACvD,4DAA4D;IACnD,QAAQ,CAAS;IAE1B,YAAY,QAAgB;QAC1B,KAAK,CACH,iDAAiD,QAAQ,kCAAkC;YACzF,sFAAsF;YACtF,oFAAoF;YACpF,mFAAmF;YACnF,0FAA0F;YAC1F,oFAAoF;YACpF,YAAY,CACf,CAAC;QACF,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;CACF"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../../../src/core/agent/window/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,2BAA4B,SAAQ,KAAK;IAClC,IAAI,GAAG,6BAA6B,CAAC;IACvD,4DAA4D;IACnD,QAAQ,CAAS;IAE1B,YAAY,QAAgB;QAC1B,KAAK,CACH,iDAAiD,QAAQ,kCAAkC;YACzF,sFAAsF;YACtF,oFAAoF;YACpF,mFAAmF;YACnF,sFAAsF;YACtF,0FAA0F;YAC1F,wFAAwF;YACxF,wBAAwB,CAC3B,CAAC;QACF,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;CACF"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * window/folded — join a summary sitting in a conversation back to what it
3
+ * stands for.
4
+ *
5
+ * Pattern: Pure lookup over recorded facts. No I/O, no inference.
6
+ * Role: core/ layer, and the ONE public door onto retained originals.
7
+ * Emits: N/A.
8
+ *
9
+ * ── Why a fingerprint and not an index ──────────────────────────────────────
10
+ * The obvious join key is "the summary is at `history[3]`". It is also wrong.
11
+ * A later fold swallows the span that CONTAINS an earlier summary, and every
12
+ * index after it moves; a conversation that folded four times would need its
13
+ * stored indices rewritten on every fold, and any reader holding an old one
14
+ * would silently be pointing at somebody else's message.
15
+ *
16
+ * So the join key is a fingerprint of the summary message's full content —
17
+ * authored frame included. Three things follow, and all three are the point:
18
+ *
19
+ * • it costs NO extra bytes on the wire (no id token planted in the frame);
20
+ * • it survives JSON, storage, and being read by a runtime that has never
21
+ * heard of this function;
22
+ * • it cannot be FORGED. A model that writes a message opening with the
23
+ * frame's own words produces different content, therefore a different
24
+ * fingerprint, therefore no match — `isCompactedSummary` alone says "this
25
+ * LOOKS like a frame", and this says "this IS the frame of a fold that was
26
+ * recorded". The two answers are different questions and the gap between
27
+ * them is exactly where a forgery would live.
28
+ *
29
+ * ── Absent is an answer ─────────────────────────────────────────────────────
30
+ * `undefined` means "no fold was recorded for this message" and never "there
31
+ * were no originals". A conversation stored by 8.1 has summaries and no spans
32
+ * at all; one folded under `retain: 'discard'` has a span whose `messages` is
33
+ * absent. Those are three different facts and the caller can tell them apart:
34
+ * no span, a span with no messages, a span with messages.
35
+ */
36
+ import type { LLMMessage } from '../../../adapters/types.js';
37
+ import type { FoldedSpan } from './types.js';
38
+ /**
39
+ * The join key for one summary message: a fingerprint of its whole content.
40
+ *
41
+ * @internal Consumers join through {@link foldedSpanFor}; this is exported for
42
+ * the strategy that stamps the span and for tests that pin the two agree.
43
+ */
44
+ export declare function summaryFingerprint(content: string): string;
45
+ /**
46
+ * The smallest thing that can answer "what did this conversation fold?".
47
+ *
48
+ * Structural rather than `AgentRunCheckpoint` on purpose: it also fits a
49
+ * paused run's `conversation`, a hand-built fixture, and anything a consumer
50
+ * pulled out of their own store — and it keeps this file from importing the
51
+ * checkpoint module, which imports this one's sibling types.
52
+ */
53
+ export interface FoldedConversation {
54
+ readonly folded?: readonly FoldedSpan[];
55
+ }
56
+ /**
57
+ * What one summary message in a conversation stands for.
58
+ *
59
+ * Hand it the conversation you stored and a message out of its `history`; get
60
+ * back the fold that produced that message, with the original messages when
61
+ * the policy retained them.
62
+ *
63
+ * @returns the span, or `undefined` when this conversation recorded no fold
64
+ * for this message — see "Absent is an answer" above.
65
+ *
66
+ * @example Show a user what the agent actually saw last week
67
+ * ```ts
68
+ * import { foldedSpanFor, isCompactedSummary } from 'agentfootprint';
69
+ *
70
+ * const conversation = readEnvelope(await sessions.hydrate(sessionId));
71
+ * for (const message of conversation.history) {
72
+ * if (!isCompactedSummary(message)) continue;
73
+ * const span = foldedSpanFor(conversation, message);
74
+ * console.log(`summary of ${span?.messageCount ?? '?'} messages`);
75
+ * for (const original of span?.messages ?? []) {
76
+ * console.log(` ${original.role}: ${original.content}`);
77
+ * }
78
+ * }
79
+ * ```
80
+ */
81
+ export declare function foldedSpanFor(conversation: FoldedConversation, message: LLMMessage): FoldedSpan | undefined;
82
+ /**
83
+ * Every message this conversation ever folded, oldest fold first, flattened.
84
+ *
85
+ * The transcript-shaped answer to `foldedSpanFor`'s message-shaped one: what
86
+ * a support view prints when somebody asks what the agent was told before the
87
+ * summaries. Spans that were discarded contribute nothing — they have nothing
88
+ * to contribute, and `foldedSpanFor` is where you find out that they existed.
89
+ */
90
+ export declare function foldedMessages(conversation: FoldedConversation): readonly LLMMessage[];
@@ -0,0 +1,92 @@
1
+ /**
2
+ * window/folded — join a summary sitting in a conversation back to what it
3
+ * stands for.
4
+ *
5
+ * Pattern: Pure lookup over recorded facts. No I/O, no inference.
6
+ * Role: core/ layer, and the ONE public door onto retained originals.
7
+ * Emits: N/A.
8
+ *
9
+ * ── Why a fingerprint and not an index ──────────────────────────────────────
10
+ * The obvious join key is "the summary is at `history[3]`". It is also wrong.
11
+ * A later fold swallows the span that CONTAINS an earlier summary, and every
12
+ * index after it moves; a conversation that folded four times would need its
13
+ * stored indices rewritten on every fold, and any reader holding an old one
14
+ * would silently be pointing at somebody else's message.
15
+ *
16
+ * So the join key is a fingerprint of the summary message's full content —
17
+ * authored frame included. Three things follow, and all three are the point:
18
+ *
19
+ * • it costs NO extra bytes on the wire (no id token planted in the frame);
20
+ * • it survives JSON, storage, and being read by a runtime that has never
21
+ * heard of this function;
22
+ * • it cannot be FORGED. A model that writes a message opening with the
23
+ * frame's own words produces different content, therefore a different
24
+ * fingerprint, therefore no match — `isCompactedSummary` alone says "this
25
+ * LOOKS like a frame", and this says "this IS the frame of a fold that was
26
+ * recorded". The two answers are different questions and the gap between
27
+ * them is exactly where a forgery would live.
28
+ *
29
+ * ── Absent is an answer ─────────────────────────────────────────────────────
30
+ * `undefined` means "no fold was recorded for this message" and never "there
31
+ * were no originals". A conversation stored by 8.1 has summaries and no spans
32
+ * at all; one folded under `retain: 'discard'` has a span whose `messages` is
33
+ * absent. Those are three different facts and the caller can tell them apart:
34
+ * no span, a span with no messages, a span with messages.
35
+ */
36
+ import { fnv1a } from '../../slots/helpers.js';
37
+ /**
38
+ * The join key for one summary message: a fingerprint of its whole content.
39
+ *
40
+ * @internal Consumers join through {@link foldedSpanFor}; this is exported for
41
+ * the strategy that stamps the span and for tests that pin the two agree.
42
+ */
43
+ export function summaryFingerprint(content) {
44
+ return fnv1a(content);
45
+ }
46
+ /**
47
+ * What one summary message in a conversation stands for.
48
+ *
49
+ * Hand it the conversation you stored and a message out of its `history`; get
50
+ * back the fold that produced that message, with the original messages when
51
+ * the policy retained them.
52
+ *
53
+ * @returns the span, or `undefined` when this conversation recorded no fold
54
+ * for this message — see "Absent is an answer" above.
55
+ *
56
+ * @example Show a user what the agent actually saw last week
57
+ * ```ts
58
+ * import { foldedSpanFor, isCompactedSummary } from 'agentfootprint';
59
+ *
60
+ * const conversation = readEnvelope(await sessions.hydrate(sessionId));
61
+ * for (const message of conversation.history) {
62
+ * if (!isCompactedSummary(message)) continue;
63
+ * const span = foldedSpanFor(conversation, message);
64
+ * console.log(`summary of ${span?.messageCount ?? '?'} messages`);
65
+ * for (const original of span?.messages ?? []) {
66
+ * console.log(` ${original.role}: ${original.content}`);
67
+ * }
68
+ * }
69
+ * ```
70
+ */
71
+ export function foldedSpanFor(conversation, message) {
72
+ const spans = conversation.folded;
73
+ if (spans === undefined || spans.length === 0)
74
+ return undefined;
75
+ const fingerprint = summaryFingerprint(message.content);
76
+ return spans.find((span) => span.summaryFingerprint === fingerprint);
77
+ }
78
+ /**
79
+ * Every message this conversation ever folded, oldest fold first, flattened.
80
+ *
81
+ * The transcript-shaped answer to `foldedSpanFor`'s message-shaped one: what
82
+ * a support view prints when somebody asks what the agent was told before the
83
+ * summaries. Spans that were discarded contribute nothing — they have nothing
84
+ * to contribute, and `foldedSpanFor` is where you find out that they existed.
85
+ */
86
+ export function foldedMessages(conversation) {
87
+ const out = [];
88
+ for (const span of conversation.folded ?? [])
89
+ out.push(...(span.messages ?? []));
90
+ return out;
91
+ }
92
+ //# sourceMappingURL=folded.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"folded.js","sourceRoot":"","sources":["../../../../../src/core/agent/window/folded.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAI/C;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC;AACxB,CAAC;AAcD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,aAAa,CAC3B,YAAgC,EAChC,OAAmB;IAEnB,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,CAAC;IAClC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAChE,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACxD,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,kBAAkB,KAAK,WAAW,CAAC,CAAC;AACvE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,YAAgC;IAC7D,MAAM,GAAG,GAAiB,EAAE,CAAC;IAC7B,KAAK,MAAM,IAAI,IAAI,YAAY,CAAC,MAAM,IAAI,EAAE;QAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC;IACjF,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -8,6 +8,11 @@
8
8
  * is a claim about the past, so this library files it as a claim — not as the
9
9
  * past. A drop is an absence, and it is named the same way.
10
10
  *
11
+ * A commit log lives as long as the process. A conversation lives longer, so
12
+ * `.compaction({ retain })` also carries the folded originals on the
13
+ * conversation checkpoint — `foldedSpanFor(conversation, message)` is the door
14
+ * back to them, in this process or the one after the deploy.
15
+ *
11
16
  * Three strategies ship, all sharing one turn segmentation and one refusal
12
17
  * engine:
13
18
  * `summarizeOldest` fold the oldest span into a summary (`.compaction()`)
@@ -17,7 +22,8 @@
17
22
  * Public surface (re-exported from the package root).
18
23
  */
19
24
  export { CompactionUnmeasurableError } from './errors.js';
20
- export type { CompactionOptions, CompactionRecord, FoldRefusal, FoldRefusalReason, ResolvedCompaction, SlidingWindowOptions, SlidingWindowRecord, TokenBudgetOptions, TokenBudgetRecord, WindowRecord, WindowRefusal, WindowRefusalReason, } from './types.js';
25
+ export type { CompactionOptions, CompactionRecord, CompactionRetention, FoldedSpan, FoldRefusal, FoldRefusalReason, ResolvedCompaction, SlidingWindowOptions, SlidingWindowRecord, TokenBudgetOptions, TokenBudgetRecord, WindowRecord, WindowRefusal, WindowRefusalReason, } from './types.js';
26
+ export { foldedMessages, foldedSpanFor, type FoldedConversation } from './folded.js';
21
27
  export type { RemovalFacts, WindowEviction, WindowStrategy, WindowStrategyInput, WindowStrategyResult, } from './strategy.js';
22
28
  export type { RemovalPlan, Turn } from './turns.js';
23
29
  export { COMPACTED_FRAME_PREFIX, isCompactedSummary } from './summarize.js';
@@ -8,6 +8,11 @@
8
8
  * is a claim about the past, so this library files it as a claim — not as the
9
9
  * past. A drop is an absence, and it is named the same way.
10
10
  *
11
+ * A commit log lives as long as the process. A conversation lives longer, so
12
+ * `.compaction({ retain })` also carries the folded originals on the
13
+ * conversation checkpoint — `foldedSpanFor(conversation, message)` is the door
14
+ * back to them, in this process or the one after the deploy.
15
+ *
11
16
  * Three strategies ship, all sharing one turn segmentation and one refusal
12
17
  * engine:
13
18
  * `summarizeOldest` fold the oldest span into a summary (`.compaction()`)
@@ -17,6 +22,7 @@
17
22
  * Public surface (re-exported from the package root).
18
23
  */
19
24
  export { CompactionUnmeasurableError } from './errors.js';
25
+ export { foldedMessages, foldedSpanFor } from './folded.js';
20
26
  export { COMPACTED_FRAME_PREFIX, isCompactedSummary } from './summarize.js';
21
27
  export { DROP_NOTICE_PREFIX, isDropNotice } from './notice.js';
22
28
  export { summarizeOldest } from './strategies/summarizeOldest.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/agent/window/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAC;AAuB1D,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/agent/window/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAC;AAiB1D,OAAO,EAAE,cAAc,EAAE,aAAa,EAA2B,MAAM,aAAa,CAAC;AASrF,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC"}
@@ -13,9 +13,15 @@
13
13
  * out to be nonsense on iteration 40 of a paid run is a policy that cost you
14
14
  * money to discover.
15
15
  */
16
- import type { CompactionOptions, ResolvedCompaction, SlidingWindowOptions, TokenBudgetOptions } from './types.js';
16
+ import type { CompactionOptions, CompactionRetention, ResolvedCompaction, SlidingWindowOptions, TokenBudgetOptions } from './types.js';
17
17
  /** Default depth of the "never touch this" recent window. */
18
18
  export declare const DEFAULT_KEEP_RECENT_TURNS = 6;
19
+ /**
20
+ * What happens to folded messages when nobody said. The originals ride with
21
+ * the conversation: losing them has to be a choice somebody typed, not a
22
+ * default they inherited.
23
+ */
24
+ export declare const DEFAULT_RETENTION: CompactionRetention;
19
25
  /**
20
26
  * Validate `.compaction()` / `summarizeOldest()` options.
21
27
  *
@@ -15,6 +15,13 @@
15
15
  */
16
16
  /** Default depth of the "never touch this" recent window. */
17
17
  export const DEFAULT_KEEP_RECENT_TURNS = 6;
18
+ /**
19
+ * What happens to folded messages when nobody said. The originals ride with
20
+ * the conversation: losing them has to be a choice somebody typed, not a
21
+ * default they inherited.
22
+ */
23
+ export const DEFAULT_RETENTION = 'conversation';
24
+ const RETENTIONS = ['conversation', 'discard'];
18
25
  function requireObject(options, label, shape) {
19
26
  if (options === null || typeof options !== 'object') {
20
27
  throw new Error(`${label}: expected an options object (${shape}), got ${typeof options}.`);
@@ -43,7 +50,7 @@ function requireKeepRecentTurns(keepRecentTurns, label) {
43
50
  */
44
51
  export function resolveCompactionOptions(options, label) {
45
52
  requireObject(options, label, '{ thresholdTokens, summarizer, ... }');
46
- const { thresholdTokens, summarizer, keepRecentTurns, model } = options;
53
+ const { thresholdTokens, summarizer, keepRecentTurns, model, retain } = options;
47
54
  requireThreshold(thresholdTokens, label);
48
55
  if (summarizer === null ||
49
56
  typeof summarizer !== 'object' ||
@@ -57,11 +64,20 @@ export function resolveCompactionOptions(options, label) {
57
64
  if (model !== undefined && (typeof model !== 'string' || model.length === 0)) {
58
65
  throw new Error(`${label}: model must be a non-empty model id, got ${String(model)}.`);
59
66
  }
67
+ if (retain !== undefined && !RETENTIONS.includes(retain)) {
68
+ throw new Error(`${label}: retain must be ${RETENTIONS.map((r) => `'${r}'`).join(' or ')}, got ` +
69
+ `${String(retain)}. It decides what happens to the messages a fold removes: ` +
70
+ `'conversation' (the default) carries them on the conversation checkpoint so a ` +
71
+ `restart can still produce them, and 'discard' does not. A value this library does ` +
72
+ `not recognise is refused rather than treated as one of them — guessing here would ` +
73
+ `mean guessing whether to keep somebody's transcript.`);
74
+ }
60
75
  return {
61
76
  thresholdTokens,
62
77
  keepRecentTurns: keepRecentTurns ?? DEFAULT_KEEP_RECENT_TURNS,
63
78
  summarizer,
64
79
  model,
80
+ retain: retain ?? DEFAULT_RETENTION,
65
81
  };
66
82
  }
67
83
  /** Validate `slidingWindow()` options. */
@@ -1 +1 @@
1
- {"version":3,"file":"options.js","sourceRoot":"","sources":["../../../../../src/core/agent/window/options.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"options.js","sourceRoot":"","sources":["../../../../../src/core/agent/window/options.ts"],"names":[],"mappings":"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"}
@@ -37,10 +37,10 @@ export declare const SLIDING_WINDOW = "sliding-window";
37
37
  * @example
38
38
  * ```ts
39
39
  * import { Agent, slidingWindow } from 'agentfootprint';
40
- * import { ollama } from 'agentfootprint/llm-providers';
40
+ * import { ollama } from 'agentfootprint/providers';
41
41
  *
42
42
  * // Works on a provider that reports no usage at all: the trigger is turns.
43
- * const agent = Agent.create({ provider: ollama(), model: 'llama3' })
43
+ * const agent = Agent.create({ provider: ollama('llama3.2'), model: 'llama3.2' })
44
44
  * .window(slidingWindow({ keepRecentTurns: 12 }))
45
45
  * .build();
46
46
  * ```
@@ -37,10 +37,10 @@ export const SLIDING_WINDOW = 'sliding-window';
37
37
  * @example
38
38
  * ```ts
39
39
  * import { Agent, slidingWindow } from 'agentfootprint';
40
- * import { ollama } from 'agentfootprint/llm-providers';
40
+ * import { ollama } from 'agentfootprint/providers';
41
41
  *
42
42
  * // Works on a provider that reports no usage at all: the trigger is turns.
43
- * const agent = Agent.create({ provider: ollama(), model: 'llama3' })
43
+ * const agent = Agent.create({ provider: ollama('llama3.2'), model: 'llama3.2' })
44
44
  * .window(slidingWindow({ keepRecentTurns: 12 }))
45
45
  * .build();
46
46
  * ```
@@ -10,8 +10,10 @@
10
10
  * This is what `.compaction({...})` configures, and the market's familiar
11
11
  * move (Claude Code / the Claude Agent SDK call it compaction). What is
12
12
  * different here is not the fold — it is that the fold is filed as a claim:
13
- * a summary is a claim ABOUT the past, and the past itself stays in the
14
- * commit log, byte for byte.
13
+ * a summary is a claim ABOUT the past, and the past itself stays. In the
14
+ * commit log for as long as the process lives, and since 8.2, under
15
+ * `retain: 'conversation'` — on the conversation checkpoint for as long as
16
+ * the conversation does, which is the half a standing agent actually needs.
15
17
  *
16
18
  * Everything it decides, it explains. Every engaged path returns a record —
17
19
  * including the paths that change nothing, which are the ones a person
@@ -10,14 +10,17 @@
10
10
  * This is what `.compaction({...})` configures, and the market's familiar
11
11
  * move (Claude Code / the Claude Agent SDK call it compaction). What is
12
12
  * different here is not the fold — it is that the fold is filed as a claim:
13
- * a summary is a claim ABOUT the past, and the past itself stays in the
14
- * commit log, byte for byte.
13
+ * a summary is a claim ABOUT the past, and the past itself stays. In the
14
+ * commit log for as long as the process lives, and since 8.2, under
15
+ * `retain: 'conversation'` — on the conversation checkpoint for as long as
16
+ * the conversation does, which is the half a standing agent actually needs.
15
17
  *
16
18
  * Everything it decides, it explains. Every engaged path returns a record —
17
19
  * including the paths that change nothing, which are the ones a person
18
20
  * debugging an over-budget window actually needs.
19
21
  */
20
22
  import { CompactionUnmeasurableError } from '../errors.js';
23
+ import { summaryFingerprint } from '../folded.js';
21
24
  import { resolveCompactionOptions } from '../options.js';
22
25
  import { indexRange } from '../removal.js';
23
26
  import { buildSummaryMessage, isCompactedSummary, runSummarizer } from '../summarize.js';
@@ -122,6 +125,7 @@ export function summarizeOldest(options) {
122
125
  foldedMessageCount: span.length,
123
126
  iteration,
124
127
  model,
128
+ retain: config.retain,
125
129
  });
126
130
  const spend = { model, usage: summary.usage };
127
131
  // Would the fold actually help? A summary plus its authored frame can be
@@ -140,6 +144,24 @@ export function summarizeOldest(options) {
140
144
  const foldedAtMs = input.now();
141
145
  const facts = input.removalFacts(indexRange(spanStart, spanEnd), foldedAtMs);
142
146
  const window = [...head, summaryMessage, ...tail];
147
+ // The durable half. It rides the SAME result the window change rides,
148
+ // so the stage commits both together — there is no ordering in which
149
+ // the messages leave and the record of what they were does not follow.
150
+ // Under 'discard' the span is still filed: a discard is an absence, and
151
+ // this family files absences the same way it files claims.
152
+ const foldedSpan = {
153
+ summaryFingerprint: summaryFingerprint(summaryMessage.content),
154
+ runId: input.runId,
155
+ iteration,
156
+ foldedAtMs,
157
+ model,
158
+ messageCount: span.length,
159
+ removedStageIds: facts.removedStageIds,
160
+ retained: config.retain,
161
+ // Detached before it is handed on: `history` came off a live scope and
162
+ // a stored conversation must never hold a reference into the heap.
163
+ ...(config.retain === 'conversation' && { messages: span.map((m) => ({ ...m })) }),
164
+ };
143
165
  const record = {
144
166
  ...base,
145
167
  removedStageIds: facts.removedStageIds,
@@ -161,6 +183,7 @@ export function summarizeOldest(options) {
161
183
  },
162
184
  record,
163
185
  evictions: facts.evictions,
186
+ folded: [foldedSpan],
164
187
  budgetPressure: {
165
188
  capTokens: config.thresholdTokens,
166
189
  projectedTokens: measured.input,
@@ -1 +1 @@
1
- {"version":3,"file":"summarizeOldest.js","sourceRoot":"","sources":["../../../../../../src/core/agent/window/strategies/summarizeOldest.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"summarizeOldest.js","sourceRoot":"","sources":["../../../../../../src/core/agent/window/strategies/summarizeOldest.ts"],"names":[],"mappings":"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"}
@@ -39,7 +39,7 @@
39
39
  */
40
40
  import type { LLMMessage } from '../../../adapters/types.js';
41
41
  import type { Turn, RemovalPlan } from './turns.js';
42
- import type { WindowRecord } from './types.js';
42
+ import type { FoldedSpan, WindowRecord } from './types.js';
43
43
  /** One message leaving the window, with the facts an eviction event needs. */
44
44
  export interface WindowEviction {
45
45
  /** Index in the PRE-change window — the index the content hash was built on. */
@@ -76,6 +76,16 @@ export interface WindowStrategyInput {
76
76
  } | undefined;
77
77
  /** The ReAct iteration this decision belongs to. */
78
78
  readonly iteration: number;
79
+ /**
80
+ * The run this decision belongs to.
81
+ *
82
+ * A strategy that retains what it removed has to name the run whose commit
83
+ * log held it — that is the honest answer to "where else could I have found
84
+ * this?", and the answer is "nowhere, once that process ended", which is the
85
+ * whole reason retention exists. `'unknown'` when the runtime could not name
86
+ * the run, never a fabricated id.
87
+ */
88
+ readonly runId: string;
79
89
  /** The agent's own model — the sensible default for a strategy that bills. */
80
90
  readonly agentModel: string;
81
91
  /** `provider.name` of the MAIN provider, for a refusal that names it. */
@@ -128,6 +138,21 @@ export interface WindowStrategyResult {
128
138
  readonly record: WindowRecord;
129
139
  /** Messages that left the window, for `context.evicted`. */
130
140
  readonly evictions: readonly WindowEviction[];
141
+ /**
142
+ * Spans this visit removed, in the form that OUTLIVES the process: appended
143
+ * to the conversation checkpoint, so a restart can still say what a summary
144
+ * stands for — and, under `retain: 'conversation'`, produce it verbatim.
145
+ *
146
+ * OMIT IT unless your strategy replaced messages with something that stands
147
+ * for them. `summarizeOldest` fills it because a summary is a claim that
148
+ * needs its evidence; the drop strategies do not, because a drop replaces
149
+ * nothing and its authored notice claims nothing.
150
+ *
151
+ * The stage writes these in the SAME commit as the window change, so there
152
+ * is no state in which messages left the window and the record of what they
153
+ * were did not follow them.
154
+ */
155
+ readonly folded?: readonly FoldedSpan[];
131
156
  /**
132
157
  * The budget reading to report on `agentfootprint.context.budget_pressure`.
133
158
  *