/** * Session entity table: reversible placeholders for coherent chat. * * Blanket `[REDACTED]` makes the assistant's replies nonsense. Instead each * redacted value gets a stable, typed placeholder (`[GIVEN_NAME_1]`, `[SSN_2]`) * that survives across turns: the same raw value always maps to the same token, * so the model can reason about "GIVEN_NAME_1" and we {@link rehydrate} the real * value back into its reply before display. * * The map lives only on the client. What leaves the device is placeholdered * text; the table never crosses the wire. */ import { type PiiLabel, type Span } from "./types"; /** Result of scrubbing one message. */ export interface ScrubResult { /** Text with PII replaced by placeholders. Safe to send/log. */ readonly text: string; /** Placeholders introduced or reused in this message. */ readonly placeholders: readonly string[]; } /** * Optional display aliases for placeholder tokens. By default a GIVEN_NAME span * becomes `[GIVEN_NAME_1]`; pass `{ GIVEN_NAME: "NAME" }` to get `[NAME_1]` instead. * Only the visible token changes — detection and policy are unaffected. */ export type PlaceholderAliases = Partial>; /** Token shape minted by the table; also the regex used to find them on the * way back. Kept in one place so scrub and rehydrate can never disagree. */ export declare const PLACEHOLDER_PATTERN: RegExp; /** * A per-conversation store mapping raw PII values to stable placeholders. * Keyed by `label + normalized value` so "John" stays `GIVEN_NAME_1` on every turn * and casing/whitespace noise doesn't mint duplicate tokens. */ export declare class SessionEntityTable { private readonly aliases; private readonly keepLabels; private readonly forward; private readonly reverse; private readonly counters; constructor(aliases?: PlaceholderAliases, keepLabels?: ReadonlySet); /** The visible name used in tokens for a label (alias or the label itself). */ private displayName; /** Get or mint the placeholder for a given label+value. Idempotent. */ placeholderFor(label: PiiLabel, value: string): string; /** * Replace each redactable span with its placeholder. Spans are pre-sorted * right-to-left by {@link applyPolicy}, so splicing never invalidates an * earlier offset. */ scrub(raw: string, spans: readonly Span[]): ScrubResult; /** * Restore real values in an assistant reply. Used on the *outbound* response * so the user sees "John", not "[NAME_1]". Unknown tokens are left intact. */ rehydrate(text: string): string; /** True if `token` is a placeholder this table can resolve. */ knows(token: string): boolean; } //# sourceMappingURL=session.d.ts.map