"use client"; import { ToolUIPart } from "ai"; import equal from "lib/equal"; import { cn } from "lib/utils"; import { ImagesIcon } from "lucide-react"; import { memo, useMemo } from "react"; import { TextShimmer } from "ui/text-shimmer"; import LetterGlitch from "ui/letter-glitch"; interface ImageGeneratorToolInvocationProps { part: ToolUIPart; } interface ImageGenerationResult { images: { url: string; mimeType?: string; }[]; mode?: "create" | "edit" | "composite"; model: string; } function PureImageGeneratorToolInvocation({ part, }: ImageGeneratorToolInvocationProps) { const isGenerating = useMemo(() => { return !part.state.startsWith("output"); }, [part.state]); const result = useMemo(() => { if (!part.state.startsWith("output")) return null; return part.output as ImageGenerationResult; }, [part.state, part.output]); const images = useMemo(() => { return result?.images || []; }, [result]); const mode = useMemo(() => { return result?.mode || "create"; }, [result]); const hasError = useMemo(() => { return ( part.state === "output-error" || (part.state === "output-available" && result?.images.length === 0) ); }, [part.state, result]); // Get mode-specific text const getModeText = (mode: string) => { switch (mode) { case "edit": return "Editing image..."; case "composite": return "Compositing images..."; default: return "Generating image..."; } }; const getModeHeader = (mode: string) => { switch (mode) { case "edit": return "Image edited"; case "composite": return "Images composited"; default: return "Image generated"; } }; // Simple loading state like web-search if (isGenerating) { return (
Image generation may take up to 1 minute.