UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

132 lines (131 loc) • 6.45 kB
/** * The registration form, the two seats, and the screen every registration passes before admission: * shape, unique name, the seat × tier table, the `uses` declaration, and the `budgetMs` fallback. */ import { type ModBusSide, type ModEventName, type ModRegistrationTier, type ModSeat, type ModTier } from "./events.js"; import { type ModBudgetReading } from "./budget.js"; import type { ModEventPayload, ModFailureCause, ModMatcher, ModSkip } from "./site-rules.js"; /** The configuration refusal: a registration the kernel cannot take refuses the whole prepare. */ export declare const MODS_INVALID_CODE = "config.mods_invalid"; /** The notice an admission refusal becomes (the run goes on without the refused registration). */ export declare const MODS_REGISTRATION_REFUSED_CODE = "mods.registration_refused"; /** What a registration declares it will touch — the upper bound the kernel holds it to. */ export interface ModUses { /** Events it hangs handlers on (names or `<prefix>.*`). */ readonly events: readonly string[]; /** `$` methods it calls (method event names). */ readonly calls: readonly string[]; } /** Who raised a dispatch: a registration (through its `$`), or the engine (`{plugin: "engine", tier: "core"}`). */ export interface ModOrigin { readonly plugin: string; readonly tier: ModTier; } /** The engine's own origin; its `plugin` word is reserved (no registration may take it). */ export declare const ENGINE_ORIGIN: ModOrigin; /** The facts `$.plugin` carries. */ export interface ModPluginFacts { readonly name: string; } /** The part of `$` every bus gives; each side adds its methods (`$.<noun>.<method>`). */ export interface ModDollarBase { readonly plugin: ModPluginFacts; } /** One entry of `next.trace`: a handler (or the core) that ran beneath, and how it ended. */ export interface ModTraceEntry { readonly index: number; readonly plugin: string; readonly tier: ModTier; readonly outcome: ModTraceOutcome; readonly ms: number; } /** How a chain member ended (CC words). */ export declare const MOD_TRACE_OUTCOMES: readonly ["returned", "passed", "rejected", "caught", "expired", "kept", "skipped", "bypassed"]; export type ModTraceOutcome = (typeof MOD_TRACE_OUTCOMES)[number]; /** What a `.catch` reads off `next.error`. */ export interface ModCaughtError { readonly kind: ModFailureCause; readonly message?: string; readonly budget: number; } /** The third argument of a handler: continue the chain, or jump (prepend / append only). */ export interface ModNext { (e: ModEventPayload): Promise<unknown>; to(e: ModEventPayload, tier: ModTier): Promise<unknown>; readonly origin: ModOrigin; readonly signal: AbortSignal; /** What ran beneath this handler's last `next`. */ readonly trace: readonly ModTraceEntry[]; readonly budget: ModBudgetReading; /** Present on a `.catch`'s `next` only. */ readonly error?: ModCaughtError; /** Present on a `.catch`'s `next` only: whether the failed handler had called `next`. */ readonly called?: boolean; } export type ModHandler<D extends ModDollarBase = ModDollarBase> = ($: D, e: ModEventPayload, next: ModNext) => unknown; export interface ModHandlerOptions<D extends ModDollarBase = ModDollarBase> { /** Answers for the handler when it throws, runs out of budget or breaks the site's contract. */ readonly catch?: ModHandler<D>; /** Watch only: a detached `e`, outside the chain, its answer refused and disclosed. */ readonly observe?: boolean; } /** `on(pattern, handler, options?)` or `on(pattern, matcher, handler, options?)`. */ export interface On<D extends ModDollarBase = ModDollarBase> { (pattern: string, handler: ModHandler<D>, options?: ModHandlerOptions<D>): void; (pattern: string, matcher: ModMatcher, handler: ModHandler<D>, options?: ModHandlerOptions<D>): void; } export interface ModRegistration<D extends ModDollarBase = ModDollarBase> { /** Unique in the run; names the registration everywhere (origin, trace, disclosures, admission). */ readonly name: string; /** Deployment seat: required. Task seat: absent or `user`. */ readonly tier?: ModRegistrationTier; readonly uses: ModUses; /** The host's provenance label, handed to admission as given. */ readonly provenance?: string; /** Each handler's own time; default 10 000 ms. */ readonly budgetMs?: number; readonly options?: unknown; register(on: On<D>, options: unknown): void; } /** One admission result: mounted (with the patterns it actually hung) or refused (by whom, why). */ export type ModAdmissionRecord = { readonly name: string; readonly seat: ModSeat; readonly tier: ModTier; readonly events: readonly string[]; readonly observe?: readonly string[]; /** Judges skipped while this registration was judged (their failure or site violation), as the dispatch listed them. */ readonly skipped?: readonly ModSkip[]; } | { readonly name: string; readonly seat: ModSeat; readonly tier: ModTier; readonly refusedBy: string; readonly reason: string; }; /** The two seats as a bus receives them; a seat is a list of registrations or absent. Screened as untrusted input. */ export interface ModSeats<D extends ModDollarBase = ModDollarBase> { readonly deployment?: readonly ModRegistration<D>[]; readonly task?: readonly ModRegistration<D>[]; } /** A registration that passed the screen, in run order. */ export interface ScreenedRegistration<D extends ModDollarBase = ModDollarBase> { readonly registration: ModRegistration<D>; readonly name: string; readonly seat: ModSeat; readonly tier: ModRegistrationTier; readonly budgetMs: number; readonly uses: ModUses; readonly provenance?: string; readonly eventsBound: ReadonlySet<ModEventName>; readonly callsBound: ReadonlySet<ModEventName>; } export declare function modsInvalid(message: string): Error & { readonly code: string; }; /** * Screen both seats and put the registrations in run order: by tier, then deployment before task, then * each seat's own order. Throws `config.mods_invalid` for anything the kernel cannot take; a bad * `budgetMs` is reported and replaced by the default instead. */ export declare function screenModSeats<D extends ModDollarBase>(seats: ModSeats<D>, side: ModBusSide, report: (err: Error) => void): ScreenedRegistration<D>[];