UNPKG

@adonis-agora/agent

Version:

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

112 lines • 5.85 kB
import type { ToolConfirmation } from '../tool-presentation.js'; import type { Actor, ToolCallApproval, ToolCallStatus, ToolKind, ToolSpec } from '../types.js'; /** The approver that means "the person the run is acting for" — the thread's own actor. */ export declare const REQUESTER_APPROVER = "requester"; /** The tool a requirement is asked about. `spec` is absent where this process cannot resolve it. */ export interface ApprovalToolRef { name: string; kind: ToolKind; spec?: ToolSpec; } /** Where the call is being made. */ export interface ApprovalThreadRef { threadId: string; runId: string; agentName?: string; } /** * What an action tool call needs before it runs. * * - `required: false` → the call runs without asking anyone (it is still recorded as an action). * - `approver` → who may decide: {@link REQUESTER_APPROVER} (the thread's own actor — the default) * or any other string, which the default {@link ApprovalPolicy.canDecide} reads as a ROLE the * decider must hold. Streamed on `approval-requested` and persisted on the call. * - `ttlMs` → how long the request stays open. When it lapses the call settles `expired` and the * model is told nobody approved it. Absent → it waits indefinitely. */ export interface ApprovalRequirement { required: boolean; approver: string; ttlMs?: number; } /** A decision about to be taken on a call, as {@link ApprovalPolicy.canDecide} sees it. */ export interface ApprovalDecisionRef { toolCallId: string; /** The approver recorded on the call when it was put to a person. */ approver: string; /** The actorRef the run is acting for — the owner of the call's thread. */ requesterRef: string; } /** * Who has to approve an action tool call, and for how long the request stays open. * * Consulted by the LOOP once per `action` call, inside the call's `persist:toolcall` checkpoint — so * a durable run reads the answer back on every replay instead of re-deciding it against a policy * that may have changed while it was parked. Only `action` calls are asked about: a policy cannot * put a `read` behind an approval, and an `ask` (a question set) is always the requester's. */ export interface ApprovalPolicy { requirementFor(tool: ApprovalToolRef, actor: Actor, thread: ApprovalThreadRef): ApprovalRequirement | Promise<ApprovalRequirement>; /** * May `actor` settle this call? Checked by the approve/reject routes before a decision is * signalled. Absent → {@link defaultCanDecide}: the requester approver means the thread's own * actor, anything else is a role the actor must hold. Plug an authz Gate here for abilities. */ canDecide?(actor: Actor, decision: ApprovalDecisionRef): boolean | Promise<boolean>; } /** * The shorthand `config/agent.ts` takes instead of a whole {@link ApprovalPolicy}: who decides and * for how long, for every `action` call — or per tool, by name. `approvalPolicy: { ttlMs: 900_000 }` * expires every request after 15 minutes; `{ tools: { refund: { approver: 'admin' } } }` routes * refunds to admins and leaves every other action with the requester. */ export interface ApprovalRules { /** Who decides by default: `'requester'` (the default) or a role name. */ approver?: string; /** How long a request stays open by default, in ms. Omit → it never lapses. */ ttlMs?: number; /** Per-tool overrides. `required: false` runs that action without asking anyone. */ tools?: Record<string, Partial<ApprovalRequirement>>; } /** An {@link ApprovalPolicy} built from {@link ApprovalRules}. */ export declare function approvalRules(rules: ApprovalRules): ApprovalPolicy; /** Accept either a whole policy or the {@link ApprovalRules} shorthand. */ export declare function toApprovalPolicy(value: ApprovalPolicy | ApprovalRules): ApprovalPolicy; /** * The behaviour the lib always had: every `action` call waits on the person who asked, with no * expiry. */ export declare class DefaultApprovalPolicy implements ApprovalPolicy { requirementFor(tool: ApprovalToolRef): ApprovalRequirement; } /** The default decider rule — see {@link ApprovalPolicy.canDecide}. */ export declare function defaultCanDecide(actor: Actor, decision: ApprovalDecisionRef): boolean; /** Resolve whether `actor` may decide, through the policy's own rule when it has one. */ export declare function mayDecideApproval(policy: ApprovalPolicy | undefined, actor: Actor, decision: ApprovalDecisionRef): Promise<boolean>; /** The columns a store keeps for one call's approval, however it names them. */ export interface ToolCallApprovalColumns { proposalId?: string | undefined; confirmation?: ToolConfirmation | undefined; toolCallId: string; status: ToolCallStatus; approver: string | null | undefined; expiresAt: string | Date | null | undefined; remember: boolean | null | undefined; executedByRef: string | null | undefined; decidedVia: string | null | undefined; error: string | null | undefined; } /** What the approve/reject routes need to know about a call before they signal a decision on it. */ export interface ToolCallApprovalState { status: ToolCallStatus; /** `null` for a call no policy put to anyone (an `ask`, or a row written before approvers existed). */ approver: string | null; expiresAt: string | null; } /** * Read a tool-call row back as the {@link ToolCallApproval} a thread carries, or `null` for a call * no policy put to anyone (no approver recorded). Shared by every store so they agree on the * status mapping: a call that ran — or ran and failed — after a decision was APPROVED. */ export declare function toolCallApprovalFromRow(row: ToolCallApprovalColumns): ToolCallApproval | null; //# sourceMappingURL=approval-policy.d.ts.map