/** * Interrupt Types for Human-in-the-Loop (HITL) Support * * TypeScript types for workflow interrupts that pause execution * and request user input before continuing. * * @module types/interrupt */ import type { ConfigSchema } from './index.js'; export type { InterruptState, IdleState, SubmittingState, ResolvedState, CancelledState, ErrorState, InterruptAction, SubmitAction, CancelAction, SuccessAction, FailureAction, RetryAction, ResetAction, TransitionResult } from './interruptState.js'; export { initialState, transition, isTerminalState, isSubmitting, hasError, canSubmit, getErrorMessage, getResolvedValue, toLegacyStatus } from './interruptState.js'; /** * Types of interrupts supported by the system * * - `confirmation`: Simple Yes/No prompt * - `choice`: Single or multiple option selection * - `text`: Free-form text input * - `form`: JSON Schema-based form */ export type InterruptType = 'confirmation' | 'choice' | 'text' | 'form' | 'review'; /** * Status of an interrupt request * * - `pending`: Awaiting user response * - `resolved`: User has provided a response * - `cancelled`: User or system cancelled the interrupt * - `expired`: Interrupt timed out without response */ export type InterruptStatus = 'pending' | 'resolved' | 'cancelled' | 'expired'; /** * Choice option for choice-type interrupts * * @example * ```typescript * const option: InterruptChoice = { * value: "high", * label: "High Priority", * description: "Process immediately" * }; * ``` */ export interface InterruptChoice { /** Unique value identifier for this option */ value: string; /** Display label for the option */ label: string; /** Optional description providing more context */ description?: string; } /** * Configuration for confirmation-type interrupts */ export interface ConfirmationConfig { /** The confirmation message/question to display */ message: string; /** Label for the confirm/yes button */ confirmLabel?: string; /** Label for the cancel/no button */ cancelLabel?: string; } /** * Configuration for choice-type interrupts */ export interface ChoiceConfig { /** The prompt message to display */ message: string; /** Available options to choose from */ options: InterruptChoice[]; /** Whether multiple selections are allowed */ multiple?: boolean; /** Minimum number of selections required (for multiple mode) */ minSelections?: number; /** Maximum number of selections allowed (for multiple mode) */ maxSelections?: number; } /** * Configuration for text-type interrupts */ export interface TextConfig { /** The prompt message to display */ message: string; /** Placeholder text for the input field */ placeholder?: string; /** Whether to show a multiline text area */ multiline?: boolean; /** Minimum text length required */ minLength?: number; /** Maximum text length allowed */ maxLength?: number; /** Default value to pre-fill */ defaultValue?: string; } /** * Configuration for form-type interrupts */ export interface FormConfig { /** The prompt message to display */ message: string; /** JSON Schema defining the form fields */ schema: ConfigSchema; /** Default values for form fields */ defaultValues?: Record; } /** * A single field change proposed for review * * @example * ```typescript * const change: ReviewChange = { * field: "title", * label: "Page Title", * original: "About Us", * proposed: "About Our Company" * }; * ``` */ export interface ReviewChange { /** Field identifier (machine key) */ field: string; /** Human-readable field label */ label: string; /** Original value before the proposed change */ original: unknown; /** Proposed new value */ proposed: unknown; } /** * Configuration for review-type interrupts * * Displays a list of proposed field changes for the user to * accept or reject individually before submitting. */ export interface ReviewConfig { /** The prompt message to display */ message: string; /** List of field changes to review */ changes: ReviewChange[]; /** Label for the "Accept All" button */ acceptAllLabel?: string; /** Label for the "Reject All" button */ rejectAllLabel?: string; /** Label for the submit button */ submitLabel?: string; } /** * Per-field decision in a review resolution */ export interface ReviewFieldDecision { /** Whether the proposed change was accepted */ accepted: boolean; /** The effective value (proposed if accepted, original if rejected) */ value: unknown; } /** * Resolution value for review-type interrupts * * Contains individual decisions for each field and a summary count. * * @example * ```typescript * const resolution: ReviewResolution = { * decisions: { * title: { accepted: true, value: "About Our Company" }, * meta_description: { accepted: false, value: "Learn about us" } * }, * summary: { accepted: 1, rejected: 1, total: 2 } * }; * ``` */ export interface ReviewResolution { /** Map of field identifier to the user's decision */ decisions: Record; /** Summary counts of accepted/rejected fields */ summary: { accepted: number; rejected: number; total: number; }; } /** * Union type for interrupt-specific configuration */ export type InterruptConfig = ConfirmationConfig | ChoiceConfig | TextConfig | FormConfig | ReviewConfig; /** * Core interrupt data structure * * Represents a pending or resolved interrupt request from the workflow. * Includes a state machine for tracking the interaction state. * * @example * ```typescript * const interrupt: Interrupt = { * id: "int-123", * type: "confirmation", * status: "pending", * message: "Send email to John?", * nodeId: "node-456", * executionId: "exec-789", * sessionId: "sess-abc", * createdAt: "2024-01-20T10:00:00Z", * allowCancel: true, * config: { * message: "Send email to John?", * confirmLabel: "Send", * cancelLabel: "Don't Send" * }, * state: { status: "idle" } * }; * ``` */ export interface Interrupt { /** Unique identifier for the interrupt */ id: string; /** Type of interrupt (confirmation, choice, text, form) */ type: InterruptType; /** Current status of the interrupt */ status: InterruptStatus; /** Primary message/prompt to display */ message: string; /** ID of the node that triggered the interrupt */ nodeId?: string; /** ID of the workflow execution */ executionId?: string; /** ID of the playground session (if applicable) */ sessionId?: string; /** ID of the pipeline (if applicable) */ pipelineId?: string; /** ID of the associated message in the chat flow */ messageId?: string; /** Timestamp when the interrupt was created (ISO 8601) */ createdAt: string; /** Timestamp when the interrupt was resolved (ISO 8601) */ resolvedAt?: string; /** Timestamp when the interrupt expires (ISO 8601) */ expiresAt?: string; /** Whether the user can cancel/dismiss this interrupt */ allowCancel: boolean; /** Type-specific configuration */ config: InterruptConfig; /** The user's response value (when resolved) */ responseValue?: unknown; /** Additional metadata from the backend */ metadata?: Record; } /** * Payload for resolving an interrupt * * @example * ```typescript * // Confirmation response * const resolution: InterruptResolution = { * value: true // or false * }; * * // Choice response (single) * const resolution: InterruptResolution = { * value: "option_a" * }; * * // Choice response (multiple) * const resolution: InterruptResolution = { * value: ["option_a", "option_b"] * }; * * // Text response * const resolution: InterruptResolution = { * value: "User entered text" * }; * * // Form response * const resolution: InterruptResolution = { * value: { name: "John", email: "john@example.com" } * }; * ``` */ export interface InterruptResolution { /** The user's response value */ value: unknown; } /** * API response for interrupt operations */ export interface InterruptApiResponse { /** Whether the request was successful */ success: boolean; /** Response data */ data?: T; /** Error message if unsuccessful */ error?: string; /** Human-readable message */ message?: string; } /** * Response type for listing interrupts */ export type InterruptListResponse = InterruptApiResponse; /** * Response type for single interrupt operations */ export type InterruptResponse = InterruptApiResponse; /** * Message metadata structure for interrupt detection * * When a message contains this metadata type, it indicates * an interrupt request that should be rendered inline. */ export interface InterruptMessageMetadata { /** Indicates this is an interrupt request */ type: 'interrupt_request'; /** The interrupt ID */ interrupt_id: string; /** Type of interrupt */ interrupt_type: InterruptType; /** JSON Schema for form-type interrupts */ schema?: ConfigSchema; /** Options for choice-type interrupts */ options?: InterruptChoice[]; /** Default value for pre-filling */ default_value?: unknown; /** Response value when interrupt has been resolved */ response_value?: unknown; /** Node ID that triggered the interrupt */ node_id?: string; /** Execution ID */ execution_id?: string; /** Whether cancel is allowed */ allow_cancel?: boolean; /** Labels for confirmation type */ confirm_label?: string; cancel_label?: string; /** Text input configuration */ placeholder?: string; multiline?: boolean; min_length?: number; max_length?: number; /** Choice configuration */ multiple?: boolean; min_selections?: number; max_selections?: number; /** Username of the person who resolved the interrupt */ resolvedByUserName?: string; /** User ID of the person who resolved the interrupt */ resolvedByUserId?: string; /** Review: list of field changes to review */ changes?: ReviewChange[]; /** Review: label for the "Accept All" button */ accept_all_label?: string; /** Review: label for the "Reject All" button */ reject_all_label?: string; /** Review: label for the submit button */ submit_label?: string; } /** * Type guard to check if message metadata indicates an interrupt * * @param metadata - Message metadata to check * @returns True if the metadata indicates an interrupt request */ export declare function isInterruptMetadata(metadata: Record | undefined): metadata is Record; /** * Safely extract interrupt metadata from a generic record * * @param metadata - The metadata record to extract from * @returns The interrupt metadata if valid, or null */ export declare function extractInterruptMetadata(metadata: Record | undefined): InterruptMessageMetadata | null; /** * Convert interrupt message metadata to a full Interrupt object * * @param metadata - The interrupt message metadata * @param messageId - The ID of the message containing the interrupt * @param content - The message content (used as the interrupt message) * @returns A fully populated Interrupt object */ export declare function metadataToInterrupt(metadata: InterruptMessageMetadata, messageId: string, content: string): Interrupt; /** * Configuration options for interrupt polling */ export interface InterruptPollingConfig { /** Whether to enable dedicated interrupt polling */ enabled: boolean; /** Polling interval in milliseconds */ interval: number; /** Maximum polling backoff interval in milliseconds */ maxBackoff: number; } /** * Default interrupt polling configuration */ export declare const defaultInterruptPollingConfig: InterruptPollingConfig;