Skip to main content
All types are exported from @boundary/contract.
import type {
  ContractResult,
  ContractAttempt,
  ContractError,
  AttemptDetail,
  FailureCategory,
  Rule,
  RunFn,
  Message,
  ContractConfig,
  DefinedContract,
  RetryOptions,
  ContractLogger,
} from "@boundary/contract";

Core types

ContractResult<T>

The return type of every contract call. Discriminated union on ok.
type ContractResult<T> =
  | {
      ok: true
      data: T              // typed, validated, all rules passed
      attempts: number     // total attempts made
      raw: string          // the raw LLM output that was accepted
      durationMS: number   // total wall-clock time
    }
  | {
      ok: false
      error: ContractError
    }

ContractAttempt

Passed to your RunFn on each attempt.
type ContractAttempt = {
  attempt: number          // 1-indexed attempt number
  maxAttempts: number      // from retry config
  instructions: string     // auto-generated prompt from schema
  repairs: Message[]       // repair messages from prior failure (empty on first)
  previousError?: ContractError
  previousCategory?: FailureCategory
}

ContractError

type ContractError = {
  message: string          // human-readable summary
  attempts: AttemptDetail[] // one entry per failed attempt
}

AttemptDetail

type AttemptDetail = {
  raw: string              // raw LLM output
  cleaned: unknown         // parsed/cleaned output
  issues: string[]         // list of violations
  category: FailureCategory
}

FailureCategory

type FailureCategory =
  | "EMPTY_RESPONSE"     // model returned nothing
  | "REFUSAL"            // model refused the task
  | "NO_JSON"            // response contained no JSON
  | "TRUNCATED"          // JSON was cut off
  | "PARSE_ERROR"        // malformed JSON
  | "VALIDATION_ERROR"   // valid JSON, failed schema
  | "INVARIANT_ERROR"    // passed schema, failed rules
  | "RUN_ERROR"          // RunFn threw an error

Rule<T>

type Rule<T> = (data: T) => true | string
Return true if the data is correct. Return a string describing the violation if it’s wrong.

RunFn

type RunFn = (attempt: ContractAttempt) => Promise<string | null>
Your LLM call function. Return the raw response as a string, or null if the model returned nothing.

Message

type Message = {
  role: string
  content: string
}
Used in attempt.repairs and repair functions.

Configuration types

ContractConfig<T>

type ContractConfig<T> = {
  schema: ZodType<T>
  rules?: Rule<T>[]
  retry?: RetryOptions
  repairs?: RepairOverrides
  instructions?: { suffix?: string }
  onAttempt?: AttemptHook
  logger?: ContractLogger<T>
  debug?: boolean
}

RetryOptions

type RetryOptions = {
  maxAttempts?: number     // default: 3
  backoff?: "none" | "linear" | "exponential"
  baseMs?: number          // default: 200
}

RepairOverrides

type RepairOverrides = Partial<Record<FailureCategory, RepairFn | false>>
type RepairFn = (detail: AttemptDetail) => Message[]

ContractLogger<T>

Hook into the execution lifecycle. All hooks are optional.
type ContractLogger<T> = {
  onRunStart?: (ctx: {
    maxAttempts: number
    hasRules: boolean
    retry: RetryPolicy
  }) => void

  onAttemptStart?: (ctx: {
    attempt: number
    maxAttempts: number
    instructions: string
    repairs: Message[]
  }) => void

  onRawOutput?: (ctx: {
    attempt: number
    raw: string
  }) => void

  onCleanedOutput?: (ctx: {
    attempt: number
    cleaned: unknown
  }) => void

  onVerifySuccess?: (ctx: {
    attempt: number
    data: T
    durationMs: number
  }) => void

  onVerifyFailure?: (ctx: {
    attempt: number
    category: FailureCategory
    issues: string[]
    durationMs: number
  }) => void

  onRepairGenerated?: (ctx: {
    attempt: number
    category: FailureCategory
    repairMessage: string
  }) => void

  onRetryScheduled?: (ctx: {
    attempt: number
    nextAttempt: number
    category: FailureCategory
    delayMs: number
  }) => void

  onRunSuccess?: (ctx: {
    attempts: number
    data: T
    totalDurationMs: number
  }) => void

  onRunFailure?: (ctx: {
    attempts: number
    category?: FailureCategory
    message: string
    totalDurationMs: number
  }) => void
}

Engine primitives

Lower-level functions for advanced use cases. All are pure and side-effect-free.
FunctionSignatureDescription
clean(raw: string | null) => unknownExtract and normalize JSON from raw LLM output
verify(data: unknown, schema: ZodType<T>, rules?: Rule<T>[]) => ContractResult<T>Validate data against schema and rules. No LLM involved.
classify(raw: string, cleaned: unknown) => FailureCategoryCategorize a failed response
repair(detail: AttemptDetail, overrides?) => Message[] | falseGenerate repair messages for a failed attempt
instructions(schema: ZodType) => stringGenerate prompt text from a Zod schema
createConsoleLogger(options?) => ContractLogger<T>Create a logger that prints to console