Image Generation Chat

    Build an image generation interface with multi-image references for image-to-image workflows.

    Basic Setup

    The simplest way to add image generation — just enable attachments and let the agent handle it.

    tsx
    <AgentChat
      agentId="image-gen-agent"
      enableAttachments
      showToolCalls
      onImageClick={(url) => window.open(url, '_blank')}
      welcomeMessage="Upload reference images and describe what you'd like to create."
    />

    Custom Image Chat

    For more control, use the hooks directly to build a custom interface with a reference image panel.

    tsx
    import { useAgentChat, useFileAttachments, FileDropZone } from '@cadraos/sdk/chat';
    import { useState } from 'react';
    
    function ImageChat() {
      const [referenceImages, setReferenceImages] = useState<string[]>([]);
    
      const attachments = useFileAttachments({
        onUpload: async (file, metadata) => {
          const res = await fetch('/api/attachments/upload', {
            method: 'POST',
            body: JSON.stringify(metadata),
          });
          const { uuid, uploadUrl } = await res.json();
          // Upload to S3
          await fetch(uploadUrl, { method: 'PUT', body: file });
          // Add preview
          setReferenceImages(prev => [...prev, URL.createObjectURL(file)]);
          return { uuid, uploadUrl };
        },
        onConfirmUpload: async (uuid) => {
          await fetch(`/api/attachments/${uuid}/confirm`, { method: 'POST' });
        },
        accept: 'image/*',
        maxFiles: 5,
      });
    
      const chat = useAgentChat({
        agentId: 'image-gen-agent',
        onSend: (message) => {
          const uuids = attachments.getReadyUuids();
          return { attachmentIds: uuids };
        },
      });
    
      return (
        <FileDropZone {...attachments.dropZoneProps}>
          <div style={{ display: 'flex', height: '100vh' }}>
            {/* Reference panel */}
            <div style={{ width: 300, borderRight: '1px solid #333', padding: 16 }}>
              <h3>Reference Images</h3>
              <div style={{ display: 'grid', gap: 8 }}>
                {referenceImages.map((url, i) => (
                  <img key={i} src={url} style={{ width: '100%', borderRadius: 8 }} />
                ))}
              </div>
              {attachments.files.length > 0 && (
                <p>{attachments.files.length} file(s) ready</p>
              )}
            </div>
    
            {/* Chat area */}
            <div style={{ flex: 1 }}>
              {/* Render messages and input using chat state */}
            </div>
          </div>
        </FileDropZone>
      );
    }

    Server-Side Image Generation

    typescript
    // Upload reference images first
    const uploadRes = await fetch('/api/attachments/upload', {
      method: 'POST',
      body: JSON.stringify({ filename: 'ref.png', mimeType: 'image/png', sizeBytes: 1024 }),
    });
    const { uuid, uploadUrl } = await uploadRes.json();
    await fetch(uploadUrl, { method: 'PUT', body: imageBuffer });
    await fetch(`/api/attachments/${uuid}/confirm`, { method: 'POST' });
    
    // Execute with reference images
    const result = await client.agents.executeSync('image-gen-agent', {
      task: 'Create a variation of this image in watercolor style',
      attachmentIds: [uuid],
    });
    
    // Images appear in tool results
    result.toolResults?.forEach(tr => {
      if (tr.images) {
        tr.images.forEach(img => console.log('Generated:', img.url));
      }
    });