UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

96 lines (95 loc) • 5.96 kB
import type { PromptCatalog } from "./catalog/schema.js"; /** Deterministic canonical JSON (sorted keys) — the one identity encoding (the catalog digest, the identity, the * center artifact digest). */ export declare function canonical(node: unknown): string; /** `sha256:<hex>` over a canonical encoding. */ export declare function digestOf(node: unknown): string; /** The bundled catalog's digest. Array positions that carry no meaning are normalized (sections by rank, messages and * bands by id), so the digest does not depend on how a module lays out its arrays; variant order is meaning (first * match wins) and stays. */ export declare function catalogDigestOf(catalog: PromptCatalog): string; /** The inputs of a run's prompt identity. Only `center` is pinned (resolved by digest on resume); the rest are what * the run computed, kept so a later run can say what changed. Absent `center` / `deploy` / `task` = that layer * contributed nothing. */ export interface PromptIdentityLayers { readonly catalog: string; readonly renderers: Readonly<Record<string, number>>; /** The adopted center artifact's digest. */ readonly center?: string; readonly deploy?: string; readonly task?: string; /** H(the run's selector values). */ readonly binding: string; } /** A run's prompt identity inputs plus its pinned center layer's provenance — what the epoch record carries. */ export interface RunPromptIdentity { readonly layers: PromptIdentityLayers; readonly sourceRevision?: string; } /** The one identity digest over the four inputs. */ export declare function promptIdentityOf(layers: PromptIdentityLayers): string; /** How a recorded epoch came to be: a legal boundary (`session_start`, `compaction`), or a record that code or * inputs moved (`code_change`, naming the changed layers when they are known) or that only the selector values * did (`selection_change`). */ export declare const PROMPT_EPOCH_ACTIVATIONS: readonly ["session_start", "compaction", "code_change", "selection_change"]; export type PromptEpochActivation = (typeof PROMPT_EPOCH_ACTIVATIONS)[number]; /** What a `code_change` record names as changed. `published_schema` is the one replacement of a retired-shape center * pin by the current center layer. */ export declare const PROMPT_EPOCH_CHANGES: readonly ["catalog", "renderers", "deploy", "task", "published_schema"]; export type PromptEpochChange = (typeof PROMPT_EPOCH_CHANGES)[number]; /** The durable record, persisted as a first-class session entry and restated in every compaction entry's * `details.promptEpoch`. */ export interface PromptEpochDescriptor { /** Monotonic per-session record counter. */ readonly epoch: number; /** The run's prompt identity ({@link promptIdentityOf}). */ readonly identity: string; readonly layers: PromptIdentityLayers; readonly activatedBy: PromptEpochActivation; /** Present only on `code_change` records whose changed layers are known. */ readonly changed?: readonly PromptEpochChange[]; /** Opaque publish provenance of the pinned center layer (present only with `layers.center`; never digested). */ readonly sourceRevision?: string; } /** What a stored epoch record reads as on the resume path: a v3 pin, or a retired shape recognized by name. */ export type StoredPromptEpoch = { readonly kind: "pin"; readonly descriptor: PromptEpochDescriptor; } | { readonly kind: "legacy"; readonly centerPinned: boolean; }; /** * Shape-normalize an untrusted v3 descriptor — the current shape's one judge (the first reading of * {@link readStoredPromptEpoch}; a session backend judges a record with it). Strict: a bounded positive epoch, a full * digest identity that MATCHES its layers, the closed activation and change vocabularies, provenance only beside a * center layer. Members it does not read (a session entry's own `type` / `id` / `parentId` / `timestamp`) are ignored. * Undefined for anything else — including every retired shape. */ export declare function normalizePromptEpoch(raw: unknown): PromptEpochDescriptor | undefined; /** * The resume path's reading of one stored record: a valid v3 pin, `legacy` (a retired shape, recognized by its field * names — nothing in it is parsed but whether `centerArtifactDigest` is a digest, the only value the retired reader * took for a pin), or undefined (malformed: the walk skips it). */ export declare function readStoredPromptEpoch(raw: unknown): StoredPromptEpoch | undefined; /** * The record a run leaves at prepare, or undefined when the stored pin already names this run's identity. * - no record: `session_start` for a session with no prior conversation; otherwise `code_change` (a session that * predates epochs — what changed is unknown); * - a v3 pin: the same identity ⇒ nothing; else `code_change` naming the changed code / input layers, or * `selection_change` when only the selector values moved; * - `legacy`: `code_change` — naming `published_schema` when the retired record pinned a center artifact (the caller * applied the center source's tri-state to it), otherwise unknown. The retired record's counter is not read; the * v3 line starts at 1. */ export declare function prepareEpochRecord(stored: StoredPromptEpoch | undefined, layers: PromptIdentityLayers, ctx: { readonly priorConversation: boolean; readonly sourceRevision?: string; }): PromptEpochDescriptor | undefined; /** * The record a compaction restates or advances: the current pin restated when the run's identity is unchanged (the * boundary is stamped), otherwise a new record with the run's layers after the boundary — an adopted center * candidate, or an emptied center layer after an explicit revocation. */ export declare function selectCompactionEpoch(current: PromptEpochDescriptor | undefined, layers: PromptIdentityLayers, sourceRevision?: string): PromptEpochDescriptor;