/**
 * Guardrails on the agent loop's own seams: an {@link InputProcessor} that scans (and redacts) every
 * prompt — including the tool results riding in it — an {@link OutputProcessor} that scans every
 * answer and the tool calls it asks for, a tool-handler wrapper, and a tool-definition screen.
 *
 * Built only on the processor SPI, so it is a consumer of the loop rather than a part of it: the
 * same rules and detectors run standalone through `scan` for traffic that never meets the loop.
 */
import type { InputProcessor, OutputProcessor } from '../spi/processors.js';
import type { ToolHandler } from '../spi/tool.js';
import type { Actor } from '../types.js';
import { type ToolDefinitionText } from './detectors/tool-poisoning.js';
import { type GuardHit, type ScanOptions, type ScanResult } from './engine.js';
import type { Finding, GuardContext, GuardrailAction, GuardrailRule, GuardrailStage, PiiType, SecretType, Segment } from './types.js';
import { Vault } from './vault.js';
/** What a rule's `when` and a custom detector see when the guardrails run inside the loop. */
export interface AgentGuardContext extends GuardContext {
    /** Undefined only for a tool definition screened outside any turn. */
    threadId?: string;
    actor?: Actor;
    agentName?: string;
    /** Model step within the run; undefined outside a processor. */
    step?: number;
    /** The tool server a screened definition came from (e.g. the MCP server's name). */
    server?: string;
}
type Stages = readonly GuardrailStage[];
export interface PiiShorthand {
    action: GuardrailAction;
    types?: readonly PiiType[];
    /**
     * Put the original values back into the answer and into tool arguments (the model only sees
     * placeholders). Covers values from the prompt and from tool results. Default true.
     */
    restore?: boolean;
    stages?: Stages;
}
export interface SecretsShorthand {
    action: GuardrailAction;
    types?: readonly SecretType[];
    stages?: Stages;
}
export interface InjectionShorthand {
    /** Default `block`. */
    action?: GuardrailAction;
    /** Noisy-OR score (0-1) at which the heuristics fire. Default 0.5. */
    threshold?: number;
    stages?: Stages;
}
export interface ToolPoisoningShorthand {
    /** `block` (default) refuses the tool in {@link Guardrails.screenTool}; `log` only reports it. */
    action?: 'block' | 'log';
    threshold?: number;
}
/** One decision worth auditing. Never carries the matched values themselves. */
export interface GuardrailEvent {
    stage: GuardrailStage;
    /** The effective action (`approve` is reported as it was configured, and enforced as a block). */
    action: GuardrailAction;
    decisive?: {
        id: string;
        name: string;
        message: string;
    };
    /** Hits in the newest content only — history re-sent every step is not reported again. */
    hits: GuardrailEventHit[];
    redactions: number;
    latencyMs: number;
    context: AgentGuardContext;
}
export type GuardrailEventHit = Omit<GuardHit, 'values'> & {
    /** {@link GuardrailsOptions.fingerprint} of each distinct value; empty without one. */
    fingerprints: string[];
};
/** Where a thread's reversible placeholders live between the prompt and the answer. */
export interface VaultStore {
    load(threadId: string): Vault | undefined | Promise<Vault | undefined>;
    save(threadId: string, vault: Vault): void | Promise<void>;
}
/**
 * The default {@link VaultStore}: this process's memory, bounded to the most recent threads. A run
 * resumed in ANOTHER process finds no vault, so its placeholders reach the reader unrestored — the
 * values still never reach the model. Supply a shared store (with {@link Vault.toJSON}) to restore
 * across processes; it then holds the raw values.
 */
export declare class InMemoryVaultStore implements VaultStore {
    private readonly maxThreads;
    private readonly vaults;
    constructor(maxThreads?: number);
    load(threadId: string): Vault | undefined;
    save(threadId: string, vault: Vault): void;
}
export type GuardrailRulesSource = readonly GuardrailRule<AgentGuardContext>[] | ((ctx: AgentGuardContext) => readonly GuardrailRule<AgentGuardContext>[] | Promise<readonly GuardrailRule<AgentGuardContext>[]>);
export interface GuardrailsOptions {
    /** PII (email, phone, CPF/CNPJ, SSN, cards with Luhn, IBAN, IPv4). */
    pii?: GuardrailAction | PiiShorthand;
    /** API keys, tokens and private keys. */
    secrets?: GuardrailAction | SecretsShorthand;
    /** Prompt-injection / jailbreak heuristics. */
    injection?: GuardrailAction | InjectionShorthand;
    /** Screen tool definitions for hidden instructions — see {@link Guardrails.screenTool}. */
    toolPoisoning?: boolean | ToolPoisoningShorthand;
    /**
     * More rules, evaluated alongside the shorthands. A function is called per scan with the turn's
     * context, which is the seam for per-tenant policy: look the tenant's rules up by `ctx.actor`.
     */
    rules?: GuardrailRulesSource;
    /** Audit hook. Awaited; a throw is swallowed so an audit sink can never change a decision. */
    onEvent?: (event: GuardrailEvent) => void | Promise<void>;
    /** Keyed hash (or any stable digest) of a matched value, reported on events instead of it. */
    fingerprint?: (value: string) => string;
    /** Per-stage refusal messages for rules that set none. */
    messages?: ScanOptions['messages'];
    /** Where reversible placeholders live between prompt and answer. Default {@link InMemoryVaultStore}. */
    vaults?: VaultStore;
    /**
     * Keep the turn streaming: the output processor declares `incremental` with this lookback, so
     * the loop releases a prefix while holding the last `lookbackChars` characters. `false` gates the
     * whole answer instead. Default `{ lookbackChars: 256 }` — wide enough for every built-in
     * pattern and placeholder; widen it for custom patterns that match longer text.
     */
    incremental?: false | {
        lookbackChars?: number;
    };
    /** Processor name (user-visible on a refusal). Default `guardrails`. */
    name?: string;
}
/** A guardrail refused content the loop cannot rewrite around: a prompt, or a tool call. */
export declare class GuardrailBlockedError extends Error {
    readonly stage: GuardrailStage;
    /** The message for the person — the rule's own, or the stage default. */
    readonly userMessage: string;
    readonly rule?: {
        id: string;
        name: string;
    } | undefined;
    constructor(stage: GuardrailStage, 
    /** The message for the person — the rule's own, or the stage default. */
    userMessage: string, rule?: {
        id: string;
        name: string;
    } | undefined);
}
/** The rules the shorthand options stand for. Exported so a caller can inspect or extend them. */
export declare function shorthandRules(options: GuardrailsOptions): GuardrailRule<AgentGuardContext>[];
/**
 * Guardrails for the agent loop. Register the two processors, optionally wrap tool handlers, and
 * hand {@link screenTool} to whatever imports remote tool definitions:
 *
 * ```ts
 * const guardrails = createGuardrails({ pii: 'redact', secrets: 'block', injection: { threshold: 0.6 }, toolPoisoning: true });
 * // config/agent.ts
 * defineConfig({ inputProcessors: [guardrails.input], outputProcessors: [guardrails.output], … });
 * ```
 */
export declare class Guardrails {
    private readonly options;
    /** Scans every prompt; redacts in place, withholds tool results, throws on a blocked prompt. */
    readonly input: InputProcessor;
    /** Scans every answer and the tool calls it asks for; redacts, restores placeholders, or rejects. */
    readonly output: OutputProcessor;
    private readonly shorthand;
    private readonly vaults;
    /** Per thread: hits already reported this turn, so re-scans of the same content stay quiet. */
    private readonly reported;
    constructor(options?: GuardrailsOptions);
    /** Every rule in force for `ctx`: the shorthands, then {@link GuardrailsOptions.rules}. */
    rulesFor(ctx: AgentGuardContext): Promise<GuardrailRule<AgentGuardContext>[]>;
    /**
     * Scans arbitrary segments at one stage with the configured rules, reporting through `onEvent`.
     * What the processors use; also the entry point for traffic that never meets the loop.
     */
    scan(ctx: AgentGuardContext, segments: readonly Segment[], vault?: Vault): Promise<ScanResult>;
    /**
     * Screens one tool definition (name, title, description, and every description in its input
     * schema) for hidden instructions. `allowed: false` means a `block`/`approve` rule fired — leave
     * the tool out of the catalog. Shaped to be handed straight to an MCP importer's screen hook.
     */
    screenTool(tool: ToolDefinitionText & {
        server?: string;
    }): Promise<{
        allowed: true;
    } | {
        allowed: false;
        reason: string;
    }>;
    /**
     * Wraps a tool handler so its arguments are guarded where the loop cannot rewrite them: the
     * thread's placeholders are restored (the model only ever saw `[EMAIL_1]`, the tool needs the
     * address), then the `tool_args` rules run — `redact` rewrites what the tool receives, `block`
     * throws a {@link GuardrailBlockedError}, which the model reads as the tool's failure.
     */
    wrapTool<I, O>(toolName: string, handler: ToolHandler<I, O>): ToolHandler<I, O>;
    private contextOf;
    private processInput;
    private guardToolResult;
    private processOutput;
    private report;
}
/** Shorthand for `new Guardrails(options)`. */
export declare function createGuardrails(options?: GuardrailsOptions): Guardrails;
/**
 * The tool-poisoning screen alone — no rules, no events. `score` is the noisy-OR of the signals
 * that fired; `findings` is empty below `threshold` (default 0.5).
 */
export declare function screenToolDefinition(tool: ToolDefinitionText, threshold?: number): {
    score: number;
    findings: Finding[];
};
export {};
//# sourceMappingURL=agent.d.ts.map