import type { PromptDefinition, PromptHistoryAction, PromptHistoryEntry, PromptLabel, PromptReference, PromptStore, PromptVersion, RenderedPrompt, RenderOptions } from '../types/prompts.js'; import type { PromptDiff } from './diff.js'; import { type GateResult } from './errors.js'; /** What a promotion gate is asked to judge. */ export interface PromotionContext { /** The prompt. */ name: string; /** The version being promoted. */ version: PromptVersion; /** The label it is being promoted to. */ to: string; /** The label it is being promoted from, when the promotion names one. */ from?: string; /** The version `to` serves now, if any. */ current?: PromptVersion; /** The registry, for gates that look things up. */ registry: PromptRegistry; } /** Decides whether a version may be promoted to a label. */ export type PromotionGate = (context: PromotionContext) => Promise | GateResult; /** A webhook notified when prompts change, signed as operation webhooks are. */ export interface PromptWebhookConfig { /** Where changes are posted. */ url: string; /** Signs each delivery in the `x-nexus-signature` header. Verify with `verifyPromptWebhook()`. */ secret: string; /** Changes delivered. Defaults to `promote`, `rollback`, and `split`. */ actions?: readonly PromptHistoryAction[]; /** Headers added to each delivery. */ headers?: Record; /** Replaces the global `fetch`. */ fetch?: typeof fetch; /** Gives up on a delivery after this long, in milliseconds. Defaults to 10 seconds. */ timeoutMs?: number; } /** Options for a prompt registry. */ export interface PromptRegistryOptions { /** Where versions, labels, and history live. Defaults to a `MemoryPromptStore`. */ store?: PromptStore; /** Gates run before a promotion, by the label promoted to, such as `{ production: [experimentGate(...)] }`. */ gates?: Record; /** Webhooks notified of changes. */ webhooks?: readonly PromptWebhookConfig[]; /** Called after every recorded change. */ onChange?: (entry: PromptHistoryEntry) => void | Promise; /** Receives webhook delivery failures, which never fail the change itself. */ onWebhookError?: (error: unknown, entry: PromptHistoryEntry) => void; /** Compiled versions kept for rendering. Defaults to 256. */ maxCompiled?: number; /** Replaces the system clock, for tests. */ now?: () => Date; } /** A version resolved for serving, with the reference recorded on requests rendered from it. */ export interface ResolvedPrompt { /** The version served. */ version: PromptVersion; /** Name, version, label, and variant, as rendered requests record them. */ reference: PromptReference; } /** The outcome of a promotion. */ export interface PromotionResult { /** The label after the promotion. */ label: PromptLabel; /** Every gate's verdict. */ results: GateResult[]; /** False when the label already served the version, so nothing moved. */ changed: boolean; } /** * Versions prompts and moves labels between them. * * `commit()` stores a definition under its content version, so committing unchanged content is a * no-op. Labels — `production`, `staging`, a tag — point at versions; `promote()` moves one after its * gates agree, `rollback()` moves it back, and `split()` shares its traffic between versions. Every * change is recorded, and the store is the only state, so any number of processes can share one. */ export declare class PromptRegistry { private readonly options; /** Where versions, labels, and history live. */ readonly store: PromptStore; private readonly compiled; private readonly now; constructor(options?: PromptRegistryOptions); /** * Commits a prompt and returns its version. Unchanged content returns the existing version and * records nothing; `label` points labels at the version either way. */ commit(prompt: PromptDefinition | { definition: PromptDefinition; }, options?: { message?: string; author?: string; label?: string | readonly string[]; }): Promise; /** * A version by content version, label, or `latest`, the default. Throws `PromptNotFoundError` when * there is none. A split label resolves to its control arm; `resolve()` picks an arm. */ get(name: string, ref?: string): Promise; /** Resolves a reference for serving, choosing an A/B arm by `key` when the label splits traffic. */ resolve(name: string, ref?: string, options?: { key?: string; }): Promise; /** Renders a prompt by reference, recording the version, label, and arm in `metadata.prompt`. */ render(name: string, variables?: Record, options?: RenderOptions & { ref?: string; key?: string; }): Promise; /** Renders a resolved version. Compilation is cached per version, since versions never change. */ renderVersion(resolved: ResolvedPrompt, variables?: Record, options?: RenderOptions): RenderedPrompt; /** Points a label at a version, without gates. Throws `PromptConflictError` if the label moved meanwhile. */ label(name: string, label: string, ref: string, options?: { by?: string; note?: string; }): Promise; /** Removes a label. Resolves false when there was none. */ unlabel(name: string, label: string, options?: { by?: string; note?: string; }): Promise; /** * Moves `to` to a version — named directly, or whatever `from` serves — once every gate for `to` * allows it. Throws `PromptPromotionError` when a gate refuses, unless `force` is set, in which * case the refusals are still reported and recorded in the note. */ promote(name: string, options: { to: string; from?: string; version?: string; by?: string; note?: string; force?: boolean; }): Promise; /** Moves a label back to where it pointed before its last change. */ rollback(name: string, label: string, options?: { by?: string; note?: string; }): Promise; /** * Splits a label's traffic between versions, for an A/B test. The first arm is the control, which * `get()` returns. Splits are not gated: split only between versions already fit to serve. */ split(name: string, label: string, arms: ReadonlyArray<{ ref: string; weight: number; }>, options?: { by?: string; note?: string; }): Promise; /** A prompt's history, newest first, optionally for one label. */ history(name: string, options?: { label?: string; limit?: number; }): Promise; /** Versions of a prompt, newest first. */ versions(name: string, options?: { limit?: number; }): Promise; /** Every label of a prompt. */ labels(name: string): Promise; /** Every prompt name. */ names(): Promise; /** What changed between two references: messages line by line, partials, configuration, and defaults. */ diff(name: string, from: string, to: string): Promise; private pointer; private remember; private record; }