/**
 * Function-library registry: typed `FunctionDef` + name-keyed dispatcher.
 *
 * Architecture (per `project_opensquid_modular_function_skill_separation`):
 * the runtime ships atomic primitives (regex, state I/O, LLM calls, verdicts);
 * skills compose them into rule processes via YAML. The registry is the ONLY
 * path from a skill step to a primitive — no global `import { add }`
 * shortcuts. The evaluator (Task 1.3) drives every call through `call()`.
 *
 * Each `FunctionDef` carries its own Zod arg schema. The registry validates
 * args before invoking `execute`, so primitives see only well-typed input
 * and never have to re-check what the YAML claimed it was passing.
 *
 * Error model: throws are reserved for programmer errors at startup
 * (duplicate registration). Runtime failures travel as `Result<T, FunctionError>`
 * — see `src/runtime/result.ts`. Primitives MUST NOT throw inside `execute`;
 * the evaluator catches stray throws and wraps them in `{ kind: 'runtime' }`,
 * but that path is for bugs, not for normal failure modes.
 *
 * Imports from: zod, runtime/types.ts, runtime/result.ts.
 * Imported by: runtime/ (evaluator), packs/ (when skills resolve `function:` refs).
 */
import type { z } from 'zod';
import type { ModelsConfig } from '../packs/schemas/models.js';
import { type Result } from '../runtime/result.js';
import type { Event } from '../runtime/types.js';
import type { Fsm } from '../runtime/fsm.js';
export interface EvalCtx {
    event: Event;
    bindings: Map<string, unknown>;
    sessionId: string;
    packId: string;
    /**
     * PR-followup: pack-shipped `models.yaml` content (`Pack.models`), threaded
     * through so `llm_classify` / `subagent_call` primitives can consult the
     * pack's declared aliases without the global `loadModelsConfig()` call
     * having to re-discover the active pack. `undefined` for packs that ship
     * no `models.yaml` and for non-pack call sites (legacy daemon).
     */
    packModels?: ModelsConfig;
    /**
     * Slice A3b: the calling pack's declared lifecycle FSM (`Pack.fsm`), threaded
     * like `packModels` so `read_fsm_state` / `advance_fsm` can read + advance the
     * machine without re-loading the pack. `undefined` when the pack ships no
     * `fsm.yaml` (those primitives then no-op).
     */
    packFsm?: Fsm;
}
export interface FunctionError {
    kind: 'arg_invalid' | 'runtime' | 'timeout' | 'not_found';
    message: string;
    cause?: unknown;
}
export interface FunctionDef<TArgs = unknown, TResult = unknown> {
    name: string;
    argSchema: z.ZodSchema<TArgs>;
    execute: (args: TArgs, ctx: EvalCtx) => Promise<Result<TResult, FunctionError>>;
    /** Checkpoint after each call so crashes can resume mid-rule. */
    durable?: boolean;
    /** Cache identical `(fn, args)` outputs (DURABLE.3, wired separately). */
    memoizable?: boolean;
    /** Order-of-magnitude latency hint; informational only. */
    costEstimateMs?: number;
}
/**
 * Effective (post-default) durability metadata for a registered primitive.
 * Returned by `FunctionRegistry.durability` so callers (evaluator, future
 * memo cache, audit tooling) read a normalized record rather than poking at
 * the raw `FunctionDef`.
 */
export interface PrimitiveDurability {
    durable: boolean;
    memoizable: boolean;
    costEstimateMs: number | undefined;
}
export declare class FunctionRegistry {
    private map;
    register<TArgs, TResult>(def: FunctionDef<TArgs, TResult>): void;
    get(name: string): FunctionDef<unknown, unknown> | undefined;
    has(name: string): boolean;
    list(): string[];
    /**
     * Normalized durability metadata for a registered primitive. Returns
     * `undefined` if the name is not registered. Default-falses apply so
     * downstream code never has to repeat the `?? false` plumbing.
     */
    durability(name: string): PrimitiveDurability | undefined;
    call(name: string, rawArgs: unknown, ctx: EvalCtx): Promise<Result<unknown, FunctionError>>;
}
//# sourceMappingURL=registry.d.ts.map