agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
57 lines (56 loc) • 3.15 kB
TypeScript
/**
* embeddingSummary — what a recording keeps of a vector: its shape, not its
* bytes.
*
* Pattern: pure copy-on-write projection, in the `storedPreview` family —
* "summarise structured values rather than serialize them", applied
* to the one field measured to dominate a recording's size.
* Role: recorders/observability layer. Applied at the RECORDING boundary
* (BoundaryRecorder payload capture, `recordRun` freeze), never to
* live run state — stages and stores keep their real vectors.
* Emits: N/A.
*
* ── The measurement this exists for ─────────────────────────────────────────
* A single retrieval turn's recording measured 2.76 MB in a production RAG
* deployment — about 1.1 MB of it embedding floats, because the memory-read
* subflow's boundary output carries every retrieved entry, and every entry
* carries its full vector (1,024 floats serializing at ~19 bytes each). No
* consumer of a recording reads those floats: retrieval debugging needs the
* score, the passage, the document and the rejected candidates — all of which
* live in the retrieval evidence and none of which this touches. The vector's
* only recording-worthy facts are that it existed, its dimensionality, and a
* checksum-grade magnitude. That is exactly what `{ dims, norm }` keeps.
*
* The walk is copy-on-write: a value with no embeddings anywhere is returned
* BY REFERENCE, so the common payload costs one traversal and zero
* allocation. It never mutates its input — recordings share structure with
* live run state, and live state is borrowed, not owned.
*
* Two spellings are recognised, because the memory layer writes both:
* - `embedding: number[]` — a `MemoryEntry`'s vector (read side);
* - `embeddings: number[][]` — the write pipeline's per-message batch.
*
* Idempotent by construction: a summary is not a numeric array, so a value
* that has already been summarised passes through unchanged.
*/
/** What remains of a vector in a recording: dimensionality and L2 norm. */
export interface EmbeddingSummary {
readonly dims: number;
readonly norm: number;
}
/** Summarise one vector. Exported for consumers that render recordings. */
export declare function summarizeVector(vector: readonly number[]): EmbeddingSummary;
/**
* Replace every `embedding` / `embeddings` field in a JSON-ish value with its
* `{ dims, norm }` summary. Copy-on-write: returns the SAME reference when
* nothing needed replacing; otherwise a structurally-shared copy. Never
* mutates the input.
*
* Shared nodes stay shared: a snapshot holds the same entry object at several
* paths (live state, stage writes, commit history), so results are memoized
* per input object — every path gets the SAME summarized copy, not one copy
* and one raw leak. Cycle-safe: an object seen again while still being walked
* resolves to its original reference (a cyclic value could not be serialized
* anyway).
*/
export declare function summarizeEmbeddings(value: unknown): unknown;