@sema-agent/core
Version:
Stateless, task-oriented AI agent core
55 lines (54 loc) • 4.69 kB
TypeScript
import type { PermissionResult } from "./tool-policy.js";
export declare const refusedOutOfContract: (message: string) => PermissionResult;
/** Is `d` a refusal the engine itself minted (by object identity — a look-alike `deny` a caller built is not one)? The receipt's
* answer is one of two things (the engine's refusal or its detached copy), and this tells them apart. */
export declare const isEngineRefusal: (d: unknown) => boolean;
/** A decision's `decisionReason` — the closed set; the type is derived FROM this list, so a word added to either side is a
* compile error rather than a drift between the type and the screen. Module-private (the package publishes the type).
* `skill`: an active skill's list spoke — the allow layer's skill member cleared the call (`allowed-tools`), or this
* run's deny row refused it (`disallowed-tools`); distinct from `rule` (a deployment policy) and `persisted_rule` (a
* person's stored row) because the authority is the skill the run activated. `deployment_rule` / `request_rule`: an entry
* of the deployment's `RunnerDeps.allowedTools` / of this run's `TaskSpec.allowedTools` cleared the call (the allow layer's
* two entry-list members) — one word per author, so "who said this needs no asking" is read off the decision. */
declare const DECISION_REASONS: readonly ["rule", "mode", "hook", "safety", "classifier", "persisted_rule", "sandbox", "org_rule", "org_unavailable", "read_only", "skill", "deployment_rule", "request_rule"];
export type DecisionReason = (typeof DECISION_REASONS)[number];
export declare const RETIRED_WINDOW_MEMBER_DENY_MESSAGE: string;
export declare const carriesRetiredWindow: (fallback: unknown) => boolean;
/**
* The VALUE screen over the engine's one-read record of a decision (never a second read of the caller's object): every
* closed-set member holds a member of its set or is absent (`action` present), and the retired window is absent. The refusal
* names the member and the set, one code for every arm. `undefined` is the receipt's spelling of absence.
*/
export declare function screenContractValues(contract: Record<string, unknown>, opts?: {
skip?: ReadonlySet<string>;
optional?: ReadonlySet<string>;
}): PermissionResult | undefined;
/**
* The receipt of the records a decision nests, into the one-read record itself: each record that is PRESENT is received by
* {@link receiveContract} (the decision's own function — an ordinary object, own enumerable data members, a prototype member
* refused by name) and must hold every required member; a present value that is not an object, or a record missing a required
* member, is refused by path. The engine's copy replaces the caller's record in `contract`, so no station reads the caller's
* again. Returns the refusal, or `undefined` when every record is in contract.
*/
export declare function receiveNestedRecords(contract: Record<string, unknown>): PermissionResult | undefined;
/** The nested records of an engine receipt, by path — frozen with the receipt, so a receipt handed back unread is the receipt. */
export declare function nestedRecordsOf(receipt: object): object[];
/** One level of the receipt, the same for the decision and each record it nests. The carrier is an ORDINARY object — it and
* every object on its prototype chain are looked at for being a Proxy before any descriptor is asked for (a Proxy's traps are
* the caller's code; the look invokes none of them) — so the receipt runs none of the carrier's code: a contract member is
* absent or an own enumerable DATA property, its value taken off the descriptor (no read at all). Anything else refuses the
* carrier, the member named by `path`: an accessor (never invoked), and a member the prototype or a non-enumerable property
* supplies, unless the nearest descriptor holding it spells absence (an `undefined` data property). Descriptors are looked up
* as OWN entries of the descriptor map, so a polluted `Object.prototype` names no member. Members outside the contract are
* not looked at — but a retired one (`retired`) is refused by name when the carrier carries it by that same law. */
/** The receipt's own answers carry a `kind` discriminant as an own property: narrowing never asks the prototype chain (`in`) for a
* word, so a polluted `Object.prototype` cannot answer for the receipt either. */
export type Received = {
kind: "held";
held: Record<string, unknown>;
} | {
kind: "refused";
refused: PermissionResult;
};
export declare function receiveContract(carrier: object, members: readonly string[], path: string, retired?: Readonly<Record<string, string>>): Received;
export {};