@framers/agentos 0.1.247 → 0.1.249

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 (47) hide show
  1. package/dist/memory/CognitiveMemoryManager.d.ts +47 -0
  2. package/dist/memory/CognitiveMemoryManager.d.ts.map +1 -1
  3. package/dist/memory/CognitiveMemoryManager.js +54 -0
  4. package/dist/memory/CognitiveMemoryManager.js.map +1 -1
  5. package/dist/memory/core/types.d.ts +31 -0
  6. package/dist/memory/core/types.d.ts.map +1 -1
  7. package/dist/memory/index.d.ts +13 -1
  8. package/dist/memory/index.d.ts.map +1 -1
  9. package/dist/memory/index.js +24 -0
  10. package/dist/memory/index.js.map +1 -1
  11. package/dist/memory/ingest/SessionSummarizer.d.ts +155 -0
  12. package/dist/memory/ingest/SessionSummarizer.d.ts.map +1 -0
  13. package/dist/memory/ingest/SessionSummarizer.js +178 -0
  14. package/dist/memory/ingest/SessionSummarizer.js.map +1 -0
  15. package/dist/memory/retrieval/fact-supersession/FactSupersession.d.ts +82 -0
  16. package/dist/memory/retrieval/fact-supersession/FactSupersession.d.ts.map +1 -0
  17. package/dist/memory/retrieval/fact-supersession/FactSupersession.js +159 -0
  18. package/dist/memory/retrieval/fact-supersession/FactSupersession.js.map +1 -0
  19. package/dist/memory/retrieval/fact-supersession/index.d.ts +10 -0
  20. package/dist/memory/retrieval/fact-supersession/index.d.ts.map +1 -0
  21. package/dist/memory/retrieval/fact-supersession/index.js +9 -0
  22. package/dist/memory/retrieval/fact-supersession/index.js.map +1 -0
  23. package/dist/memory/retrieval/hybrid/HybridRetriever.d.ts +151 -0
  24. package/dist/memory/retrieval/hybrid/HybridRetriever.d.ts.map +1 -0
  25. package/dist/memory/retrieval/hybrid/HybridRetriever.js +287 -0
  26. package/dist/memory/retrieval/hybrid/HybridRetriever.js.map +1 -0
  27. package/dist/memory/retrieval/hybrid/index.d.ts +12 -0
  28. package/dist/memory/retrieval/hybrid/index.d.ts.map +1 -0
  29. package/dist/memory/retrieval/hybrid/index.js +10 -0
  30. package/dist/memory/retrieval/hybrid/index.js.map +1 -0
  31. package/dist/memory/retrieval/hybrid/reciprocalRankFusion.d.ts +87 -0
  32. package/dist/memory/retrieval/hybrid/reciprocalRankFusion.d.ts.map +1 -0
  33. package/dist/memory/retrieval/hybrid/reciprocalRankFusion.js +88 -0
  34. package/dist/memory/retrieval/hybrid/reciprocalRankFusion.js.map +1 -0
  35. package/dist/memory/retrieval/session/SessionRetriever.d.ts +123 -0
  36. package/dist/memory/retrieval/session/SessionRetriever.d.ts.map +1 -0
  37. package/dist/memory/retrieval/session/SessionRetriever.js +220 -0
  38. package/dist/memory/retrieval/session/SessionRetriever.js.map +1 -0
  39. package/dist/memory/retrieval/session/SessionSummaryStore.d.ts +122 -0
  40. package/dist/memory/retrieval/session/SessionSummaryStore.d.ts.map +1 -0
  41. package/dist/memory/retrieval/session/SessionSummaryStore.js +142 -0
  42. package/dist/memory/retrieval/session/SessionSummaryStore.js.map +1 -0
  43. package/dist/memory/retrieval/session/index.d.ts +12 -0
  44. package/dist/memory/retrieval/session/index.d.ts.map +1 -0
  45. package/dist/memory/retrieval/session/index.js +10 -0
  46. package/dist/memory/retrieval/session/index.js.map +1 -0
  47. package/package.json +1 -1
@@ -0,0 +1,155 @@
1
+ /**
2
+ * @file SessionSummarizer.ts
3
+ * @description Session-level contextual retrieval (Anthropic Sep 2024
4
+ * variant, adapted to conversational memory).
5
+ *
6
+ * ## What this does
7
+ *
8
+ * For each session in a benchmark case (e.g. a `conv-26` chat thread in
9
+ * LOCOMO or a `haystack_sessions[i]` entry in LongMemEval), an LLM
10
+ * generates a dense 50–100 token summary that captures the topic,
11
+ * key user-stated facts (names, numbers, dates, preferences), and key
12
+ * assistant-stated facts. That summary is then prepended to *every*
13
+ * chunk produced from that session before embedding — giving the
14
+ * embedding vector global session context it would otherwise lack.
15
+ *
16
+ * ## Why session-granularity (not per-chunk)
17
+ *
18
+ * Anthropic's canonical
19
+ * {@link https://www.anthropic.com/news/contextual-retrieval Contextual Retrieval}
20
+ * prepends context *per chunk*. That's right for heterogeneous documents
21
+ * where each chunk might cover a different topic. Conversational data is
22
+ * different: a session is a topically-coherent thread. Adjacent chunks in
23
+ * the same session share context, so per-chunk contextualization would
24
+ * fire ~10× as many LLM calls at the *same* summarization model for the
25
+ * same downstream embedding benefit — this is a same-model
26
+ * granularity comparison, not a cross-reader pricing claim.
27
+ *
28
+ * The closest industry analog is Mastra Observational Memory's Observer
29
+ * phase (rewrites full messages into dense observations). Ours is a
30
+ * lighter variant — we *prepend* a summary to preserve the original
31
+ * chunk text verbatim, rather than rewriting it.
32
+ *
33
+ * ## Caching
34
+ *
35
+ * Summaries are cached to disk under `<cacheDir>/<sha256-hex>.txt`. The
36
+ * cache key hashes the session text, model id, and template version so
37
+ * any of those three changing invalidates the cache cleanly. Mirrors
38
+ * the {@link CachedEmbedder} pattern for consistency.
39
+ *
40
+ * ## Cost
41
+ *
42
+ * Single LLM call per unique session. For LongMemEval-S (~50 sessions
43
+ * per case × 500 cases) with gpt-5-mini / Haiku pricing:
44
+ * ~25,000 calls × 50–100 output tokens × 2,000 input tokens (session)
45
+ * ≈ $50–90 one-time across all cases. Cached thereafter.
46
+ *
47
+ * ## Expected lift
48
+ *
49
+ * Anthropic's published numbers: −49% retrieval failure with contextual
50
+ * embeddings alone, −67% when combined with reranking. We already have
51
+ * Cohere rerank-v3.5 wired, so the upper bound applies. Our Phase A
52
+ * multi-session ceiling of 50% is the main target; expected lift
53
+ * +8–15pp on multi-session categories across LongMemEval and LOCOMO.
54
+ *
55
+ * @module agentos-bench/cognitive/SessionSummarizer
56
+ */
57
+ /**
58
+ * Callable that invokes a chat LLM given a system + user prompt and
59
+ * returns the generated text. The bench constructs one from the
60
+ * existing {@link IReader} so summarization reuses the same pricing +
61
+ * timeout plumbing as the benchmark's reader.
62
+ */
63
+ export type SessionSummarizerInvoker = (system: string, user: string) => Promise<{
64
+ text: string;
65
+ tokensIn: number;
66
+ tokensOut: number;
67
+ model: string;
68
+ }>;
69
+ /**
70
+ * Options for constructing a {@link SessionSummarizer}.
71
+ */
72
+ export interface SessionSummarizerOptions {
73
+ /** LLM invoker — produces the summary text. */
74
+ invoker: SessionSummarizerInvoker;
75
+ /**
76
+ * Optional directory for persistent disk cache. When set, summaries
77
+ * survive across process restarts and re-runs. Mirrors the
78
+ * {@link CachedEmbedder} cache layout.
79
+ */
80
+ cacheDir?: string;
81
+ /**
82
+ * Model identifier baked into the cache key so switching models
83
+ * invalidates the cache automatically. Should match the invoker's
84
+ * underlying model.
85
+ */
86
+ modelId: string;
87
+ /**
88
+ * Maximum tokens to ask the LLM to emit. Default 140 (generous headroom
89
+ * over the 50–100 target; truncate post-hoc if needed).
90
+ */
91
+ maxTokens?: number;
92
+ /**
93
+ * Template version. Bump whenever the summarization prompt changes so
94
+ * disk caches from prior versions are invalidated.
95
+ * Current: `'v1-2026-04-19'`.
96
+ */
97
+ templateVersion?: string;
98
+ /** Optional cost-tracker hook. Called after every uncached call. */
99
+ onCallCost?: (tokensIn: number, tokensOut: number, model: string) => void;
100
+ }
101
+ /**
102
+ * Summary cache stats for diagnostics / budget tracking.
103
+ */
104
+ export interface SummarizerStats {
105
+ hits: number;
106
+ misses: number;
107
+ writes: number;
108
+ /** Total tokens consumed on uncached LLM calls. */
109
+ tokensIn: number;
110
+ tokensOut: number;
111
+ }
112
+ /**
113
+ * LLM-backed session summarizer with a persistent on-disk cache.
114
+ *
115
+ * @example
116
+ * ```ts
117
+ * const summarizer = new SessionSummarizer({
118
+ * invoker: async (system, user) => {
119
+ * const resp = await reader.invoke({ system, user, maxTokens: 140, temperature: 0 });
120
+ * return { text: resp.text, tokensIn: resp.tokensIn, tokensOut: resp.tokensOut, model: resp.model };
121
+ * },
122
+ * cacheDir: '/path/to/data/.session-summary-cache',
123
+ * modelId: 'gpt-5-mini',
124
+ * });
125
+ *
126
+ * const summary = await summarizer.summarize('conv-26-session-3', sessionText);
127
+ * // => "User discussed adopting a new rescue dog from a Portland shelter..."
128
+ * ```
129
+ */
130
+ export declare class SessionSummarizer {
131
+ private readonly opts;
132
+ /** Running stats for diagnostics. */
133
+ readonly stats: SummarizerStats;
134
+ private readonly systemPrompt;
135
+ private readonly templateVersion;
136
+ private readonly maxTokens;
137
+ constructor(opts: SessionSummarizerOptions);
138
+ /**
139
+ * Summarize a single session. Returns cached result if available,
140
+ * otherwise calls the LLM and writes to cache.
141
+ *
142
+ * @param sessionKey — a stable identifier for the session (e.g. `${caseId}:${sessionId}`).
143
+ * Used only for logging; the cache key is content-addressed.
144
+ * @param sessionText — the raw text of the session (all turns concatenated).
145
+ */
146
+ summarize(_sessionKey: string, sessionText: string): Promise<string>;
147
+ /**
148
+ * Build the SHA-256 cache key from session content + model + template.
149
+ * Exposed for tests; callers should use {@link summarize}.
150
+ */
151
+ computeCacheKey(sessionText: string): string;
152
+ /** Expose the resolved template version — useful for cache-key fingerprints in other layers. */
153
+ getTemplateVersion(): string;
154
+ }
155
+ //# sourceMappingURL=SessionSummarizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SessionSummarizer.d.ts","sourceRoot":"","sources":["../../../src/memory/ingest/SessionSummarizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AAMH;;;;;GAKG;AACH,MAAM,MAAM,wBAAwB,GAAG,CACrC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,KACT,OAAO,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,+CAA+C;IAC/C,OAAO,EAAE,wBAAwB,CAAC;IAClC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oEAAoE;IACpE,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3E;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAgBD;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,iBAAiB;IAchB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAbjC,qCAAqC;IACrC,QAAQ,CAAC,KAAK,EAAE,eAAe,CAM7B;IAEF,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEN,IAAI,EAAE,wBAAwB;IAM3D;;;;;;;OAOG;IACG,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAqD1E;;;OAGG;IACH,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAU5C,gGAAgG;IAChG,kBAAkB,IAAI,MAAM;CAG7B"}
@@ -0,0 +1,178 @@
1
+ /**
2
+ * @file SessionSummarizer.ts
3
+ * @description Session-level contextual retrieval (Anthropic Sep 2024
4
+ * variant, adapted to conversational memory).
5
+ *
6
+ * ## What this does
7
+ *
8
+ * For each session in a benchmark case (e.g. a `conv-26` chat thread in
9
+ * LOCOMO or a `haystack_sessions[i]` entry in LongMemEval), an LLM
10
+ * generates a dense 50–100 token summary that captures the topic,
11
+ * key user-stated facts (names, numbers, dates, preferences), and key
12
+ * assistant-stated facts. That summary is then prepended to *every*
13
+ * chunk produced from that session before embedding — giving the
14
+ * embedding vector global session context it would otherwise lack.
15
+ *
16
+ * ## Why session-granularity (not per-chunk)
17
+ *
18
+ * Anthropic's canonical
19
+ * {@link https://www.anthropic.com/news/contextual-retrieval Contextual Retrieval}
20
+ * prepends context *per chunk*. That's right for heterogeneous documents
21
+ * where each chunk might cover a different topic. Conversational data is
22
+ * different: a session is a topically-coherent thread. Adjacent chunks in
23
+ * the same session share context, so per-chunk contextualization would
24
+ * fire ~10× as many LLM calls at the *same* summarization model for the
25
+ * same downstream embedding benefit — this is a same-model
26
+ * granularity comparison, not a cross-reader pricing claim.
27
+ *
28
+ * The closest industry analog is Mastra Observational Memory's Observer
29
+ * phase (rewrites full messages into dense observations). Ours is a
30
+ * lighter variant — we *prepend* a summary to preserve the original
31
+ * chunk text verbatim, rather than rewriting it.
32
+ *
33
+ * ## Caching
34
+ *
35
+ * Summaries are cached to disk under `<cacheDir>/<sha256-hex>.txt`. The
36
+ * cache key hashes the session text, model id, and template version so
37
+ * any of those three changing invalidates the cache cleanly. Mirrors
38
+ * the {@link CachedEmbedder} pattern for consistency.
39
+ *
40
+ * ## Cost
41
+ *
42
+ * Single LLM call per unique session. For LongMemEval-S (~50 sessions
43
+ * per case × 500 cases) with gpt-5-mini / Haiku pricing:
44
+ * ~25,000 calls × 50–100 output tokens × 2,000 input tokens (session)
45
+ * ≈ $50–90 one-time across all cases. Cached thereafter.
46
+ *
47
+ * ## Expected lift
48
+ *
49
+ * Anthropic's published numbers: −49% retrieval failure with contextual
50
+ * embeddings alone, −67% when combined with reranking. We already have
51
+ * Cohere rerank-v3.5 wired, so the upper bound applies. Our Phase A
52
+ * multi-session ceiling of 50% is the main target; expected lift
53
+ * +8–15pp on multi-session categories across LongMemEval and LOCOMO.
54
+ *
55
+ * @module agentos-bench/cognitive/SessionSummarizer
56
+ */
57
+ import { promises as fs } from 'node:fs';
58
+ import { createHash } from 'node:crypto';
59
+ import path from 'node:path';
60
+ /** Default summarization prompt — see file docstring for rationale. */
61
+ const DEFAULT_SYSTEM_PROMPT = [
62
+ 'You produce a concise search-retrieval summary of a conversation session.',
63
+ 'Your output will be prepended to individual turn-level chunks before vector embedding, so the embedding captures the session-wide context each chunk alone would miss.',
64
+ 'Target length: 50–100 tokens. No preamble, no sign-off — emit only the summary.',
65
+ 'Structure the summary as dense prose:',
66
+ ' 1. The topic or theme of the session (one short clause).',
67
+ ' 2. The specific facts the user stated — names, numbers, dates, preferences, decisions, named items (e.g. "Wells Fargo mortgage", "turbinado sugar", "mid-century dresser").',
68
+ ' 3. The specific facts the assistant stated, suggested, or provided (numbers, recommendations, named entities).',
69
+ 'Be concrete. Use exact nouns and numbers from the conversation. Do not generalize. Do not editorialize.',
70
+ ].join(' ');
71
+ const DEFAULT_TEMPLATE_VERSION = 'v1-2026-04-19';
72
+ /**
73
+ * LLM-backed session summarizer with a persistent on-disk cache.
74
+ *
75
+ * @example
76
+ * ```ts
77
+ * const summarizer = new SessionSummarizer({
78
+ * invoker: async (system, user) => {
79
+ * const resp = await reader.invoke({ system, user, maxTokens: 140, temperature: 0 });
80
+ * return { text: resp.text, tokensIn: resp.tokensIn, tokensOut: resp.tokensOut, model: resp.model };
81
+ * },
82
+ * cacheDir: '/path/to/data/.session-summary-cache',
83
+ * modelId: 'gpt-5-mini',
84
+ * });
85
+ *
86
+ * const summary = await summarizer.summarize('conv-26-session-3', sessionText);
87
+ * // => "User discussed adopting a new rescue dog from a Portland shelter..."
88
+ * ```
89
+ */
90
+ export class SessionSummarizer {
91
+ constructor(opts) {
92
+ this.opts = opts;
93
+ /** Running stats for diagnostics. */
94
+ this.stats = {
95
+ hits: 0,
96
+ misses: 0,
97
+ writes: 0,
98
+ tokensIn: 0,
99
+ tokensOut: 0,
100
+ };
101
+ this.systemPrompt = DEFAULT_SYSTEM_PROMPT;
102
+ this.templateVersion = opts.templateVersion ?? DEFAULT_TEMPLATE_VERSION;
103
+ this.maxTokens = opts.maxTokens ?? 140;
104
+ }
105
+ /**
106
+ * Summarize a single session. Returns cached result if available,
107
+ * otherwise calls the LLM and writes to cache.
108
+ *
109
+ * @param sessionKey — a stable identifier for the session (e.g. `${caseId}:${sessionId}`).
110
+ * Used only for logging; the cache key is content-addressed.
111
+ * @param sessionText — the raw text of the session (all turns concatenated).
112
+ */
113
+ async summarize(_sessionKey, sessionText) {
114
+ const trimmed = sessionText.trim();
115
+ if (!trimmed)
116
+ return '';
117
+ const cacheKey = this.computeCacheKey(trimmed);
118
+ // Try disk cache
119
+ if (this.opts.cacheDir) {
120
+ const cachePath = path.join(this.opts.cacheDir, `${cacheKey}.txt`);
121
+ try {
122
+ const cached = await fs.readFile(cachePath, 'utf8');
123
+ this.stats.hits += 1;
124
+ return cached;
125
+ }
126
+ catch {
127
+ // File doesn't exist or can't be read — fall through to LLM call.
128
+ }
129
+ }
130
+ this.stats.misses += 1;
131
+ const response = await this.opts.invoker(this.systemPrompt, trimmed);
132
+ const summary = response.text.trim();
133
+ this.stats.tokensIn += response.tokensIn;
134
+ this.stats.tokensOut += response.tokensOut;
135
+ if (this.opts.onCallCost) {
136
+ this.opts.onCallCost(response.tokensIn, response.tokensOut, response.model);
137
+ }
138
+ // Persist to disk cache (best-effort; exclusive create so concurrent
139
+ // writers don't tear). Non-fatal on write failure — caller still
140
+ // gets the summary for this call.
141
+ if (this.opts.cacheDir) {
142
+ try {
143
+ await fs.mkdir(this.opts.cacheDir, { recursive: true });
144
+ const cachePath = path.join(this.opts.cacheDir, `${cacheKey}.txt`);
145
+ await fs.writeFile(cachePath, summary, { encoding: 'utf8', flag: 'wx' });
146
+ this.stats.writes += 1;
147
+ }
148
+ catch (err) {
149
+ const code = err?.code;
150
+ // EEXIST means another writer got there first — their content is
151
+ // valid. Any other error is logged but non-fatal.
152
+ if (code !== 'EEXIST') {
153
+ // eslint-disable-next-line no-console
154
+ console.warn(`[SessionSummarizer] Failed to write cache for key ${cacheKey.slice(0, 8)}...: ${String(err)}`);
155
+ }
156
+ }
157
+ }
158
+ return summary;
159
+ }
160
+ /**
161
+ * Build the SHA-256 cache key from session content + model + template.
162
+ * Exposed for tests; callers should use {@link summarize}.
163
+ */
164
+ computeCacheKey(sessionText) {
165
+ return createHash('sha256')
166
+ .update(this.opts.modelId)
167
+ .update('\n')
168
+ .update(this.templateVersion)
169
+ .update('\n')
170
+ .update(sessionText)
171
+ .digest('hex');
172
+ }
173
+ /** Expose the resolved template version — useful for cache-key fingerprints in other layers. */
174
+ getTemplateVersion() {
175
+ return this.templateVersion;
176
+ }
177
+ }
178
+ //# sourceMappingURL=SessionSummarizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SessionSummarizer.js","sourceRoot":"","sources":["../../../src/memory/ingest/SessionSummarizer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * @file FactSupersession.ts
3
+ * @description Post-retrieval filter that uses an LLM to identify and
4
+ * drop memory traces whose factual claims have been superseded by
5
+ * later traces about the same subject.
6
+ *
7
+ * ## What this does
8
+ *
9
+ * Given a query and a list of retrieved `ScoredMemoryTrace`s, fires
10
+ * one LLM call with a strict JSON output contract. The LLM returns
11
+ * `{ dropIds: string[] }` — trace IDs to remove. The class filters
12
+ * the input list and returns the survivors in original order.
13
+ *
14
+ * ## Failure modes (never throws)
15
+ *
16
+ * - Parse error → return original traces + `parse-failed` diagnostic.
17
+ * - Schema mismatch → return original + `schema-mismatch` diagnostic.
18
+ * - Timeout → return original + `timeout` diagnostic.
19
+ * - LLM throws → return original + `llm-error` diagnostic.
20
+ * - All IDs dropped (adversarial output) → safety clamp, return
21
+ * original + `drop-all-rejected` diagnostic.
22
+ *
23
+ * ## Why this exists
24
+ *
25
+ * The baseline + Hybrid retrieval surfaces BOTH statements when a
26
+ * user has updated a fact ("I live in NYC" + "I moved to Berlin").
27
+ * The reader sometimes picks the older or hedges. A supersession
28
+ * pass gives the reader only the canonical current state.
29
+ *
30
+ * @module agentos/memory/retrieval/fact-supersession/FactSupersession
31
+ */
32
+ import type { ScoredMemoryTrace } from '../../core/types.js';
33
+ export type LlmInvoker = (systemPrompt: string, userPrompt: string) => Promise<string>;
34
+ /** Options for constructing a {@link FactSupersession}. */
35
+ export interface FactSupersessionOptions {
36
+ /** LLM invoker used for the supersession pass. */
37
+ llmInvoker: LlmInvoker;
38
+ /** Max traces to send to the LLM. @default 10 */
39
+ maxTraces?: number;
40
+ /** Max wall-clock ms before timeout fallback. @default 8000 */
41
+ timeoutMs?: number;
42
+ }
43
+ /** Per-call input to {@link FactSupersession.resolve}. */
44
+ export interface FactSupersessionInput {
45
+ traces: ScoredMemoryTrace[];
46
+ query: string;
47
+ }
48
+ /** Per-call output from {@link FactSupersession.resolve}. */
49
+ export interface FactSupersessionResult {
50
+ /** Traces surviving the filter, in original order. */
51
+ traces: ScoredMemoryTrace[];
52
+ /** IDs dropped by the LLM (subset of input trace IDs). */
53
+ droppedIds: string[];
54
+ diagnostics: {
55
+ llmLatencyMs: number;
56
+ parseOk: boolean;
57
+ notes?: string[];
58
+ };
59
+ }
60
+ /**
61
+ * Post-retrieval fact supersession filter.
62
+ *
63
+ * @example
64
+ * ```ts
65
+ * const fs = new FactSupersession({
66
+ * llmInvoker: async (system, user) => (await reader.invoke({ system, user, maxTokens: 200, temperature: 0 })).text,
67
+ * });
68
+ * const result = await fs.resolve({ traces: retrieval.retrieved, query: caseQuery });
69
+ * // Feed `result.traces` to the reader instead of `retrieval.retrieved`.
70
+ * ```
71
+ */
72
+ export declare class FactSupersession {
73
+ private readonly llmInvoker;
74
+ private readonly maxTraces;
75
+ private readonly timeoutMs;
76
+ constructor(opts: FactSupersessionOptions);
77
+ resolve(input: FactSupersessionInput): Promise<FactSupersessionResult>;
78
+ private buildUserPrompt;
79
+ private invokeWithTimeout;
80
+ private parseDropIds;
81
+ }
82
+ //# sourceMappingURL=FactSupersession.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FactSupersession.d.ts","sourceRoot":"","sources":["../../../../src/memory/retrieval/fact-supersession/FactSupersession.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,MAAM,MAAM,UAAU,GAAG,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAEvF,2DAA2D;AAC3D,MAAM,WAAW,uBAAuB;IACtC,kDAAkD;IAClD,UAAU,EAAE,UAAU,CAAC;IACvB,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,0DAA0D;AAC1D,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,6DAA6D;AAC7D,MAAM,WAAW,sBAAsB;IACrC,sDAAsD;IACtD,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,0DAA0D;IAC1D,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,EAAE;QACX,YAAY,EAAE,MAAM,CAAC;QACrB,OAAO,EAAE,OAAO,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC;CACH;AAkBD;;;;;;;;;;;GAWG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,IAAI,EAAE,uBAAuB;IAMnC,OAAO,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAkE5E,OAAO,CAAC,eAAe;YAST,iBAAiB;IAS/B,OAAO,CAAC,YAAY;CAmBrB"}
@@ -0,0 +1,159 @@
1
+ /**
2
+ * @file FactSupersession.ts
3
+ * @description Post-retrieval filter that uses an LLM to identify and
4
+ * drop memory traces whose factual claims have been superseded by
5
+ * later traces about the same subject.
6
+ *
7
+ * ## What this does
8
+ *
9
+ * Given a query and a list of retrieved `ScoredMemoryTrace`s, fires
10
+ * one LLM call with a strict JSON output contract. The LLM returns
11
+ * `{ dropIds: string[] }` — trace IDs to remove. The class filters
12
+ * the input list and returns the survivors in original order.
13
+ *
14
+ * ## Failure modes (never throws)
15
+ *
16
+ * - Parse error → return original traces + `parse-failed` diagnostic.
17
+ * - Schema mismatch → return original + `schema-mismatch` diagnostic.
18
+ * - Timeout → return original + `timeout` diagnostic.
19
+ * - LLM throws → return original + `llm-error` diagnostic.
20
+ * - All IDs dropped (adversarial output) → safety clamp, return
21
+ * original + `drop-all-rejected` diagnostic.
22
+ *
23
+ * ## Why this exists
24
+ *
25
+ * The baseline + Hybrid retrieval surfaces BOTH statements when a
26
+ * user has updated a fact ("I live in NYC" + "I moved to Berlin").
27
+ * The reader sometimes picks the older or hedges. A supersession
28
+ * pass gives the reader only the canonical current state.
29
+ *
30
+ * @module agentos/memory/retrieval/fact-supersession/FactSupersession
31
+ */
32
+ /**
33
+ * Canonical supersession system prompt. Strict rules: supersession
34
+ * requires contradiction between two claims about the same (subject,
35
+ * predicate); complementary facts never supersede.
36
+ */
37
+ const SUPERSESSION_SYSTEM_PROMPT = `You are a fact-supersession analyzer for memory retrieval. Given a user question and N retrieved memory traces, identify traces containing FACTS that have been SUPERSEDED by later traces about the same subject.
38
+
39
+ Rules:
40
+ 1. Supersession requires contradiction — two traces making DIFFERENT claims about the same (subject, predicate).
41
+ 2. Use the timestamp field to order claims chronologically. The LATER trace wins.
42
+ 3. Traces about DIFFERENT subjects are never mutually superseding.
43
+ 4. Complementary facts (different predicates about the same subject) never supersede each other.
44
+ 5. Return a JSON object: {"dropIds": ["id1", "id2"]}. Drop ONLY the outdated ones. Return {"dropIds": []} if no supersession detected.
45
+
46
+ Do not drop traces that are not clearly superseded.`;
47
+ /**
48
+ * Post-retrieval fact supersession filter.
49
+ *
50
+ * @example
51
+ * ```ts
52
+ * const fs = new FactSupersession({
53
+ * llmInvoker: async (system, user) => (await reader.invoke({ system, user, maxTokens: 200, temperature: 0 })).text,
54
+ * });
55
+ * const result = await fs.resolve({ traces: retrieval.retrieved, query: caseQuery });
56
+ * // Feed `result.traces` to the reader instead of `retrieval.retrieved`.
57
+ * ```
58
+ */
59
+ export class FactSupersession {
60
+ constructor(opts) {
61
+ this.llmInvoker = opts.llmInvoker;
62
+ this.maxTraces = opts.maxTraces ?? 10;
63
+ this.timeoutMs = opts.timeoutMs ?? 8000;
64
+ }
65
+ async resolve(input) {
66
+ const start = Date.now();
67
+ const notes = [];
68
+ if (input.traces.length === 0) {
69
+ return {
70
+ traces: [],
71
+ droppedIds: [],
72
+ diagnostics: { llmLatencyMs: 0, parseOk: true },
73
+ };
74
+ }
75
+ const window = input.traces.slice(0, this.maxTraces);
76
+ const userPrompt = this.buildUserPrompt(input.query, window);
77
+ let llmText;
78
+ try {
79
+ llmText = await this.invokeWithTimeout(userPrompt);
80
+ }
81
+ catch (err) {
82
+ const reason = err?.message?.includes('timeout')
83
+ ? 'fact-supersession:timeout'
84
+ : 'fact-supersession:llm-error';
85
+ notes.push(reason);
86
+ return {
87
+ traces: input.traces,
88
+ droppedIds: [],
89
+ diagnostics: { llmLatencyMs: Date.now() - start, parseOk: false, notes },
90
+ };
91
+ }
92
+ const parsed = this.parseDropIds(llmText);
93
+ if (!parsed.ok) {
94
+ notes.push(parsed.reason);
95
+ return {
96
+ traces: input.traces,
97
+ droppedIds: [],
98
+ diagnostics: { llmLatencyMs: Date.now() - start, parseOk: false, notes },
99
+ };
100
+ }
101
+ if (parsed.dropIds.length >= input.traces.length) {
102
+ notes.push('fact-supersession:drop-all-rejected');
103
+ return {
104
+ traces: input.traces,
105
+ droppedIds: [],
106
+ diagnostics: { llmLatencyMs: Date.now() - start, parseOk: true, notes },
107
+ };
108
+ }
109
+ const dropSet = new Set(parsed.dropIds);
110
+ const filtered = input.traces.filter((t) => !dropSet.has(t.id));
111
+ const realDropped = input.traces
112
+ .filter((t) => dropSet.has(t.id))
113
+ .map((t) => t.id);
114
+ return {
115
+ traces: filtered,
116
+ droppedIds: realDropped,
117
+ diagnostics: {
118
+ llmLatencyMs: Date.now() - start,
119
+ parseOk: true,
120
+ notes: notes.length > 0 ? notes : undefined,
121
+ },
122
+ };
123
+ }
124
+ buildUserPrompt(query, traces) {
125
+ const lines = traces.map((t) => {
126
+ const ts = new Date(t.createdAt).toISOString();
127
+ const content = t.content.length > 500 ? `${t.content.slice(0, 500)}...` : t.content;
128
+ return `[id=${t.id} | ts=${ts} | "${content}"]`;
129
+ });
130
+ return `Question: ${query}\n\nTraces (id | timestamp | content):\n${lines.join('\n')}\n\nReturn JSON only.`;
131
+ }
132
+ async invokeWithTimeout(userPrompt) {
133
+ return new Promise((resolve, reject) => {
134
+ const timer = setTimeout(() => reject(new Error('fact-supersession timeout')), this.timeoutMs);
135
+ this.llmInvoker(SUPERSESSION_SYSTEM_PROMPT, userPrompt)
136
+ .then((text) => { clearTimeout(timer); resolve(text); })
137
+ .catch((err) => { clearTimeout(timer); reject(err); });
138
+ });
139
+ }
140
+ parseDropIds(text) {
141
+ const cleaned = text.trim().replace(/^```(?:json)?/i, '').replace(/```$/i, '').trim();
142
+ let obj;
143
+ try {
144
+ obj = JSON.parse(cleaned);
145
+ }
146
+ catch {
147
+ return { ok: false, reason: 'fact-supersession:parse-failed' };
148
+ }
149
+ if (!obj || typeof obj !== 'object' || !Array.isArray(obj.dropIds)) {
150
+ return { ok: false, reason: 'fact-supersession:schema-mismatch' };
151
+ }
152
+ const arr = obj.dropIds;
153
+ if (!arr.every((v) => typeof v === 'string')) {
154
+ return { ok: false, reason: 'fact-supersession:schema-mismatch' };
155
+ }
156
+ return { ok: true, dropIds: arr };
157
+ }
158
+ }
159
+ //# sourceMappingURL=FactSupersession.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FactSupersession.js","sourceRoot":"","sources":["../../../../src/memory/retrieval/fact-supersession/FactSupersession.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @module agentos/memory/retrieval/fact-supersession
3
+ * @description Post-retrieval LLM-based supersession filter — drops
4
+ * memory traces whose factual claims have been superseded by later
5
+ * traces about the same subject. Used to push knowledge-update
6
+ * accuracy past the ceiling hit by pure retrieval + rerank.
7
+ */
8
+ export { FactSupersession } from './FactSupersession.js';
9
+ export type { FactSupersessionOptions, FactSupersessionInput, FactSupersessionResult, } from './FactSupersession.js';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/memory/retrieval/fact-supersession/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,YAAY,EACV,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @module agentos/memory/retrieval/fact-supersession
3
+ * @description Post-retrieval LLM-based supersession filter — drops
4
+ * memory traces whose factual claims have been superseded by later
5
+ * traces about the same subject. Used to push knowledge-update
6
+ * accuracy past the ceiling hit by pure retrieval + rerank.
7
+ */
8
+ export { FactSupersession } from './FactSupersession.js';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/memory/retrieval/fact-supersession/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC"}