import type { MemoryRecord } from "./types.js"; /** Event time for distillation ordering/grouping: when it happened, not when the row moved. */ export declare function eventTimeOf(record: MemoryRecord): string; /** ISO-week key (UTC): "-W", so a batch is one namespace-week. */ export declare function isoWeekKey(iso: string): string; export interface ConsolidationBatch { readonly namespace: string; readonly period: { readonly since: string; readonly until: string; }; readonly records: readonly MemoryRecord[]; } /** Group active episodic records into per-(namespace, ISO week) batches, ordered by * event time; groups below minBatchSize are dropped (summarizing 2 runs is noise), * groups above maxBatchSize are chunked. Pure: the caller filters by age/status. */ export declare function selectConsolidationBatches(records: readonly MemoryRecord[], opts: { readonly minBatchSize: number; readonly maxBatchSize: number; }): ConsolidationBatch[]; export interface ReflectionInput { readonly namespace: string; readonly records: readonly MemoryRecord[]; /** The newest event time covered — becomes the next pass's watermark. */ readonly coveredUntil: string; } /** Records strictly newer than the watermark, newest-capped then re-sorted ascending. * Returns null below the threshold — that null is what makes `dawn memory reflect` * a cheap no-op for cron. Callers pass records from ONE namespace. */ export declare function selectReflectionInput(records: readonly MemoryRecord[], opts: { readonly minNewRecords: number; readonly maxRecords: number; readonly coveredUntil?: string; }): ReflectionInput | null; export declare function buildConsolidationPrompt(batch: ConsolidationBatch): string; export declare function buildReflectionPrompt(input: ReflectionInput): string; export declare function parseConsolidationOutput(raw: string): { summary: string; }; export interface ReflectionInsight { readonly insight: string; readonly confidence: number; readonly tags: readonly string[]; } /** Deliberate leniency asymmetry: a missing/garbage `confidence` falls back to * 0.5 and non-string tags are dropped (cosmetic fields — don't fail a whole * batch over them), while a missing `insight` throws (that IS the payload). */ export declare function parseReflectionOutput(raw: string): { insights: ReflectionInsight[]; }; /** One summary per batch: the id is derived, not random, so re-consolidating the * SAME batch overwrites its own summary instead of piling up duplicates — the * idempotency the engine relies on. * The source ids are part of the hash because (namespace, period) alone is NOT * unique: when every record in a namespace-week shares an exactly equal event * time (bulk import, backfill) and maxBatchSize splits them, each chunk derives * the same since/until (t and t+1ms) — two distinct batches, one id, and the * second summary would silently overwrite the first. Hashing the chunk's own * record ids disambiguates them and still yields a stable id for an identical * re-run. Covered by "gives same-period chunks distinct summary ids". */ export declare function buildSummaryRecord(batch: ConsolidationBatch, summary: string, now: string, opts?: { readonly ttlMs?: number; }): MemoryRecord; /** A pass that legitimately yields NO durable insight still did the work, and the * watermark is the only place that fact can live. Without this record the * namespace is re-selected — and re-PAID for — on every subsequent cron run, * forever, because `readWatermark` finds nothing to advance past. * It is written `superseded` on purpose: `recall` sees only active/candidate * rows, so the sentinel can never surface as a fake insight, while `browse` * (which readWatermark uses, and which does not filter by status unless asked) * still finds it. The id is derived from (namespace, coveredUntil) only — an * identical re-run overwrites its own sentinel instead of piling up. * Covered by "a zero-insight pass still advances the watermark" (distill-engine). */ export declare function buildReflectionWatermarkRecord(input: ReflectionInput, now: string): MemoryRecord; /** The id hashes (namespace, coveredUntil, insight) — so the SAME insight text in * the SAME pass is one record, not two (the engine's put dedupes it), while a * later pass with a newer watermark restates it as a distinct record. */ export declare function buildReflectionRecords(input: ReflectionInput, insights: readonly ReflectionInsight[], now: string, opts: { readonly status: "candidate" | "active"; }): MemoryRecord[]; //# sourceMappingURL=distill.d.ts.map