@sema-agent/core
Version:
Stateless, task-oriented AI agent core
66 lines (65 loc) • 3.8 kB
TypeScript
/**
* What a Skill card's approval is bound to, as ONE value: the skill the call names and the two lists approving it releases,
* in the rule grammar's canonical spelling (de-duplicated, sorted). Its hash is the `boundGrantDigest` a parked approval is
* judged by, so a reader holds the list a person approved and the binding that covers it as the same fact — the live
* `AskRequest`, the parked row and the inbox projection all carry it (minted by `skillGrantBindingMembers`).
*
* A leaf on purpose: the checkpoint projection reads it at its boundary and may not import the module that mints it (it imports only
* the hash).
*/
export interface BoundSkillGrants {
/** The skill's name as the loaded table spells it, or `null` when the call names no loaded skill (it grants nothing). */
readonly skill: string | null;
/** The skill's `allowed-tools` entries — what approving the activation lets be used without asking. */
readonly allowedTools: readonly string[];
/** The skill's `disallowed-tools` entries — what activating it refuses for the rest of the run. */
readonly disallowedTools: readonly string[];
}
/**
* Why a card carries no binding digest — the closed set of `boundGrantAbsence`: `not_bindable` (the call is not an
* activation of the engine's `Skill` tool: it binds no grant) or `unreadable` (the card binds a grant and what it binds
* cannot be read: a stored row whose digest is not a string, or that says neither).
*/
export declare const BOUND_GRANT_ABSENCES: readonly ["not_bindable", "unreadable"];
export type BoundGrantAbsence = (typeof BOUND_GRANT_ABSENCES)[number];
/**
* A stored value read as a {@link BoundSkillGrants}, whole or not at all: a fresh copy of the three members and nothing else,
* or `undefined` when any member is not of its type. Every member is read ONCE, so the value screened is the value published.
*/
export declare function readBoundSkillGrants(raw: unknown): BoundSkillGrants | undefined;
/** The card members every ask carries about its binding — exactly one arm: a call to the engine's `Skill` tool carries the
* digest and the value it hashes, every other call the absence word. */
export type SkillGrantBindingMembers = {
readonly boundGrantDigest: string;
readonly boundGrants: BoundSkillGrants;
readonly boundGrantAbsence?: never;
} | {
readonly boundGrantAbsence: BoundGrantAbsence;
readonly boundGrantDigest?: never;
readonly boundGrants?: never;
};
/** The members of a card that is not a `Skill` activation: the factory's other arm, and what a tool's own consent card (never a
* `Skill` call) spreads. */
export declare const NOT_BINDABLE: Readonly<{
readonly boundGrantAbsence: "not_bindable";
}>;
/** The leg's binding factory ({@link SkillGrantBindingMembers} for a call over `args`), the one every ask-mint site spreads. */
export type GrantBindingOf = (call: {
readonly toolName: string;
}, args: unknown) => SkillGrantBindingMembers;
/**
* The binding members of a stored parked row, as the inbox projection publishes them — exactly one of three: the digest when it
* is a string (and the lists only as the value that digest hashes — {@link readBoundSkillGrants} whole, and equal to the digest by
* hash; a pair that disagrees, or lists beside no digest, would show an approver one list while the approval binds another), else
* the row's absence word when it is a member of the set, else `unreadable` — the row does not say what it binds.
*/
export declare function readBoundBinding(row: {
readonly boundGrantDigest?: unknown;
readonly boundGrants?: unknown;
readonly boundGrantAbsence?: unknown;
}): {
boundGrantDigest: string;
boundGrants?: BoundSkillGrants;
} | {
boundGrantAbsence: BoundGrantAbsence;
};