@x-otto/memory 0.0.1-alpha.3 → 0.0.1-alpha.4

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @x-otto/memory
2
2
 
3
- Agent working memory pipeline: LLM-driven compaction, LLM-free pruning, archive persistence, multi-source AGENTS.md memory, writable cross-session auto-memory, operational learning, and workspace file-state snapshots.
3
+ Agent working memory pipeline: LLM-driven compaction, LLM-free pruning, multi-source AGENTS.md memory, writable cross-session auto-memory, operational learning, and workspace file-state snapshots.
4
4
 
5
5
  ## Install
6
6
 
@@ -15,9 +15,8 @@ import { MemoryManager, OperationalLearningStore, FileStateManager } from '@x-ot
15
15
 
16
16
  // Pipeline: prune → compaction → archive
17
17
  const memory = new MemoryManager({
18
- workspaceDir: process.cwd(),
19
- model: 'claude-sonnet-4-5',
20
- provider: myProvider,
18
+ summarize: async (prompt, opts) => myLLM.complete(prompt, opts),
19
+ model: { contextWindow: 200_000, maxOutput: 8_192 },
21
20
  })
22
21
  const result = await memory.process(messages, sessionId)
23
22
  // Returns { messages, summary, archivePath, pruned, compacted }
@@ -33,7 +32,7 @@ await lessons.save({ tags: ['testing'], trigger: 'flaky test', insight: 'reset s
33
32
  // File state snapshot
34
33
  const fsm = new FileStateManager()
35
34
  const snapshot = await fsm.capture({ workspaceDir: '.' })
36
- // snapshot → { tree, recentFiles: { created, modified, deleted } }
35
+ // snapshot → { directoryTree, modifiedFiles: { created, modified, deleted }, findings }
37
36
  ```
38
37
 
39
38
  ## Pipeline: prune → compaction → archive
@@ -43,21 +42,23 @@ const snapshot = await fsm.capture({ workspaceDir: '.' })
43
42
  - Triggered when estimated tokens exceed `prune.trigger` threshold
44
43
  - Protection window: last N messages (by token count) are always kept
45
44
  - `tool_result` content outside protection → `[output pruned — N tokens]`
46
- - `tool_call` arguments for write tools (write/edit/apply_patch) truncated beyond `truncateMaxLength`
45
+ - `tool_call` arguments for write tools (write/edit) truncated beyond `truncateMaxLength`
47
46
  - Minimum gain gate: rolls back if net savings < `minimum` tokens
48
47
 
49
- ### 2. Compaction — LLM-driven summary (`compaction.ts`)
48
+ ### 2. Compaction — LLM-driven summary (`compaction-backend.ts`)
50
49
 
51
50
  - `findCutPoint`: keep recent tokens, align to user/assistant boundary, detect split-turn
52
51
  - Separates messages-to-summarize / preserved / turn-prefix region
53
52
  - Extracts file operations (read/modified paths) from tool_results
54
- - Calls injected `summarize(system, messages, opts)` with structured prompt (Goal / Constraints / Progress / Key Decisions / Next Steps / File Operations / Critical Context)
53
+ - Calls injected `summarize(prompt, opts)` with structured prompt (Goal / Constraints / Progress / Key Decisions / Next Steps / File Operations / Critical Context)
55
54
  - Iterative: previous summary + new messages → `UPDATE_SUMMARIZATION_PROMPT`
56
55
  - Split turn: generates additional turn-prefix summary via `TURN_PREFIX_SUMMARIZATION_PROMPT`
57
56
 
58
- ### 3. Archive — persist compaction output (`archive.ts`)
57
+ ### 3. Archive — session-derived view (`archive-source.ts`)
59
58
 
60
- - Formats compressed messages + summary as Markdown (single messages >2000 chars truncated)
59
+ - Archive is a session-derived view (compaction boundaries reconstructed from session entries on demand), not independent persistence
60
+ - `InMemoryArchiveStorage` retained as V-form (headless, no session tree) fallback
61
+ - `ArchiveSource` interface unifies both implementations; `MemoryManager` has no form-branching
61
62
  - Backend: `InMemoryArchiveStorage` (default; the former `PersistenceBackedArchiveStorage` / `createArchiveStorage` file/HTTP stack was deleted — archive is now a session-derived view, not independent persistence)
62
63
 
63
64
  ## Persistent Memory (`persistent-memory.ts`)
@@ -124,10 +125,15 @@ Read-only workspace snapshot for agent context:
124
125
  ```
125
126
  src/
126
127
  types.ts # Config types, MemoryStore, ArchiveStorage, ManagerConfig
127
- memory-manager.ts # Pipeline coordinator + persistent memory facade
128
+ memory-manager.ts # Pipeline coordinator + persistent memory facade + trigger orchestration
128
129
  prune.ts # No-LLM pruning (window, tool_result truncation, gain gate)
129
- compaction.ts # Cut point, LLM summary, split-turn, file ops extraction
130
+ compaction.ts # Pure functions: findCutPoint / isSummaryMessage / extractFileOps / formatFileOps
131
+ compaction-backend.ts # CompactionBackend: compact/prepare/isEligible (strategy-execution separation)
132
+ trigger-policies.ts # TriggerPolicy interface + TokenPressure/RealInput/Residency/Prune policies
133
+ coverage-governor.ts # Per-session coverage boost state (instance-owned)
134
+ archive-source.ts # ArchiveSource interface + SessionEntries/InMemory implementations
130
135
  compaction-truncation.ts # Summary-input formatting & truncation primitives
136
+ memory-injection.ts # <agent_memory> injection: budget accounting + index folding
131
137
  archive.ts # InMemoryArchiveStorage + formatArchive
132
138
  persistent-memory.ts # AGENTS.md multi-source + FileSystemMemoryStore / InMemoryMemoryStore
133
139
  http-memory-store.ts # Remote HTTP memory store
@@ -136,13 +142,14 @@ src/
136
142
  agents-discovery.ts # AGENTS.md path discovery
137
143
  memory-extractor.ts # Derive persistable memory entries from session
138
144
  evolution-signal-store.ts # Evolution-observation unified signal exit (append-only)
145
+ signal-log.ts # SignalLog persistence (AppendLog JSONL domain wrapper)
139
146
  overlay-memory-store.ts # Shadow-mode MemoryStore overlay (reads-through, writes in-memory)
140
147
  token-estimator.ts # CJK-aware token estimation + usage-hybrid context
141
148
  defaults.ts # computeMemoryDefaults / resolveContextSize
142
149
  operational-learning.ts # Lessons store (CRUD + weighted search + atomic persistence)
143
150
  file-state-snapshot.ts # Workspace read-only snapshot
144
- prompts.ts # Summary prompts + memory/archive injection builders
145
- constants.ts # Thresholds, paths
151
+ prompts.ts # Summary prompts + archive reference builders
152
+ constants.ts # Thresholds, paths, conflict ring size
146
153
  index.ts # Barrel exports
147
154
  ```
148
155
 
package/dist/index.d.ts CHANGED
@@ -1,21 +1,41 @@
1
1
  import { Message } from "@x-otto/interchange";
2
2
 
3
3
  //#region src/compaction-truncation.d.ts
4
+ declare function formatMessageForSummary(msg: Message): string;
4
5
  /**
5
6
  * RFC-381 M3:压缩阶段 spill 端口(可选)。超大可再生 tool_result 在截断前先全文落盘,
6
7
  * 返回路径字符串;返回 undefined = 无端口/失败(fail-open 退回内存截断)。
7
8
  * 实现侧复用执行时 spill(tool-result-store),与 prune.ts 的 SPILL_MARKER 占位符同格式。
8
9
  */
9
10
  type CompactionSpillSink = (toolCallId: string, text: string) => Promise<string | undefined>;
10
- /** RFC-381 M3:P3 层触发 spill 的文本长度下界(低于它不值得落盘 IO)。 */
11
- declare const SPILL_MIN_CHARS = 4096;
11
+ //#endregion
12
+ //#region src/coverage-governor.d.ts
12
13
  /**
13
- * RFC-381 M3:对批次中 P3(可再生 tool_result)的超长文本做 spill——全文落盘 + 占位符
14
- * (read 工具可恢复)。只替换文本、不改消息结构;spill 失败/无端口 → 原样返回(fail-open)。
15
- * 调用方在 `truncateBatchByPriority` 之前调用(async 上下文),使截断从「有损丢弃」升级
16
- * 为「无损移出上下文」。
14
+ * coverage-governor.ts —— RFC-324 D3 M3:摘要覆盖率闭环状态(per-session)。
15
+ *
16
+ * `compaction.ts` 模块级 Map 迁出(RFC-394 M1):coverage 递推状态归属实例,
17
+ * 消除模块级可变全局状态(多实例交叉污染隐患 + 自由函数隐藏状态依赖 + 测试需
18
+ * 手动清理全局 Map)。M2 将随 CompactionBackend 构造注入。
19
+ *
20
+ * 语义(RFC-324 D3 M3):上次压缩 coverage < warn/error 时,下次压缩调大批次上限
21
+ * (每批更小源内容 → 提高覆盖率)。**仅递推一次**(consume 后清零),避免持续
22
+ * 放大导致批次数无界。
17
23
  */
18
- declare function spillBatchP3(batch: readonly Message[], spill: CompactionSpillSink | undefined): Promise<Message[]>;
24
+ declare class CoverageGovernor {
25
+ /** per-session 调大批次数(正常值 0 = 不调整)。 */
26
+ private readonly boostedBySession;
27
+ /** 指定 session 的调大批次数(正常值 0 = 不调整)。 */
28
+ get(sessionId: string): number;
29
+ /**
30
+ * 记录本次压缩 coverage,供下次压缩调批次上限(RFC-324 D3 M3)。
31
+ * coverage < error → 双重调大(x2,下限 16);error..warn → 调大(+2);>= warn → 不干预。
32
+ */
33
+ record(coverage: number, currentBatches: number, sessionId: string, errorThreshold: number, warnThreshold: number): void;
34
+ /** 读取并清零(仅递推一次)。delete 而非 set(0)——值归 0 时 key 永久残留(08-12 review W4)。 */
35
+ consume(sessionId: string): number;
36
+ /** 会话销毁时清理其条目(MemoryManager.forgetSession 调用)——覆盖「set 后未 consume 即 forget」的残留。 */
37
+ forget(sessionId: string): void;
38
+ }
19
39
  //#endregion
20
40
  //#region src/types.d.ts
21
41
  /**
@@ -53,6 +73,14 @@ interface PruneConfig {
53
73
  * 裁掉=真实信息损失。空列表 = 不裁任何 tool_result。
54
74
  */
55
75
  regenerableTools: string[];
76
+ /**
77
+ * RFC-437 D2:可再生名单的**惰性 getter**(可选)——每次 prune 实时读取,与静态
78
+ * `regenerableTools` 并集(getter 为工具声明真源,静态名单回退兜底 legacy 名)。
79
+ * 由装配侧注入 `() => toolRegistry.listRegenerableNames()`:内置 + 插件工具的
80
+ * `regenerableOutput: true` 声明即时生效(插件晚于 memory 构造装载也能被 prune
81
+ * 看见)。缺省未提供 = 现状行为逐字节不变。
82
+ */
83
+ regenerableToolNames?: () => string[];
56
84
  /** 二次保护:即便在 regenerableTools 内,列入此处的工具仍不裁(覆盖)。 */
57
85
  protectedTools: string[];
58
86
  truncateTools: string[];
@@ -126,7 +154,20 @@ interface CompactionConfig {
126
154
  * cacheRetention(消息仍在指令文本内)。缺省 false = 现状行为逐字节不变。
127
155
  */
128
156
  prefixReuse?: boolean;
157
+ /**
158
+ * RFC-436 G2:压缩请求前缀的 cacheRetention 档位(TTL 决定前缀能否命中 provider
159
+ * KV 缓存)。**不随正常轮次快照**——压缩是低频大 prefill 操作,正常轮次非交互模式
160
+ * 用 'short'(5min TTL),压缩距上轮请求通常远超 5 分钟,随快照必然过期(前缀复用
161
+ * 形同虚设)。缺省 'long'(1h TTL,DEFAULT_COMPACTION_CONFIG 定义)。宿主可按场景
162
+ * 覆盖(如 provider 对 long 收费异常时临时切 'short')。
163
+ */
164
+ cacheRetention?: CompactionCacheRetention;
129
165
  }
166
+ /**
167
+ * RFC-436 G2:压缩请求前缀 TTL 档位(与 provider 侧 CacheRetention 结构兼容,
168
+ * memory 是叶包不依赖 provider,本地定义联合类型)。
169
+ */
170
+ type CompactionCacheRetention = 'none' | 'short' | 'long';
130
171
  /**
131
172
  * RFC-387 D1:压缩请求的可缓存前缀(wire 形态快照的子集)。
132
173
  *
@@ -146,6 +187,12 @@ interface CompactionPrefix {
146
187
  * 仅单批路径传递;多批各批内容不同,不传。
147
188
  */
148
189
  messages?: readonly Message[];
190
+ /**
191
+ * RFC-436 G2:装配方用于压缩请求的 cacheRetention(缺省 'long')。memory 侧
192
+ * 从 CompactionConfig.cacheRetention 注入;不随快照(快照是正常轮次的 retention,
193
+ * 对低频压缩请求 TTL 过短)。
194
+ */
195
+ cacheRetention?: CompactionCacheRetention;
149
196
  systemPromptSegments?: readonly unknown[];
150
197
  tools?: readonly unknown[];
151
198
  modelId?: string;
@@ -348,6 +395,28 @@ interface MemoryManagerConfig {
348
395
  * 读取器,跟随活跃会话)。与 `maxContentBytes` 配对注入,缺一不启用字节因子。
349
396
  */
350
397
  getEstimatedBytes?: () => number | undefined;
398
+ /**
399
+ * RFC-390 D2:provider 真实 input token 读数(惰性,跟随最近一轮 usage)。
400
+ *
401
+ * 注入后 `needsCompaction` 在 `estimateContextTokens` 的混合口径之外,
402
+ * 额外参考真实 input tokens——当真实 input(total 口径)已达软触发线 90%
403
+ * 时提前触发压缩,不等启发式估算追上。解决空响应轮 `record()` 跳过导致
404
+ * `lastTokenUsage` 滞后的盲区(模型返回空响应时 usage 不更新,估算可能仍判
405
+ * "不需压缩",上下文继续膨胀到模型退化)。
406
+ *
407
+ * **坐标系(RFC-339 B1 教训)**:返回值是 **total 口径**(含 cache 前缀),
408
+ * 与 `estimateContextTokens` 的 `total` 同维度。软触发线 `triggerTokens`
409
+ * 是 bodyAfterPrefix 口径——使用时须换算:`realInput >= triggerTokens * 0.9`
410
+ * 是保守近似(realInput 含前缀,triggerTokens 不含——保守侧误差,不会误触发)。
411
+ * 未注入时回退纯估算(向后兼容)。
412
+ */
413
+ getRealInputTokens?: () => number | undefined;
414
+ /**
415
+ * RFC-394 M1:coverage 闭环状态(可选注入)。缺省 MemoryManager 自建实例。
416
+ * 注入面供测试读取 per-session boost 值(替代已删除的 `__getCoverageBoostedBatchesForTest`
417
+ * 测试后门)——测试创建 governor 传入并断言其状态;生产无需注入。
418
+ */
419
+ coverageGovernor?: CoverageGovernor;
351
420
  }
352
421
  interface MemoryDefaults {
353
422
  compaction: CompactionConfig;
@@ -358,13 +427,11 @@ interface MemoryDefaults {
358
427
  declare class MemoryManager {
359
428
  private readonly persistent;
360
429
  /**
361
- * archive = session 派生视图——loadSessionEntries 就位时走 session 条目的
362
- * compaction 边界间重建;未就位(无持久化/V 形态)时回退到 archiveStorage(InMemory)。
430
+ * RFC-394 M4:归档源——统一接口(替代原 archiveStorage + loadSessionEntries +
431
+ * messageFromEntry 三字段双路径 try/fallback)。构造期决定用哪个实现
432
+ * (SessionEntriesArchiveSource / InMemoryArchiveSource),不再运行时分支。
363
433
  */
364
- private readonly archiveStorage;
365
- private readonly loadSessionEntries?;
366
- private readonly messageFromEntry?;
367
- private readonly summarize;
434
+ private readonly archiveSource;
368
435
  private readonly estimateTokens;
369
436
  /** 构造时保留原始配置副本,供 reconfigure 用新窗口重算阈值。 */
370
437
  private readonly rawConfig;
@@ -378,9 +445,9 @@ declare class MemoryManager {
378
445
  /** RFC-321 M3:生效字节预算惰性读数(跟随 ResidencyGovernor 收紧档位)。 */
379
446
  private readonly getMaxContentBytes?;
380
447
  private readonly getEstimatedBytes?;
448
+ /** RFC-390 D2:provider 真实 input token 读数(惰性)。 */
449
+ private readonly getRealInputTokens?;
381
450
  private readonly previousSummaries;
382
- /** archive Path 单调发号——每会话内独立(archive:{sessionId}:{1..N})。 */
383
- private readonly archiveIdCounter;
384
451
  /**
385
452
  * 终局架构 review 建议优化项:并发 process() 门闩(per-session)。
386
453
  *
@@ -395,8 +462,21 @@ declare class MemoryManager {
395
462
  private readonly compactionInFlight;
396
463
  /** RFC-381 M1:跨进程 durable 压缩锁端口(可选;缺省退回进程内 Set)。 */
397
464
  private readonly compactionLock?;
398
- /** RFC-381 M3:压缩阶段 spill 端口(可选)。 */
399
- private readonly compactionSpill?;
465
+ /**
466
+ * RFC-381 M3:压缩阶段 spill 端口(可选;缺省退回既有内存截断)。
467
+ * **公开只读**——生产链透传回归门(coding m13-storage-wiring.test.ts)断言此字段:
468
+ * App 组合根注入的 spill 必须真到达 MemoryManager(2026-08-14 曾发生断链:
469
+ * buildDefaultMemory 解构/传参漏了 compactionSpill,spill 静默失效)。
470
+ */
471
+ readonly compactionSpill?: CompactionSpillSink;
472
+ /** RFC-394 M1:coverage 闭环状态——实例归属(config 可注入供测试读取,缺省自建)。 */
473
+ private readonly coverageGovernor;
474
+ /** RFC-394 M2:压缩执行后端(策略与编排分离——本类只编排,执行归 backend)。 */
475
+ private readonly compactionBackend;
476
+ /** RFC-394 M3:压缩触发策略列表(OR 合并)。 */
477
+ private readonly compactionPolicies;
478
+ /** RFC-394 M3:裁剪触发策略列表(OR 合并)。 */
479
+ private readonly prunePolicies;
400
480
  /** M-2:确定性时钟端口(缺省真实系统时钟)。 */
401
481
  private readonly clock;
402
482
  constructor(config: MemoryManagerConfig);
@@ -407,7 +487,7 @@ declare class MemoryManager {
407
487
  clearSession(sessionId?: string): void;
408
488
  /**
409
489
  * 审计修复:会话销毁/驱逐时遗忘其全部 per-session 状态——防三个 Map 在长跑进程中无界增长。
410
- * 与 clearSession 不同:此处清 archiveIdCounter(会话终态,无再压缩可能)。
490
+ * 与 clearSession 不同:此处清 archive 会话终态数据(无再压缩可能)。
411
491
  */
412
492
  forgetSession(sessionId: string): void;
413
493
  /**
@@ -423,6 +503,14 @@ declare class MemoryManager {
423
503
  * prune/compaction 一切触发线均按此计算,避免构造期 model 未知导致的 200K 默认锁死。
424
504
  */
425
505
  private effectiveContextWindow;
506
+ /**
507
+ * 生效压缩配置——CompactionBackend 经 getConfig 惰性读取。
508
+ * 装配面:reconfigure 更新 + 生效窗口 + coverage 阈值惰性读(settings 在 App
509
+ * 构造后才 load,静态快照会永远是 undefined;未注入或字段缺省时回退 memory 侧常量)。
510
+ * RFC-394 M2:原 compact() 调用处的内联合并逻辑迁入此处,backend 只做
511
+ * `{ ...DEFAULT, ...getConfig() }` 兜底。
512
+ */
513
+ private effectiveCompactionConfig;
426
514
  /**
427
515
  * 主动检查当前消息量是否超过压缩触发线(基于 reconfigure 后的新窗口);
428
516
  * 超过则 force-compact。用于模型切换时预防下一轮 413。
@@ -441,26 +529,26 @@ declare class MemoryManager {
441
529
  /** 估算复用变体(终局审查 2026-07-18:process() 一次估算供判定+执行两处消费,
442
530
  * 消除同批消息的重复全量遍历——WeakMap 缓存对 spread 新建的消息数组会穿透)。 */
443
531
  private needsPruneWith;
444
- /**
445
- * RFC review D8:距最后一条带时间戳消息(user/tool_result/system_notification——
446
- * assistant 消息由模型生成无 timestamp)的 gap 是否超时间基阈值。
447
- * 参照 CC timeBasedMCConfig:60min = 服务端 prompt cache 必过期,旧工具输出清掉纯收益。
448
- */
449
- private timeGapTriggered;
450
532
  prune(messages: readonly Message[], force?: boolean): PruneResult;
451
533
  private pruneWith;
452
534
  needsCompaction(messages: readonly Message[]): boolean;
453
535
  /**
454
- * 驻留(字节)维度是否已逼近预算——`needsCompaction` 的非 token 触发因子。
455
- *
456
- * 单独抽出的原因(RFC-321 R10,二轮实证):字节因子与已删除的条数因子**同型死区**——
457
- * 判定为真不代表切得动。`findCutPoint` 要求总 token ≥ keepRecent(窗口×0.1),大窗口下
458
- * 「字节超预算但总 token 偏小」的形态(如少量大附件)会让 `prepareCompaction` 返回 null,
459
- * 压缩静默不发生(实证:1M 窗口、200 条 × 1000 字符、字节因子触发 → compacted=false、
460
- * LLM 调用 0)。故 `process()` 在**由驻留压力驱动**时同样启用 keepRecent 钳制,与
461
- * 逃生阀 force 路径共用同一修法。
462
- */
463
- private residencyPressure;
536
+ * 驻留(字节)压力是否活跃——供 process() force keepRecent 钳制与日志归因用。
537
+ * RFC-394 M3:直接用 ResidencyPolicy 判定(策略对象复用,不内联逻辑)。
538
+ */
539
+ private isResidencyPressureActive;
540
+ /**
541
+ * RFC-394 M3:触发判定上下文装配——一次性读取所有策略所需的状态(estimate /
542
+ * 生效窗口 / 配置 / 时钟 / realInputTokens / 字节预算 / 字节估算 / timeGapMs),
543
+ * 供所有策略共用,消除 needsCompaction 与 needsPruneWith 各自读状态的重复。
544
+ */
545
+ private buildTriggerContext;
546
+ /**
547
+ * RFC review D8 / RFC-394 M3:距最后一条带时间戳消息(user/tool_result/
548
+ * system_notification——assistant 消息由模型生成无 timestamp)的 gap(ms)。
549
+ * 单一真源(timeGapTriggered 与 pruneWith 共用,消除重复倒序遍历)。
550
+ */
551
+ private computeTimeGapMs;
464
552
  isEligibleForManualCompact(messages: readonly Message[]): boolean;
465
553
  /**
466
554
  * @param options.force RFC-321 R10:强制压缩语义下 keepRecent 钳制到当前总量一半,
@@ -472,9 +560,8 @@ declare class MemoryManager {
472
560
  }): CompactionPreparation | null;
473
561
  compact(preparation: CompactionPreparation, sessionId?: string, signal?: AbortSignal): Promise<CompactionResult>;
474
562
  /**
475
- * 压缩归档单源(reused B1 缓存命中 / fresh LLM 压缩两路共用,memory-1 去重):递增 per-session
476
- * 归档序号 → 赋逻辑 `archive:<sessionId>:<idx>` → 仅当无 loadSessionEntries 重建器时落盘
477
- * (有重建器则归档按需从会话条目还原,archivePath 只作逻辑引用)。
563
+ * RFC-394 M4:归档记录委托给 ArchiveSource(SessionEntriesArchiveSource
564
+ * InMemoryArchiveSource)——MemoryManager 不再做形态分支。
478
565
  */
479
566
  private recordCompactionArchive;
480
567
  process(messages: readonly Message[], sessionId?: string, signal?: AbortSignal, options?: {
@@ -495,11 +582,7 @@ declare class MemoryManager {
495
582
  };
496
583
  }>;
497
584
  listArchives(sessionId: string): Promise<ArchiveEntry[]>;
498
- /** 从 session entries 的 compaction 节点枚举 ArchiveEntry 列表。 */
499
- private listArchivesFromEntries;
500
585
  readArchive(archivePath: string): Promise<string>;
501
- /** 从 session entries 的 compaction 边界间重建归档全文。 */
502
- private readArchiveFromEntries;
503
586
  dispose(): void;
504
587
  }
505
588
  declare function createMemoryManager(config: MemoryManagerConfig): MemoryManager;
@@ -853,10 +936,56 @@ declare const DEFAULT_COMPACTION_CONFIG: CompactionConfig;
853
936
  declare const DEFAULT_PRUNE_CONFIG: PruneConfig;
854
937
  declare function resolveContextSize(size: ContextSize, contextWindow: number): number;
855
938
  //#endregion
939
+ //#region src/memory-injection.d.ts
940
+ /**
941
+ * memory-injection.ts —— RFC-394 M6/P1-11:`<agent_memory>` 段注入逻辑。
942
+ *
943
+ * 从 `prompts.ts` 拆出——prompts.ts 只留 prompt 模板(摘要/抽取/turn-prefix),
944
+ * 本文件负责「多源记忆 → 带预算的 `<agent_memory>` 注入文本」:
945
+ * - token 预算记账(CJK 加权)
946
+ * - 二分截断到 code-point 边界
947
+ * - RFC-382 D1 索引行折叠(mtime 窗口)
948
+ * - `<memory_guidelines>` 尾部追加
949
+ *
950
+ * 公开导出不变(barrel re-export,消费方零破坏)。
951
+ */
952
+ /**
953
+ * `<agent_memory>` 段的默认总预算(tokens,粗估)。
954
+ *
955
+ * 本仓正常场景(AGENTS.md 三源 + AutoMemory 索引)实测 ~3.4k tokens;monorepo
956
+ * `discoverAgentsSources` 理论上限是 10 文件 × 64KB = 640KB,若真的堆到那个量级会把
957
+ * system prompt 撑爆。这里的预算不是替代 discoverAgentsSources 的单文件/文件数上限
958
+ * (那层继续管),而是在全部来源(含它管不到的 writable AGENTS.md / AutoMemory 索引)
959
+ * 汇总之后再把一道总闸——`buildMemoryInjection` 是唯一收口点,别处管不到的这里管。
960
+ *
961
+ * 取 3.4k 实测值的 ~2.3 倍留余量,同时把极端场景压掉 95%+。
962
+ */
963
+ declare const DEFAULT_MEMORY_INJECTION_BUDGET_TOKENS = 8000;
964
+ declare function buildMemoryInjection(memories: Map<string, string>, budgetTokens?: number, entryMtimes?: Map<string, number>, nowMs?: number): string;
965
+ //#endregion
856
966
  //#region src/prompts.d.ts
857
- declare const SUMMARIZATION_PROMPT = "You are a conversation summarizer for an AI coding assistant. Your task is to create a structured summary of the conversation that preserves all information needed to continue the work.\n\nCreate the summary in the following format:\n\n## Goal\n[What is the user trying to accomplish?]\n\n## Constraints & Preferences\n- [Any constraints, preferences, or requirements the user mentioned]\n\n## All User Requests\n- [List EVERY distinct request/instruction the user made, in order, that is not a tool result. This is the authoritative record of user intent \u2014 quote the user's own wording; do not paraphrase away specifics.]\n\n## Progress\n### Done\n- [x] [Completed work items]\n### In Progress\n- [ ] [Work in progress]\n\n## Key Decisions\n- **[Decision]**: [Brief rationale]\n\n## Next Steps\n1. [Planned next steps. For the immediate next action, include a VERBATIM quote of the most recent user message or your own last stated intent it derives from \u2014 anchors the task, prevents drift.]\n\n## File Operations\n### Read\n- [Files that were read]\n### Modified\n- [Files that were modified]\n\n## Critical Context\n- [Any critical context needed to continue the work]\n\nIMPORTANT:\n- Preserve exact file paths, function names, error messages, and code snippets\n- Keep technical details precise \u2014 do not generalize\n- Include all tool call results that affect the current state\n- Note any pending or failed operations";
967
+ /**
968
+ * RFC-394 M6/P1-5:SUMMARIZATION_PROMPT 收敛为壳 + SUMMARY_BODY_FORMAT(与其他变体一致,
969
+ * 消除双模板源的细微措辞漂移风险)。测试断言 `SUMMARIZATION_PROMPT` 含
970
+ * `'## All User Requests'` / `'EVERY distinct request'` —— SUMMARY_BODY_FORMAT 已含。
971
+ */
972
+ declare const SUMMARIZATION_PROMPT = "You are a conversation summarizer for an AI coding assistant. Your task is to create a structured summary of the conversation that preserves all information needed to continue the work.\n\nCreate the summary in the following format:\n\n## Goal\n[What is the user trying to accomplish?]\n\n## Constraints & Preferences\n- [Any constraints, preferences, or requirements the user mentioned]\n\n## All User Requests\n- [List EVERY distinct request/instruction the user made, in order, that is not a tool result. This is the authoritative record of user intent \u2014 multi-round compaction must never let an earlier request silently drop. Quote the user's own wording for each; do not paraphrase away specifics.]\n\n## Progress\n### Done\n- [x] [Completed work items]\n### In Progress\n- [ ] [Work in progress]\n\n## Key Decisions\n- **[Decision]**: [Brief rationale]\n\n## Next Steps\n1. [Planned next steps. For the immediate next action, include a VERBATIM quote of the most recent user message or your own last stated intent that it derives from \u2014 this anchors the task and prevents interpretation drift across compactions.]\n\n## File Operations\n### Read\n- [Files that were read]\n### Modified\n- [Files that were modified]\n\n## Critical Context\n- [Any critical context needed to continue the work]\n\nIMPORTANT:\n- Preserve exact file paths, function names, error messages, and code snippets\n- Keep technical details precise \u2014 do not generalize\n- Include all tool call results that affect the current state\n- Note any pending or failed operations";
858
973
  declare const UPDATE_SUMMARIZATION_PROMPT = "You are updating an existing conversation summary with new information. The existing summary and new messages are provided below.\n\nProduce a single UPDATED summary that stays BOUNDED \u2014 a summary that grows without limit across rounds eventually gets hard-truncated by the output cap, silently losing whatever fell past the limit. Keep it tight by actively triaging, not by appending.\n\nKeep (never drop):\n- Every distinct user request/instruction (the \"All User Requests\" record is authoritative)\n- Unfinished, in-progress, or blocked work\n- Decisions not yet verified, and anything the user corrected you on\n- Exact file paths, function names, error messages, code snippets still in play\n\nDrop / compress (make room):\n- Work that is both completed AND verified \u2014 collapse to a one-line outcome\n- Superseded intermediate attempts and abandoned approaches\n- Redundant restatements already captured elsewhere in the summary\n\nRules:\n- Move completed \"In Progress\" items to \"Done\", then compress \"Done\" per the above\n- Merge new work items, decisions, and context; do not simply append\n- Keep the same structured format (including \"All User Requests\")\n- If any information conflicts, use the newer version";
859
974
  declare const TURN_PREFIX_SUMMARIZATION_PROMPT = "You are summarizing the FIRST PART of an assistant turn that was split during conversation compaction. The remaining part of this turn is still in the conversation.\n\nCreate a brief summary in this format:\n\n## Original Request\n[What did the user ask for in this turn?]\n\n## Early Progress\n- [Key actions completed in the prefix portion]\n\n## Context for Remaining Messages\n- [Information needed to understand the remaining suffix messages]\n\nKeep it concise \u2014 this will be prepended to the remaining messages of this turn.";
975
+ /**
976
+ * RFC-339 D3:游标感知提示词的三个变体(选择逻辑见 `pickVariant`)。
977
+ *
978
+ * 缺陷背景(RFC-339 §1.3 缺陷 D):`prepareCompaction` 早已算出 `preservedMessages`
979
+ * (切点之后原样保留、会拼在摘要之后一起送回模型的近期消息),但提示词从不告诉模型
980
+ * 这个边界的存在。后果:①模型把保留区内容也概括进摘要 → 重复占位、概括版与原文版
981
+ * 并存易矛盾;②模型无法产出「读懂保留区所需的前置信息」这种面向续作的摘要。
982
+ *
983
+ * - FULL:无保留区(全量折叠,罕见)。等价于原 SUMMARIZATION_PROMPT。
984
+ * - WITH_PRESERVED_TAIL:**主路径**。显式告知其后 N 条原样保留、不要概括它们,
985
+ * 并要求产出「保留区依赖的前置信息」段。
986
+ * - SEGMENT:分批(map-reduce)的 map 阶段单段摘要,显式告知「这是第 i/N 段、不是
987
+ * 全部对话」,禁止输出面向全局的 next-step 判断(那属于 reduce 合并阶段)。
988
+ */
860
989
  declare const WITH_PRESERVED_TAIL_PROMPT = "You are a conversation summarizer for an AI coding assistant. You are summarizing the EARLIER portion of a conversation. The most recent messages are kept verbatim and will follow your summary unchanged \u2014 they are shown to you below in <preserved_tail_context> FOR REFERENCE ONLY.\n\nYour summary and those preserved recent messages together become the assistant's full context going forward.\n\nCreate the summary in the following format:\n\n## Goal\n[What is the user trying to accomplish?]\n\n## Constraints & Preferences\n- [Any constraints, preferences, or requirements the user mentioned]\n\n## All User Requests\n- [List EVERY distinct request/instruction the user made, in order, that is not a tool result. This is the authoritative record of user intent \u2014 multi-round compaction must never let an earlier request silently drop. Quote the user's own wording for each; do not paraphrase away specifics.]\n\n## Progress\n### Done\n- [x] [Completed work items]\n### In Progress\n- [ ] [Work in progress]\n\n## Key Decisions\n- **[Decision]**: [Brief rationale]\n\n## Next Steps\n1. [Planned next steps. For the immediate next action, include a VERBATIM quote of the most recent user message or your own last stated intent that it derives from \u2014 this anchors the task and prevents interpretation drift across compactions.]\n\n## File Operations\n### Read\n- [Files that were read]\n### Modified\n- [Files that were modified]\n\n## Critical Context\n- [Any critical context needed to continue the work]\n\n## Context the Preserved Tail Depends On\n- [Facts a reader MUST know to correctly understand the preserved recent messages shown in <preserved_tail_context>: decisions already made, file paths and their current state, conventions/constraints agreed earlier, mistakes already corrected, and any partially-done work those recent messages continue. Read the preserved tail, then look BACK through the earlier conversation for what it silently relies on. This section is the whole point of this summary \u2014 be specific.]\n\nIMPORTANT:\n- Preserve exact file paths, function names, error messages, and code snippets\n- Keep technical details precise \u2014 do not generalize\n- Include all tool call results that affect the current state\n- Note any pending or failed operations\n- Do NOT summarize the content of <preserved_tail_context> \u2014 it is kept verbatim after your summary and re-describing it wastes your budget. Use it ONLY to work out which parts of the EARLIER conversation it depends on.\n- Summarize ONLY the conversation inside <conversation>.";
861
990
  declare const SEGMENT_SUMMARIZATION_PROMPT = "You are summarizing ONE SEGMENT of a longer conversation for an AI coding assistant. This is a partial view \u2014 you are NOT seeing the whole conversation, and other segments are being summarized separately. Your segment summary will later be merged with the others.\n\nCreate a concise summary of THIS SEGMENT in the following format:\n\n## Goal\n[What is the user trying to accomplish?]\n\n## Constraints & Preferences\n- [Any constraints, preferences, or requirements the user mentioned]\n\n## All User Requests\n- [List EVERY distinct request/instruction the user made, in order, that is not a tool result. This is the authoritative record of user intent \u2014 multi-round compaction must never let an earlier request silently drop. Quote the user's own wording for each; do not paraphrase away specifics.]\n\n## Progress\n### Done\n- [x] [Completed work items]\n### In Progress\n- [ ] [Work in progress]\n\n## Key Decisions\n- **[Decision]**: [Brief rationale]\n\n## Next Steps\n1. [Planned next steps. For the immediate next action, include a VERBATIM quote of the most recent user message or your own last stated intent that it derives from \u2014 this anchors the task and prevents interpretation drift across compactions.]\n\n## File Operations\n### Read\n- [Files that were read]\n### Modified\n- [Files that were modified]\n\n## Critical Context\n- [Any critical context needed to continue the work]\n\nIMPORTANT:\n- Preserve exact file paths, function names, error messages, and code snippets\n- Keep technical details precise \u2014 do not generalize\n- Include all tool call results that affect the current state\n- Note any pending or failed operations\n- Do NOT emit conclusions that require seeing the whole conversation (e.g. a single global \"next step\"). Report only what THIS segment establishes; the merge step will reconcile across segments.\n- If <preserved_tail_context> is present, it holds the most recent messages, kept verbatim outside this compaction. Do NOT summarize it \u2014 use it ONLY to judge which parts of THIS segment it depends on, and make sure those parts survive into your summary. Summarize ONLY the content inside <conversation>.";
862
991
  declare const SEGMENT_MERGE_PROMPT = "You are merging several segment summaries of one conversation into a single coherent summary for an AI coding assistant. Each input below is a summary of a different (chronological) segment of the same conversation.\n\nReconcile them into one summary in the following format:\n\n## Goal\n[What is the user trying to accomplish?]\n\n## Constraints & Preferences\n- [Any constraints, preferences, or requirements the user mentioned]\n\n## All User Requests\n- [List EVERY distinct request/instruction the user made, in order, that is not a tool result. This is the authoritative record of user intent \u2014 multi-round compaction must never let an earlier request silently drop. Quote the user's own wording for each; do not paraphrase away specifics.]\n\n## Progress\n### Done\n- [x] [Completed work items]\n### In Progress\n- [ ] [Work in progress]\n\n## Key Decisions\n- **[Decision]**: [Brief rationale]\n\n## Next Steps\n1. [Planned next steps. For the immediate next action, include a VERBATIM quote of the most recent user message or your own last stated intent that it derives from \u2014 this anchors the task and prevents interpretation drift across compactions.]\n\n## File Operations\n### Read\n- [Files that were read]\n### Modified\n- [Files that were modified]\n\n## Critical Context\n- [Any critical context needed to continue the work]\n\nIMPORTANT:\n- Preserve exact file paths, function names, error messages, and code snippets\n- Keep technical details precise \u2014 do not generalize\n- Include all tool call results that affect the current state\n- Note any pending or failed operations\n- Resolve conflicts in favour of the LATER segment.\n- Merge duplicate items; do not simply concatenate.";
@@ -914,19 +1043,6 @@ declare function buildSummarizationPrompt(messages: string, previousSummary?: st
914
1043
  */
915
1044
  declare function buildSegmentMergePrompt(segmentSummaries: string, previousSummary?: string, customInstructions?: string): string;
916
1045
  declare function buildTurnPrefixPrompt(turnPrefixMessages: string): string;
917
- /**
918
- * `<agent_memory>` 段的默认总预算(tokens,粗估)。
919
- *
920
- * 本仓正常场景(AGENTS.md 三源 + AutoMemory 索引)实测 ~3.4k tokens;monorepo
921
- * `discoverAgentsSources` 理论上限是 10 文件 × 64KB = 640KB,若真的堆到那个量级会把
922
- * system prompt 撑爆。这里的预算不是替代 discoverAgentsSources 的单文件/文件数上限
923
- * (那层继续管),而是在全部来源(含它管不到的 writable AGENTS.md / AutoMemory 索引)
924
- * 汇总之后再把一道总闸——`buildMemoryInjection` 是唯一收口点,别处管不到的这里管。
925
- *
926
- * 取 3.4k 实测值的 ~2.3 倍留余量,同时把极端场景压掉 95%+。
927
- */
928
- declare const DEFAULT_MEMORY_INJECTION_BUDGET_TOKENS = 8000;
929
- declare function buildMemoryInjection(memories: Map<string, string>, budgetTokens?: number, entryMtimes?: Map<string, number>, nowMs?: number): string;
930
1046
  /**
931
1047
  * 跨会话经验抽取提示词。要求模型从一段会话切片里提炼可复用的「经验」
932
1048
  * (trigger=何时适用 / insight=怎么做 / tags=召回关键词),严格输出 JSON 数组。
@@ -985,13 +1101,12 @@ interface Lesson {
985
1101
  sourceSessionId: string;
986
1102
  createdAt: number;
987
1103
  /**
988
- * @deprecated RFC-284 D8:改用 `relevantHitCount`。
989
- *
990
- * 该字段唯一自增点是 `search()`,而注入路径走 `list()` `search()` 零生产调用方,
991
- * 故它在历史数据中结构性恒为 0(详见 RFC-036 §8.9 勘误)。保留仅为向后兼容:
992
- * 读取时与 `relevantHitCount` 双向同步,不再作为新的判据来源。
1104
+ * @deprecated RFC-394 M5:改用 `relevantHitCount`。该字段是 v1 遗留——`save()` 不再
1105
+ * 写入它,`search()`/`recordRelevantHits()` 不再同步它。旧数据文件里遗留的值由
1106
+ * `hydrateLesson` 读取时一次性映射到 `relevantHitCount`(读旧写新,无需迁移脚本)。
1107
+ * 类型改为可选——新创建的 lesson 不赋此属性(`JSON.stringify` 不落盘 undefined 键)。
993
1108
  */
994
- appliedCount: number;
1109
+ appliedCount?: number;
995
1110
  /** 语义类别。缺省视为未归类,由 M4 审计填充。 */
996
1111
  class?: LessonClass;
997
1112
  /** 生命周期状态。缺省视为 `active`。 */
@@ -1021,6 +1136,15 @@ type LessonInput = Omit<Lesson, 'id' | 'createdAt' | 'appliedCount'>;
1021
1136
  interface LessonFilter {
1022
1137
  tags?: string[];
1023
1138
  query?: string;
1139
+ /**
1140
+ * RFC-284 T7:是否包含已出射(archived/tombstone)的 lesson。缺省 false——
1141
+ * `list()` 的主消费方是 stable prompt 注入(lesson-injection.ts),归档语义
1142
+ * 的全部意义就是「不再进 stable 注入」;审计/维护工具需要全量视图时显式传 true。
1143
+ * 注意 `search()`(相关性召回)刻意**不受**此过滤影响——archived 的经验仍可被
1144
+ * query 相关召回进 volatile hints(出 stable 注入 ≠ 出召回,比 DSH 冻结归档温和,
1145
+ * 适配 lesson「低频但可能突然有用」的数据性质)。
1146
+ */
1147
+ includeArchived?: boolean;
1024
1148
  }
1025
1149
  interface SimilarLesson {
1026
1150
  lesson: Lesson;
@@ -1064,6 +1188,12 @@ interface LearningStoreOptions {
1064
1188
  * 两个写盘分支于单点。由 §D1 白名单点 agent-services-setup 从 isShadowModeEnabled 派生。
1065
1189
  */
1066
1190
  ephemeral?: boolean;
1191
+ /**
1192
+ * 确定性时钟端口(RFC-394 M5)。缺省 `() => Date.now()`(向后兼容);
1193
+ * 注入后 save 的 `createdAt` / search·recordRelevantHits 的 `lastAccessedAt` /
1194
+ * persist 的快照时间戳全部经注入时钟——确定性重放前提(CODE-STYLE §43)。
1195
+ */
1196
+ now?: () => number;
1067
1197
  }
1068
1198
  /** 估算注入 token(CJK≈1/字,ASCII≈4 字符/token)。与 RFC-284 探针脚本同口径。 */
1069
1199
  declare function estimateLessonTokens(lesson: Pick<Lesson, 'tags' | 'trigger' | 'insight'>): number;
@@ -1078,6 +1208,11 @@ declare class OperationalLearningStore {
1078
1208
  private lessons;
1079
1209
  private nextId;
1080
1210
  private loaded;
1211
+ /**
1212
+ * RFC-284 T7:本进程是否显式改过治理字段(archiveLessons)。为真时 `persist()` 跳过
1213
+ * 磁盘治理字段合并——否则本进程刚做的归档会被磁盘旧值(active)覆盖回去。
1214
+ */
1215
+ private governanceDirty;
1081
1216
  private readonly snapshotId;
1082
1217
  private readonly persistence;
1083
1218
  /** RFC-164 M164-2 D5:MemoryStore 接入(可选)——提供时优先于 `persistence` 路径。 */
@@ -1088,8 +1223,28 @@ declare class OperationalLearningStore {
1088
1223
  private readonly scope;
1089
1224
  /** RFC-345 §D3:影子态——persist() 短路(内存优先架构,写后读经 this.lessons Map 保持)。 */
1090
1225
  private readonly ephemeral;
1226
+ /** RFC-394 M5:确定性时钟端口(缺省 Date.now)。 */
1227
+ private readonly now;
1091
1228
  constructor(options?: LearningStoreOptions);
1092
1229
  save(input: LessonInput): Promise<Lesson>;
1230
+ /**
1231
+ * RFC-284 T7:归档写入通道——把指定 lesson 置为 `archived`(出 stable 注入面,
1232
+ * 数据保留、`search()` 相关性召回不受影响)。这是 archive-plan dry-run(T4a)
1233
+ * 的 apply 执行端。
1234
+ *
1235
+ * 保守语义(RFC-284 endgame-retention-design §4 Layer C):
1236
+ * - `pinned` / `state==='live'` 的 lesson **拒绝归档**(返回 skipped,不抛错)——
1237
+ * 与 dry-run checker 的保护项判据一致,双层防线(plan 侧 protected + store 侧硬闸)。
1238
+ * - 未知 id 计入 skipped(fail-soft:plan 与 store 可能有漂移,不让单条错拦整批)。
1239
+ * - 幂等:已 archived 的再归档计入 archived(状态不变,不重复写盘副作用)。
1240
+ */
1241
+ archiveLessons(ids: readonly string[]): Promise<{
1242
+ archived: string[];
1243
+ skipped: Array<{
1244
+ id: string;
1245
+ reason: string;
1246
+ }>;
1247
+ }>;
1093
1248
  search(query: string, limit?: number): Promise<Lesson[]>;
1094
1249
  /**
1095
1250
  * RFC-036 M61(R4 去重前置):在写入前查找与 `(trigger, insight)` 近似重复的既有经验。
@@ -1120,6 +1275,23 @@ declare class OperationalLearningStore {
1120
1275
  refresh(): Promise<void>;
1121
1276
  /** RFC-164 M164-2 D5:MemoryStore 路径的加载——store.load 返回原始 JSON 字符串,本地解析。 */
1122
1277
  private loadFromStore;
1278
+ /**
1279
+ * RFC-284 T7 修复(2026-08-15 验收发现的真实缺陷):写盘前合并磁盘上的**治理字段**。
1280
+ *
1281
+ * 事故:`scripts/rfc284-archive-plan.mjs --apply` 把 60 条 lesson 置为 `archived` 落盘后,
1282
+ * 40 分钟后被长驻 otto 进程整体抹回 `active`——`persist()` 用**进程启动时加载的内存 Map**
1283
+ * 全量覆写,完全不知道外部工具改过磁盘。归档在真机上直接失效(验收脚本抓到)。
1284
+ *
1285
+ * 所有权划分(与 auth-store「读盘-合并-写回」同款纹理):
1286
+ * - **运行时拥有**:trigger/insight/tags/relevantHitCount/lastAccessedAt 等自身产生的字段;
1287
+ * - **外部治理工具拥有**:`state`/`pinned`/`supersededBy`/`class`(archive-plan/governance-plan
1288
+ * 等脚本写入,运行时只读不产)。
1289
+ *
1290
+ * 合并规则:治理字段以**磁盘为准**(除非本进程显式改过它——`archiveLessons()` 走内存已改,
1291
+ * 此时内存值更新,用 `governanceDirty` 标记豁免)。磁盘读失败一律 fail-open 用内存值写出
1292
+ * (不让合并失败演变成写盘失败——丢新 lesson 比丢归档标记更严重)。
1293
+ */
1294
+ private mergeGovernanceFieldsFromDisk;
1123
1295
  private persist;
1124
1296
  }
1125
1297
  //#endregion
@@ -1399,5 +1571,5 @@ interface SignalLog {
1399
1571
  }
1400
1572
  declare function createSignalLog(dir: string): SignalLog;
1401
1573
  //#endregion
1402
- export { type AgentsDiscoveryOptions, type ArchiveEntry, type ArchiveStorage, type AutoExtractOutcome, type AutoExtractReason, AutoMemory, type AutoMemoryEntry, type AutoMemoryOptions, type CompactionConfig, type CompactionLockPort, type CompactionPrefix, type CompactionPreparation, type CompactionResult, type CompactionSpillSink, type ContextSize, type ContextTokenEstimate, type CutPoint, DEFAULT_COMPACTION_CONFIG, DEFAULT_MEMORY_INJECTION_BUDGET_TOKENS, DEFAULT_MEMORY_SOURCES, DEFAULT_PRUNE_CONFIG, DEFAULT_SIMILARITY_THRESHOLD, type EvolutionSignalCount, type EvolutionSignalKind, type EvolutionSignalPersistPort, type EvolutionSignalRecord, type EvolutionSignalSink, EvolutionSignalStore, type EvolutionSignalStoreOptions, type ExtractLLM, type ExtractionOptions, type FileStateCapture, FileStateManager, type FileStateSnapshot, FileSystemMemoryStore, HttpMemoryStore, IMAGE_BLOCK_TOKEN_ESTIMATE, InMemoryArchiveStorage, InMemoryMemoryStore, LESSON_EXTRACTION_PROMPT, type LearningStoreOptions, type Lesson, type LessonClass, type LessonFilter, type LessonInput, type LessonState, type LessonWriteStore, type MemoryAutoExtractConfig, type MemoryAutoExtractorDeps, type MemoryDefaults, MemoryManager, type MemoryManagerConfig, type MemorySource, type MemoryStore, type MessageFromEntry, type MinimalEntry, OperationalLearningStore, PersistentMemory, type PruneConfig, type PruneResult, SEGMENT_MERGE_PROMPT, SEGMENT_SUMMARIZATION_PROMPT, SPILL_MIN_CHARS, SUMMARIZATION_PROMPT, type SaveExtractedOptions, type SaveExtractedResult, type SignalLog, type SimilarLesson, type StorageType, type SummarizationContext, type SummarizationVariant, TURN_PREFIX_SUMMARIZATION_PROMPT, UPDATE_SUMMARIZATION_PROMPT, WITH_PRESERVED_TAIL_PROMPT, buildArchiveReference, buildExtractionPrompt, buildLowCoverageNotice, buildMemoryInjection, buildSegmentMergePrompt, buildSummarizationPrompt, buildTurnPrefixPrompt, computeLessonContentHash, computeMemoryDefaults, createMemoryAutoExtractor, createMemoryManager, createOverlayMemoryStore, createSignalLog, discoverAgentsSources, ensureTokenizer, estimateLessonTokens, estimateMessageTokens, estimateMessagesTokens, estimateTokens, estimateTokensHeuristic, extractLessons, formatArchive, messageToText, prune, resolveContextSize, saveExtractedLessons, spillBatchP3 };
1574
+ export { type AgentsDiscoveryOptions, type ArchiveEntry, type ArchiveStorage, type AutoExtractOutcome, type AutoExtractReason, AutoMemory, type AutoMemoryEntry, type AutoMemoryOptions, type CompactionConfig, type CompactionLockPort, type CompactionPrefix, type CompactionPreparation, type CompactionResult, type CompactionSpillSink, type ContextSize, type ContextTokenEstimate, type CutPoint, DEFAULT_COMPACTION_CONFIG, DEFAULT_MEMORY_INJECTION_BUDGET_TOKENS, DEFAULT_MEMORY_SOURCES, DEFAULT_PRUNE_CONFIG, DEFAULT_SIMILARITY_THRESHOLD, type EvolutionSignalCount, type EvolutionSignalKind, type EvolutionSignalPersistPort, type EvolutionSignalRecord, type EvolutionSignalSink, EvolutionSignalStore, type EvolutionSignalStoreOptions, type ExtractLLM, type ExtractionOptions, type FileStateCapture, FileStateManager, type FileStateSnapshot, FileSystemMemoryStore, HttpMemoryStore, IMAGE_BLOCK_TOKEN_ESTIMATE, InMemoryArchiveStorage, InMemoryMemoryStore, LESSON_EXTRACTION_PROMPT, type LearningStoreOptions, type Lesson, type LessonClass, type LessonFilter, type LessonInput, type LessonState, type LessonWriteStore, type MemoryAutoExtractConfig, type MemoryAutoExtractorDeps, type MemoryDefaults, MemoryManager, type MemoryManagerConfig, type MemorySource, type MemoryStore, type MessageFromEntry, type MinimalEntry, OperationalLearningStore, PersistentMemory, type PruneConfig, type PruneResult, SEGMENT_MERGE_PROMPT, SEGMENT_SUMMARIZATION_PROMPT, SUMMARIZATION_PROMPT, type SaveExtractedOptions, type SaveExtractedResult, type SignalLog, type SimilarLesson, type StorageType, type SummarizationContext, type SummarizationVariant, TURN_PREFIX_SUMMARIZATION_PROMPT, UPDATE_SUMMARIZATION_PROMPT, WITH_PRESERVED_TAIL_PROMPT, buildArchiveReference, buildExtractionPrompt, buildLowCoverageNotice, buildMemoryInjection, buildSegmentMergePrompt, buildSummarizationPrompt, buildTurnPrefixPrompt, computeLessonContentHash, computeMemoryDefaults, createMemoryAutoExtractor, createMemoryManager, createOverlayMemoryStore, createSignalLog, discoverAgentsSources, ensureTokenizer, estimateLessonTokens, estimateMessageTokens, estimateMessagesTokens, estimateTokens, estimateTokensHeuristic, extractLessons, formatArchive, formatMessageForSummary, messageToText, prune, resolveContextSize, saveExtractedLessons };
1403
1575
  //# sourceMappingURL=index.d.ts.map