///
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,
};
},
);