/** * Output Text Computation * * Converts a ContentItem array into a single string for test assertions. * Joins all text content with newlines and trims whitespace. * * ## Strategy * - Extract text from text-type content items * - Extract text from resource items that have a text field * - Skip image items (no text representation by default) * - Join multiple text items with newlines * - Trim leading/trailing whitespace from result * * ## Edge Cases * - Empty content array → empty string * - Content with no text items → empty string * - Null/undefined text values → skipped * - Whitespace-only items → preserved but trimmed at end * * @example Basic text * ```typescript * const content = [{ type: "text", text: "Hello" }]; * computeOutputText(content); // "Hello" * ``` * * @example Multiple text items * ```typescript * const content = [ * { type: "text", text: "Hello" }, * { type: "text", text: "World" } * ]; * computeOutputText(content); // "Hello\nWorld" * ``` * * @example Mixed content with images * ```typescript * const content = [ * { type: "text", text: "Image:" }, * { type: "image", data: "...", mimeType: "image/png" }, * { type: "text", text: "Done" } * ]; * computeOutputText(content); // "Image:\nDone" * ``` * * @example Resource with text * ```typescript * const content = [ * { type: "text", text: "File contents:" }, * { type: "resource", data: "file.txt", text: "Hello from file" } * ]; * computeOutputText(content); // "File contents:\nHello from file" * ``` * * @module @wavespec/kit/response */ import type { ContentItem } from "@wavespec/types"; /** * Compute output_text from content array * * Joins all text content with newlines. Ignores images unless they have * text representations. Trims whitespace from the final result. * * @param content - Array of content items from response * @returns Single string for test assertions * * @example * ```typescript * const content = [ * { type: "text", text: "Hello" }, * { type: "text", text: "World" } * ]; * computeOutputText(content); // "Hello\nWorld" * ``` */ export function computeOutputText(content: ContentItem[]): string { const textParts: string[] = []; for (const item of content) { // Handle text items if (item.type === "text" && item.text != null) { textParts.push(item.text); continue; } // Handle resource items with text field if ( item.type === "resource" && item.text != null ) { textParts.push(item.text); continue; } // Skip images and other types without explicit text representation } // Join with newlines and trim return textParts.join("\n").trim(); }