import React, { useMemo } from 'react'; import { Image as ImageIcon } from 'lucide-react-native'; import { flattenToolCall } from '../../features/conversation/agentPhase'; import type { SuperagentToolRendererProps } from '../../types'; import { getGeneratedImages, getGeneratedImagesHeader } from '../mediaWidgetUtils'; import { ImageGrid, type ImageGridItem } from '../primitives/ImageGrid'; import { ToolWidgetRow } from '../primitives/ToolWidgetRow'; /** * generate_image (and the game-asset variants) — native port of the web * GeneratedImagesGroup batch card: a header with live ready/total progress, * then a thumbnail grid of the resolved images with a tap-to-zoom lightbox. * The web routes even a single generate_image through the same grouped card * (applyImageGrouping), so this one widget covers both the single GenerateImage * row and the grouped strip; grouping happens in createToolChunks via * groupedToolNames. */ export function GeneratedImagesWidget({ toolCall }: SuperagentToolRendererProps) { const calls = useMemo(() => flattenToolCall(toolCall), [toolCall]); const result = useMemo(() => getGeneratedImages(calls), [calls]); if (result.total === 0) return null; // Only ready items render as thumbnails — a failed call can still carry a // URL (errored after resolving) that must not show as a successful image. const images: ImageGridItem[] = result.items .filter((item) => item.status === 'ready' && item.url) .map((item) => ({ label: item.label || undefined, url: item.url as string })); // Failures surface in the header copy ("… · 2 failed"); the icon goes red // only when the whole batch failed. const status = !result.allDone ? 'running' : result.readyCount === 0 ? 'error' : 'success'; return ( 0} icon={ImageIcon} status={status} title={getGeneratedImagesHeader(result)} > ); }