agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
62 lines (61 loc) • 2.7 kB
TypeScript
/**
* 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<NarrativeBeat>[])
*
* This stage produces full `MemoryEntry<NarrativeBeat>` 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<NarrativeBeat>[];
}
/**
* Build the `extractBeats` stage function.
*
* ```ts
* let b = flowChart<ExtractBeatsState>('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<ExtractBeatsState>) => Promise<void>;