← Back to Archive

Building ChatGpMe: AI Integration with Cloudflare Workers

I built ChatGpMe as an experiment to explore Cloudflare’s AI capabilities. Here’s a detailed look at how I implemented both text and image generation features.

Chat Implementation

The chat system uses streaming responses for a better user experience. Here’s the core implementation:

import { Ai } from '@cloudflare/ai';

export async function onRequest({ request, env }) {
  const model = "@cf/meta/llama-3.3-70b-instruct-fp8-fast";
  const { messages, prompt } = await request.json();
  
  const response = await env.AI.run(
    model,
    { messages, stream: true },
    { gateway: { id: 'martingpt', skipCache: true } }
  );

  const stream = response
    .pipeThrough(new TextDecoderStream())
    .pipeThrough(new SSEToStream())
    .pipeThrough(new TextEncoderStream());

  return new Response(stream, {
    headers: { 'content-type': 'application/x-ndjson' },
  });
}

Image Generation

I implemented image generation using the Flux model from Black Forest Labs, available through Cloudflare Workers AI:

export async function generateImage({ request, env }) {
  const { prompt } = await request.json();
  const gateway_id = "martingpt";

  const response = await env.AI.run(
    "@cf/black-forest-labs/flux-1-schnell",
    { prompt },
    { gateway: { id: gateway_id, skipCache: true } }
  );

  // Response includes base64 encoded image
  const dataURI = `data:image/jpeg;charset=utf-8;base64,${response.image}`;
  return Response.json({ dataURI });
}

Frontend Integration

The chat interface uses React with TypeScript for type safety:

interface ChatMessage {
  role: 'user' | 'assistant';
  content: string;
}

function ChatInterface() {
  const [messages, setMessages] = useState<ChatMessage[]>([]);
  const [isLoading, setIsLoading] = useState(false);

  async function handleSubmit(userMessage: string) {
    setIsLoading(true);
    try {
      const response = await fetch('/api/chat', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          messages: [...messages, { role: 'user', content: userMessage }]
        }),
      });

      const reader = response.body?.getReader();
      let accumulatedResponse = '';

      while (true) {
        const { done, value } = await reader?.read();
        if (done) break;
        
        const chunk = new TextDecoder().decode(value);
        accumulatedResponse += chunk;
        
        setMessages(prev => [
          ...prev.slice(0, -1),
          { role: 'assistant', content: accumulatedResponse }
        ]);
      }
    } finally {
      setIsLoading(false);
    }
  }

  return (
    // Chat interface JSX
  );
}

Cloudflare AI Gateway

The application uses Cloudflare’s AI Gateway, which provides several built-in features:

  • Automatic request caching at the edge
  • Built-in rate limiting protection
  • Request queueing and load balancing
  • Usage analytics and monitoring

This allows me to focus on the application logic while the infrastructure handles scaling and protection.

This post was written with AI assistance and reviewed by humans.