UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

75 lines (74 loc) • 4.16 kB
/** * The gate's reading of `tool.check`: the ONE comparison of an answer with the verdict standing where it was raised, and the * raise over every chain a leg's gate is constrained by (its own bus, then each inherited installation), read by that one * comparison. The lanes own the raise points and what each reading does to the pass; this module owns what an answer means. */ import type { PermissionResult, ToolCallRequest } from "./tool-policy.js"; import type { AllowRuleShadow } from "./allow-rule-shadow.js"; import { type InstallationAskSettlement, type ToolCheckOutcome, type ToolCheckProjection } from "./mods/stations.js"; /** A verdict `tool.check` is raised over — never a deny (a standing refusal raises nothing). */ export type ToolCheckStanding = Exclude<PermissionResult, { action: "deny"; }>; /** What a reading came to. `minted` on an ask: the reading minted it over an allow (the ask carries no stamp of the round yet). * `approved`: a person an inherited installation's question went to approved an edit of the call — the gate's approved-edit * pass takes it, as it takes an edit approved at this leg's own question. */ export type ToolCheckReading = { readonly kind: "stands"; } | { readonly kind: "denied"; readonly deny: PermissionResult; } | { readonly kind: "asked"; readonly ask: Extract<PermissionResult, { action: "ask"; }>; readonly minted: boolean; readonly marked?: true; } | { readonly kind: "cleared"; readonly allow: Extract<PermissionResult, { action: "allow"; }>; } | { readonly kind: "shadowed"; readonly shadows: readonly AllowRuleShadow[]; } | { readonly kind: "approved"; readonly allow: Extract<PermissionResult, { action: "allow"; }> & { readonly updatedInput: unknown; }; readonly outstanding?: Extract<PermissionResult, { action: "ask"; }>; }; /** The call a reading is about: its wire name, the args the check judged, the policy's rewrite riding a minted verdict, and the * request an inherited installation's question is settled over (the judged args). */ export interface ToolCheckCall { readonly toolName: string; readonly judged: unknown; readonly rewrite: unknown; readonly request: ToolCallRequest; readonly signal: AbortSignal | undefined; } /** One chain a gate raises `tool.check` on: its raise over a projection; for the leg's own bus only, the allow layer's * predicate under which its `allow` may clear an ask; for an inherited installation only, the settlement its question takes. */ export interface ToolCheckChain { readonly raise: (projection: ToolCheckProjection) => Promise<ToolCheckOutcome | undefined>; readonly mayClear?: () => boolean; readonly settle?: InstallationAskSettlement; } /** * The raise over every chain the leg's gate is constrained by, read by the one comparison: the leg's own bus first (its `allow` * may clear an ask where the allow layer may), then each inherited installation in order (its `allow` clears nothing — a * constraint only tightens). Each chain is raised over the verdict the previous left standing (`project`); a refusal ends it. * An inherited installation's `ask` is its own question, settled where its installation froze (`settle`, the settlement its * `classic.PreToolUse` ask takes in the fold): refused ⇒ refused; approved ⇒ the verdict standing before it stands (this leg's * own question, if any, is still this leg's); approved with an edit ⇒ `approved`, for the gate's approved-edit pass; floated * (the call marked for the park) ⇒ asked. The reading of the whole is the last verdict the chains moved the call to — an ask * keeps the disclosures any later `allow` made over it — else the disclosures alone, else it stands. Undefined when no chain * raised (nothing hangs on the event). */ export declare function readToolChecks(chains: readonly ToolCheckChain[], standing: ToolCheckStanding, call: ToolCheckCall, project: (current: ToolCheckStanding, mayClear: (() => boolean) | undefined) => ToolCheckProjection): Promise<ToolCheckReading | undefined>;