/** * Response Helper Types * * Type definitions for response normalization helpers used by adapters. * These types enable building a schema-driven response transformation system * that can handle any protocol format (HTTP, MCP, OpenAI, etc.). * * @module @wavespec/kit/response/types */ import type { ContentItem } from "@wavespec/types"; /** * Normalized response format * * The universal output of response normalization. All adapters should * produce this format from their protocol-specific responses. * * ## Fields * - `content`: Array of ContentItems (text, image, resource) * - `output_text`: Concatenated text from all content items * - `isError`: Whether this response represents an error * * @example * ```typescript * const normalized: NormalizedResponse = { * content: [{ type: "text", text: "Hello world" }], * output_text: "Hello world", * isError: false * }; * ``` */ export interface NormalizedResponse { /** * Array of content items extracted from the response */ content: ContentItem[]; /** * Concatenated text from all text content items * Used for assertions and error messages */ output_text: string; /** * Flag indicating if this response represents an error condition */ isError: boolean; } /** * Content builder function type * * Creates a ContentItem from a value. Used to convert protocol-specific * content items to the universal ContentItem format. * * @template T - The input type (protocol-specific content item) * @param item - The item to convert * @returns ContentItem for the input, or null to filter it out * * @example * ```typescript * const textBuilder: ContentBuilder = (text: string) => ({ * type: "text", * text * }); * ``` */ export type ContentBuilder = (item: T) => ContentItem | null; /** * Output text computer function type * * Computes output_text from a ContentItem array. Typically concatenates * text from all text content items. * * @param content - Array of content items * @returns Concatenated text output * * @example * ```typescript * const computeOutputText: OutputTextComputer = (content: ContentItem[]) => { * return content * .filter((item) => item.type === "text" && item.text) * .map((item) => item.text!) * .join(""); * }; * ``` */ export type OutputTextComputer = (content: ContentItem[]) => string; /** * Path extractor for nested object access * * Flexible way to specify how to extract a value from nested objects. * Can be a string path, array of path segments, or custom function. * * @template T - The object type being extracted from * * @example String path * ```typescript * const path: PathExtractor = "data.items"; * // Extracts: obj.data.items * ``` * * @example Array of segments * ```typescript * const path: PathExtractor = ["messages", "0", "content"]; * // Extracts: obj.messages[0].content * ``` * * @example Custom function * ```typescript * const path: PathExtractor = (data) => { * const allContent = []; * for (const msg of data.messages) { * allContent.push(...msg.content); * } * return allContent; * }; * ``` */ export type PathExtractor = string | string[] | ((data: T) => unknown); /** * Response normalization configuration schema * * Declarative schema that defines how to extract and transform content * from a protocol-specific response format. Eliminates boilerplate by * separating the transformation logic from the protocol details. * * @template T - The protocol response type * * @example MCP Tool Response * ```typescript * const schema: ResponseNormalizerConfig = { * contentPath: "content", * // Extract directly from result.content * }; * ``` * * @example MCP Prompt Response with flattening * ```typescript * const schema: ResponseNormalizerConfig = { * contentPath: (data) => { * const allContent = []; * for (const message of data.messages) { * if (Array.isArray(message.content)) { * allContent.push(...message.content); * } else { * allContent.push(message.content); * } * } * return allContent; * }, * flattenArrays: true, * }; * ``` * * @example HTTP Response with error handling * ```typescript * const schema: ResponseNormalizerConfig = { * contentPath: "data", * errorPath: "error", * errorExtractor: (data) => data.status >= 400, * itemNormalizer: (item) => ({ * type: "text", * text: JSON.stringify(item, null, 2) * }) * }; * ``` */ export interface ResponseNormalizerConfig { /** * Path to content items in the response * * Can be: * - String: dot-notation path (e.g., "data.items") * - Array: path segments (e.g., ["messages", "0", "content"]) * - Function: custom extraction logic */ contentPath: PathExtractor; /** * Optional: Flatten nested arrays * * If true, recursively flattens array nesting. * Useful when response has [[item1], [item2]] and you want [item1, item2]. * * @default false */ flattenArrays?: boolean; /** * Optional: Custom item normalizer function * * If not provided, uses default normalization that handles common * protocol types (text, image, audio, resource, primitives, objects). * Override to customize item transformation logic. * * @default defaultItemNormalizer */ itemNormalizer?: ContentBuilder; /** * Optional: Path to error indicator in response * * Can be a path to an error field or array indicating error condition. * If present and truthy, isError will be set to true. * * @example * ```typescript * errorPath: "error" // response.error is truthy * errorPath: "errors" // response.errors is truthy (error array) * ``` */ errorPath?: PathExtractor; /** * Optional: Custom error extraction function * * If provided, called to determine if response is an error. * Allows custom logic like checking status codes or error types. * * @example * ```typescript * errorExtractor: (data) => data.status >= 400 * errorExtractor: (data) => data.errorCode !== null * ``` */ errorExtractor?: (data: T) => boolean; } /** * Protocol-specific content item type * * Generic type for a protocol's native content item format. * Different protocols have different content representations: * - MCP: `{ type: "text" | "image" | "audio" | "resource", ...}` * - HTTP: String, Buffer, or parsed JSON * - OpenAI: Various message/response formats * * @template T - The protocol's content item type */ export type ProtocolContentItem = T; /** * Response transformer function * * Takes a protocol-specific response and transforms it into a NormalizedResponse. * The main entry point for response normalization in each adapter. * * @template T - The protocol response type * @param response - Protocol-specific response * @returns Normalized response with ContentItem[], output_text, isError * * @example * ```typescript * const normalizer: ResponseTransformer = (response) => { * const content = normalizeHttpContent(response.data); * return { * content, * output_text: computeOutputText(content), * isError: response.status >= 400 * }; * }; * ``` */ export type ResponseTransformer = (response: T) => NormalizedResponse; //# sourceMappingURL=types.d.ts.map