/// import { Cell, computed, generateText, ifElse, ImageData, NAME, pattern, UI, VNode, } from "commontools"; /** * Image Chat - Simple image upload with LLM analysis */ type ImageChatInput = { systemPrompt?: string; model?: string; }; type ImageChatOutput = { images: Cell; prompt: Cell; response: string | undefined; pending: boolean | undefined; ui: VNode; }; export default pattern( ({ systemPrompt, model }) => { const images = Cell.of([]); const prompt = Cell.of(""); // Build content parts array with text and images const contentParts = computed(() => { const parts: Array< { type: "text"; text: string } | { type: "image"; image: string } > = []; if (prompt.get()) { parts.push({ type: "text", text: prompt.get() }); } for (const img of images.get() || []) { parts.push({ type: "image", image: img.data }); } return parts; }); // Generate text from the content parts const { result, pending, requestHash: _requestHash } = generateText({ system: computed(() => systemPrompt || "You are a helpful assistant that can analyze images. Describe what you see." ), prompt: contentParts, model: computed(() => model || "anthropic:claude-sonnet-4-5"), }); const ui = ( Image Chat {/* Image Upload */} Upload Images {/* Prompt Input */} Your Question {/* Response */} {ifElse( pending,
Analyzing...
, ifElse( result, Response
{result}
, null, ), )}
); return { [NAME]: "Image Chat", [UI]: ui, images, prompt, response: result, pending, ui, }; }, );