/** * The bounded result store for the LOSSY surface. * * MCP is the lossy surface (docs/agent-response-design.md): a tool result is * text in an agent's context window, so a listing that would be fine as JSON * over HTTP is a context bomb here. The rule that follows is "truncate the * VIEW, never the DATA": * * 1. the FULL result is persisted under an opaque `ref`, * 2. the tool returns a bounded window plus `shown` / `total` — so the agent * is TOLD it is looking at a slice, never left to infer it, and * 3. `expand_result` is the affordance that fetches the rest. * * A tool that renders `items.slice(0, 20)` and says nothing is the failure this * module exists to prevent: the agent reads twenty rows, concludes there are * twenty, and acts on a number that is wrong. * * BOUNDS. The store is in-process (it dies with the server, which is correct — * a ref is a handle on THIS session's answer, not a cache) and doubly bounded: * at most {@link RESULT_STORE_MAX_ENTRIES} results are retained, oldest evicted * first, and every entry expires {@link RESULT_STORE_TTL_MS} after it was * stored. A long-lived agent host cannot grow this without limit. TTL runs from * the STORE time and is not refreshed by reads, so a ref cannot be kept alive * forever by polling it. * * SECRET-BEARING RESULTS ARE NEVER STORED. `secret: true` returns the bounded * view with `ref: null` and writes nothing — enforced here, in code, not by * convention at the call sites. Per docs/agent-response-design.md a * secret-bearing response is never cached, never persisted into an * agent-surface result store, and never logged; a one-shot credential (a * maintenance lease's `holder_token`, a freshly minted key) that landed in a * retained buffer would be readable for the next half hour by anything that * could name its ref. */ /** How many results are retained at once. Oldest is evicted first. */ export declare const RESULT_STORE_MAX_ENTRIES = 32; /** How long a stored result stays addressable, measured from the store time. */ export declare const RESULT_STORE_TTL_MS: number; /** The default window a tool shows inline before pointing at `expand_result`. */ export declare const RESULT_STORE_DEFAULT_SHOWN = 20; /** `expand_result`'s default page size when the caller does not ask for one. */ export declare const RESULT_STORE_DEFAULT_EXPAND_LIMIT = 100; /** The ceiling on one `expand_result` window — the surface stays bounded even when expanded. */ export declare const RESULT_STORE_MAX_EXPAND_LIMIT = 1000; /** What a tool returns inline: a window, honestly labelled, plus the handle to the rest. */ export interface StoredResultView { /** The handle `expand_result` takes. `null` when nothing was stored (a secret-bearing result). */ ref: string | null; /** How many items are in {@link items} — the size of the VIEW. */ shown: number; /** How many items exist in total — the size of the DATA. */ total: number; items: T[]; } /** One window of a previously stored result. */ export interface ExpandedResult { ref: string; /** What produced it, e.g. `vault_heads`. Lets the caller render it sensibly. */ kind: string; offset: number; shown: number; total: number; items: unknown[]; } /** * Persist the full result and return a bounded view of it. * * @param kind What produced this, e.g. `vault_heads`. Echoed by `expand_result`. * @param items The COMPLETE list. Never pre-truncate before calling this. * @param opts.shown Window size. Defaults to {@link RESULT_STORE_DEFAULT_SHOWN}. * @param opts.secret `true` ⇒ store NOTHING and return `ref: null`. See the module header. */ export declare function storeResult(kind: string, items: T[], opts?: { shown?: number; secret?: boolean; }): StoredResultView; /** * Read a window of a stored result. * * Returns `null` when the ref is unknown, already evicted, or expired — the * three are deliberately indistinguishable, because the caller's recovery is * the same in all three cases: re-run the tool that produced it. */ export declare function expandResult(ref: string, opts?: { offset?: number; limit?: number; }): ExpandedResult | null; /** Drop every retained result. Test-only, and the server's own reset if it ever needs one. */ export declare function _resetResultStore(): void; /** Override the clock so TTL behaviour is testable without sleeping. Test-only; `null` restores it. */ export declare function _setResultStoreClock(clock: (() => number) | null): void; /** How many results are currently retained. Test-only introspection. */ export declare function _resultStoreSize(): number; //# sourceMappingURL=result-store.d.ts.map