import { AgentMiddleware } from "../contracts/middleware/middleware.contract.mjs"; import { GuardrailMatch, GuardrailPhase } from "./contracts/verdict.type.mjs"; import { GuardOptions } from "./contracts/guard-options.type.mjs"; //#region ../ai/src/guard/guard.d.ts /** * One flagged match recorded into `ctx.state`. Mirrors the * {@link GuardrailVerdict} `flag` shape plus the phase it fired at, so an * observer can reconstruct *what* tripped *where* without re-running the * detector. */ interface FlagRecord { /** The detector that produced the flag. */ readonly detector: string; /** Where the detector was running. */ readonly phase: GuardrailPhase; /** The detector's human-readable reason. */ readonly reason: string; /** The matches the detector recorded. */ readonly matches: readonly GuardrailMatch[]; } /** * Build the composed **guardrail middleware** (surfaced as * `ai.guardrail(options)`) — one {@link AgentMiddleware} that runs the * configured detectors at three hook points and maps each * {@link GuardrailVerdict} onto the pipeline's throw / return / record * mechanics: * * - **`input`** detectors run at `trip.before` over the outbound prompt * (`extractUserText(ctx.messages)`). `block` / `flag` only — the core * `trip.before` seam cannot rewrite-and-continue, so a `redact` verdict here * is downgraded to a `block`. * - **`output`** detectors run at `trip.after` over `response.content`. Full * `allow` / `redact` / `block` / `flag` support — a `redact` returns a * replacement `ModelResponse` with the rewritten `content`. * - **`tool`** detectors run at `tool.before` over `JSON.stringify(toolArgs)`. * `block` / `flag`; a `redact` is downgraded to a `block` * (`tool-arg-redaction-unsupported`). Scoped to `toolNames` via the core * `forTool(toolNames, mw)` helper when set. * * **Verdict → action.** Detectors run in registration order; the first * `redact` / `block` short-circuits the phase. `block` throws a * {@link GuardrailViolationError} on `result.error` (never out of the * pipeline); `flag` records the match into `ctx.state` under `.flags` * and continues; a `{ type: "block", escalate: true }` verdict awaits * `escalation.onBlock` before throwing. A detector that *throws* is treated as * an infra fault and fails open (recorded as a flag, run continues). * * @param options - The {@link GuardOptions}: per-phase detector arrays, * optional `toolNames` scope, `escalation` seam, and `name` override. * @returns One {@link AgentMiddleware} to pass into `ai.agent({ middleware: [...] })`. * * @example * const policy = ai.guardrail({ * name: "compliance", * input: [ai.guardrail.injection({ onMatch: "block" })], * output: [ai.guardrail.pii({ onMatch: "redact", mask: "[REDACTED:{label}]" })], * tool: [ai.guardrail.pii({ onMatch: "block" })], * toolNames: ["send_email"], * escalation: { async onBlock(e) { await reviewQueue.enqueue(e); } }, * }); * * const agent = ai.agent({ model, tools: [sendEmail], middleware: [policy] }); */ declare function guard(options: GuardOptions): AgentMiddleware; //#endregion export { FlagRecord, guard }; //# sourceMappingURL=guard.d.mts.map