UNPKG

@adonis-agora/agent

Version:

Governed, durable-backed AI agent (chat + tool-calling + governance) for AdonisJS — part of the Agora ecosystem.

90 lines • 4.75 kB
import { type DetectorSpec, type Finding, type GuardContext, type GuardrailAction, type GuardrailRule, type GuardrailStage, type Segment } from './types.js'; import { Vault } from './vault.js'; /** * One reported hit. `values` holds the distinct matched values so a caller can fingerprint them * (a keyed hash correlates repeats without storing the value) — never persist them as they are. */ export interface GuardHit { ruleId: string; ruleName: string; action: GuardrailAction; detector: string; category: string; score: number; count: number; /** Distinct values found (at most 20). In-memory only. */ values: string[]; /** Found in the newest turn (false: only in re-sent history, already reported once). */ fresh: boolean; /** `detector_error` hits: what failed, and what the rule's fail mode made of it. */ error?: string; failMode?: 'open' | 'closed'; } export interface ScanResult { stage: GuardrailStage; /** Most severe action among the rules that fired. */ action: GuardrailAction; /** The rule that decided a block / approval, and the message for the person. */ decisive?: { id: string; name: string; message: string; }; /** Segment texts after redaction (same order as the input). */ segments: string[]; /** Whether any segment changed. */ changed: boolean; hits: GuardHit[]; vault: Vault; /** Redacted spans. */ redactions: number; latencyMs: number; } export interface ScanOptions { /** Per-stage refusal messages, for rules that set none. */ messages?: Partial<Record<GuardrailStage, string>>; /** Refusal message for `approve`, for rules that set none. */ approvalMessage?: string; /** * Stages whose redactions are reversible (unless the rule sets `restore: false`). Default * `['llm_request']`: what the caller sent is theirs to get back; what a tool or the model produced * is removed one-way. A caller whose tool results are its own data may add `tool_result`. */ restorableStages?: readonly GuardrailStage[]; } export declare const DEFAULT_MESSAGES: Record<GuardrailStage, string>; export declare const DEFAULT_APPROVAL_MESSAGE = "This needs approval under your organization's AI guardrails before it can go ahead."; /** What replaces an instruction-like finding: it is removed, not tokenized. */ export declare const INJECTION_REPLACEMENT = "[removed: suspected prompt injection]"; /** Whether a rule's scope covers the context (stage, tool, `when`). Segments are filtered apart. */ export declare function ruleApplies<C extends GuardContext>(rule: GuardrailRule<C>, ctx: C): boolean; export declare function orderRules<C extends GuardContext>(rules: readonly GuardrailRule<C>[]): GuardrailRule<C>[]; /** Runs one detector on one text. A custom detector's throw is the rule's fail mode to decide. */ export declare function runDetector<C extends GuardContext>(spec: DetectorSpec<C>, text: string, ctx: C): Promise<Finding[]>; /** * The in-process detectors of a rule set, as one span locator — what a stream window must never * cut through (see `StreamGuard`'s `locate`). Custom detectors are left out: they may be remote. */ export declare function spanLocator<C extends GuardContext>(rules: readonly GuardrailRule<C>[]): ((text: string) => Finding[]) | undefined; /** * Non-overlapping spans. Overlapping findings are merged into their union (nothing that any * detector found is left uncovered), labelled by the longer finding (ties: the higher score) — * an injected HTML comment that contains an email address is removed as a whole. With `text`, a * merged span's value is re-read from it. */ export declare function resolveOverlaps(findings: readonly Finding[], text?: string): Finding[]; export declare function applyRedactions(text: string, findings: readonly Finding[], vault: Vault, restorable: boolean): { text: string; count: number; }; /** * Evaluates the rules for one stage over a set of segments. Rules run by ascending priority; an * `allow` rule that fires stops evaluation; otherwise every firing rule contributes and the most * severe action wins (block > approve > redact > log). Detector results are shared between rules. * * Blocking applies to the NEWEST turn: content found only in re-sent history (`fresh: false`) was * already refused once, so it is removed one-way instead — the conversation can go on and the value * still never reaches the model. */ export declare function scan<C extends GuardContext>(rules: readonly GuardrailRule<C>[], ctx: C, segments: readonly Segment[], vault?: Vault, options?: ScanOptions): Promise<ScanResult>; //# sourceMappingURL=engine.d.ts.map