import type { Model } from "../../internal/llm.js"; import type { ThinkingLevel } from "../../internal/harness.js"; import type { Brain } from "../types.js"; import type { MemoryStore } from "../memory.js"; import type { ModelPricing } from "../pricing.js"; /** * Memory write-side consolidation (design/41 B-full). After a task ends, reconcile the notes the model * saved this task against existing memory with **one** LLM call (Mem0-style ADD/UPDATE/DELETE/NONE), so * a scope's memory stays "few and accurate". This module is the pure orchestration — the Runner owns * the result-first / independent-timeout / fail-open envelope around it. * * Two-stage trigger keeps the LLM cost bounded ("write amplification" is the core tension): * 1. A **vector-distance band** classifies each new note by its NEAREST existing candidate: * `< lo` near-duplicate → cheap UPDATE (no LLM); `[lo, hi]` → batched into the LLM; `> hi` new → kept. * 2. **One batched LLM call** at task end handles all band-zone notes together. */ /** Default reconcile band over cosine distance ∈ [0, 2] (see {@link MemoryStore.searchScored}). */ export declare const DEFAULT_CONSOLIDATION_BAND: { readonly lo: 0.05; readonly hi: 0.3; }; /** Default top-k candidates fetched per new note (F6 token bound). */ export declare const DEFAULT_CONSOLIDATION_SEARCH_LIMIT = 20; /** Default cap on this-task notes consolidated in one batch (F6 token bound). */ export declare const DEFAULT_CONSOLIDATION_MAX_NOTES = 50; /** Default independent timeout for the whole consolidation pass (seconds). */ export declare const DEFAULT_CONSOLIDATION_TIMEOUT_SEC = 30; /** Normalize a note body for the EXACT-restatement check in the ` Promise<{ apiKey: string; headers?: Record; } | undefined>; /** Independent timeout / external-cancel signal for the whole pass. */ signal?: AbortSignal; } export interface ConsolidationParams { /** Must implement the id-addressable trio (searchScored/update/delete); see `supportsConsolidation`. */ store: MemoryStore; scope: string; /** This task's saved notes (from the `remember` tool). */ notes: ConsolidationNote[]; band: { lo: number; hi: number; }; searchLimit: number; maxNotes: number; llm: ConsolidationLLM; /** Called for each skipped/malformed reconcile decision (Runner forwards to `onError(phase:"memory")`). */ onWarn?: (err: unknown) => void; } /** Usage of a consolidation pass. `applied` = store mutations performed (cheap-path + LLM decisions). */ export interface ConsolidationStats { tokens: number; costMicroUsd: number; applied: number; /** * design/84 Seam B (前置 BLOCKER): the stable ids of the notes this pass CREATED via an ADD decision * (only present for an id-returning structured store). Periodic/incremental consolidation (Seam B) uses * this — together with the persisted `consolidationGenerated` marker that candidate filtering excludes — * so a later pass never re-consolidates this pass's own output (infinite re-merge). Empty when no ADD ran * or the store does not return ids. */ addedIds: string[]; /** * design/84 Seam B (no-miss): the stable ids of the input notes this pass ACTUALLY processed — i.e. the * post-trim, post-`maxNotes`-slice batch this pass classified/consolidated (with an id). Notes without a * store id are absent. */ consolidatedIds: string[]; /** * design/84 Seam B (MAJOR1 BLOCKER): the stable ids of the input notes this pass was FED but did NOT * process to completion (a cheap-path UPDATE/DELETE threw, or a band note's LLM decision was malformed / * its mutation threw, or the whole decisions array was unparseable). The cursor advance (both inline and * periodic) MUST stop STRICTLY BELOW the smallest failed id — a single max high-water marker cannot * express "skip the middle, keep a low one pending", so a low-id failure that is NOT the batch max would * otherwise be exiled from consolidation forever. Empty when every fed note succeeded. */ failedIds: string[]; } /** * Run one consolidation pass. Returns the usage (cost lands in `stats.memory`), or `undefined` when * there was nothing to do. Throws on a hard LLM failure (the Runner catches → `onError(phase:"memory")`); * the model's saved notes are never rolled back (fail-open). Per-decision problems are warned, not thrown. */ export declare function runMemoryConsolidation(p: ConsolidationParams): Promise; //# sourceMappingURL=memory-consolidation.d.ts.map