/** * extractBeats — write-side stage that compresses `scope.newMessages` * into `NarrativeBeat`s via a pluggable `BeatExtractor`. * * Reads from scope: `newMessages`, `turnNumber` * Writes to scope: `newBeats` (MemoryEntry[]) * * This stage produces full `MemoryEntry` records so the * downstream write stage (a thin adapter over `writeMessages`) can * persist them via the ordinary `MemoryStore.putMany` batched API. * Entry ids are `beat-{turn}-{index}` — deterministic, idempotent on * re-run within the same turn (matches the `writeMessages` convention). * * The extractor is called ONCE per turn on the turn's new messages. * Returning an empty array is valid — not every turn produces a beat. */ import type { TypedScope } from 'footprintjs'; import type { MemoryEntry } from '../entry/index.js'; import type { MemoryState } from '../stages/index.js'; import type { BeatExtractor } from './extractor.js'; import type { NarrativeBeat } from './types.js'; export interface ExtractBeatsConfig { /** The extractor to call. See `heuristicExtractor` / `llmExtractor`. */ readonly extractor: BeatExtractor; /** * Optional tier for the persisted beats (passed through to the write * stage downstream). Typical pattern: `'hot'` for recent turns, * `'warm'` for older, `'cold'` for archival. Omit for no tier. */ readonly tier?: 'hot' | 'warm' | 'cold'; /** * Optional TTL in ms from `Date.now()` applied to persisted beat * entries. Useful for retention windows — `'hot'` beats expire in 7 * days, `'cold'` beats live indefinitely, etc. */ readonly ttlMs?: number; /** * Optional id producer — receives `(turn, index, beat)` and returns * the MemoryEntry id. Defaults to `beat-{turn}-{index}` which makes * re-runs of the same turn idempotent. */ readonly idFrom?: (turn: number, index: number, beat: NarrativeBeat) => string; } /** State added to `MemoryState` by this stage. */ export interface ExtractBeatsState extends MemoryState { /** * Extracted beats as complete `MemoryEntry` records, ready for a * downstream write stage to persist via `store.putMany`. */ newBeats?: readonly MemoryEntry[]; } /** * Build the `extractBeats` stage function. * * ```ts * let b = flowChart('Seed', seed, 'seed'); * b = b.addFunction('ExtractBeats', extractBeats({ extractor }), 'extract-beats'); * b = b.addFunction('WriteBeats', writeBeats({ store }), 'write-beats'); * ``` */ export declare function extractBeats(config: ExtractBeatsConfig): (scope: TypedScope) => Promise;