/** * VCR Helper Type Definitions * * Type definitions for VCR (Video Cassette Recorder) style request extraction. * Enables adapters to record and replay test interactions with external systems. * * @module @wavespec/kit/vcr */ import type { ContentItem } from "@wavespec/types"; // Re-export VCR types from adapter-types (canonical location) // New code should import directly from @wavespec/types/vcr export type { RequestData, RequestExtractor } from "@wavespec/types/vcr"; // Import RequestData for use in the deprecated OperationData alias import type { RequestData } from "@wavespec/types/vcr"; /** * Extracted operation data for cassette recording * * @deprecated Use RequestData from @wavespec/types/vcr instead. * This type is kept for backward compatibility and is now an alias. * * Represents a normalized request extracted from a test specification. * Used by the VCR system to record and replay operations without * calling external services. * * ## Migration * ```typescript * // Old * import type { OperationData } from "@wavespec/kit/vcr"; * * // New * import type { RequestData } from "@wavespec/types/vcr"; * ``` * * @see RequestData for the canonical type */ export type OperationData = RequestData; // RequestExtractor is now exported from @wavespec/types/vcr (see re-export above) /** * Extractor Configuration Options * * Configuration for customizing request extraction behavior. * * @example * ```typescript * const config: ExtractorConfig = { * includeHeaders: ["Authorization", "Content-Type"], * excludeFields: ["timestamp", "request_id"], * normalizeKeys: true, * strictMode: false * }; * ``` */ export interface ExtractorConfig { /** * Headers to include in extracted request data * * By default, most extractors include only essential headers. * This option allows specifying additional headers to capture. * * @default undefined (use adapter default) * @example ["Authorization", "X-API-Key", "User-Agent"] */ includeHeaders?: string[]; /** * Headers to exclude from extracted request data * * Use this to filter out sensitive headers that shouldn't be recorded. * Case-insensitive matching. * * @default undefined (no exclusions) * @example ["Authorization", "Cookie", "X-API-Key"] */ excludeHeaders?: string[]; /** * Fields to exclude from extracted data * * Use this to filter out non-deterministic or sensitive fields * that shouldn't be used for cassette matching. * * @default undefined (no exclusions) * @example ["timestamp", "request_id", "correlation_id"] */ excludeFields?: string[]; /** * Whether to normalize field names/keys * * If true, converts field names to a consistent format (e.g., lowercase). * Useful for adapters that have inconsistent field naming. * * @default false */ normalizeKeys?: boolean; /** * Strict mode validation * * If true, throws errors for missing required fields instead of * silently ignoring them. Useful for development/debugging. * * @default false */ strictMode?: boolean; } /** * Cassette format for stored interactions * * Represents a stored recording of a request/response pair. * Used by the replay system to match incoming requests and * provide recorded responses. * * @example * ```typescript * const cassette: Cassette = { * version: "1.0", * meta: { adapter: { name: "http", version: "0.1.0" } }, * recorded_at: "2025-11-06T10:00:00Z", * interactions: [ * { * match_key: "abc123...", * request: { operation: "get", data: {...} }, * response: { content: [...], isError: false }, * duration_ms: 145 * } * ] * }; * ``` */ export interface Cassette { /** * Cassette format version * * Used for migration and compatibility checking. * Format: "major.minor" (e.g., "1.0") */ version: string; /** * Metadata about this cassette */ meta: CassetteMetadata; /** * When this cassette was recorded * * ISO-8601 format string (e.g., "2025-11-06T10:30:45Z") */ recorded_at: string; /** * Array of recorded interactions * * Each interaction is a single request/response pair captured * during recording. Order matters for stateful adapters. */ interactions: Interaction[]; } /** * Cassette metadata */ export interface CassetteMetadata { /** * Adapter information */ adapter: { /** Adapter name (e.g., "mcp", "http", "openai-agents") */ name: string; /** Adapter version (e.g., "0.1.0") */ version: string; }; /** * Server fingerprint (SHA-256 hash of server config) * * Used to detect when cassettes are recorded for a different server * configuration. Helps catch issues like: * - Different API versions * - Different servers * - Different configurations */ server_fingerprint: string; } /** * Recorded interaction * * A single request/response pair captured during recording. */ export interface Interaction { /** * Unique match key for this interaction * * SHA-256 hash of request data, used to quickly find matching * cassettes during replay. Enables deterministic matching * without re-hashing on every lookup. */ match_key: string; /** * Recorded request data */ request: OperationData; /** * Recorded response data */ response: ResponseData; /** * Duration in milliseconds * * Time taken to execute the operation. Used for replay timing * and performance analysis. */ duration_ms: number; } /** * Response data stored in cassette * * Normalized representation of a service response. */ export interface ResponseData { /** * Response content items * * Normalized ContentItem array from adapter response normalization. */ content: ContentItem[]; /** * Whether this response represents an error */ isError: boolean; /** * Computed output text * * Text content extracted from the response, used for assertions. * Computed by concatenating all text ContentItems. */ output_text?: string; }