/** * Simple Chat WITHOUT Agents SDK * * This template shows how to build a chat interface using JUST the Vercel AI SDK * on Cloudflare Workers - no Agents SDK, no Durable Objects, no WebSockets. * * WHAT THIS PROVIDES: * - ✅ AI streaming responses (SSE) * - ✅ React hooks (useChat, useCompletion) * - ✅ Multi-provider support * - ✅ ~100 lines of code vs ~500+ with Agents SDK * * WHAT THIS DOESN'T PROVIDE: * - ❌ WebSocket bidirectional communication (only SSE one-way) * - ❌ Built-in state persistence (add D1/KV separately if needed) * - ❌ Durable Objects (single Worker handles all requests) * - ❌ Multi-agent coordination * * USE THIS WHEN: * - Building a basic chat interface * - SSE streaming is sufficient (most cases) * - No persistent state needed per user * - Want minimal complexity * * DON'T USE THIS WHEN: * - Need WebSocket bidirectional real-time * - Need stateful agent instances * - Building multi-agent systems * - Need scheduled tasks or workflows * * MIGRATION PATH: * If you discover later that you need WebSockets or Durable Objects state, * you can migrate to Agents SDK. Start simple, add complexity only when needed. */ // ============================================================================ // BACKEND: Cloudflare Worker with AI SDK // ============================================================================ import { Hono } from 'hono'; import { cors } from 'hono/cors'; import { streamText } from 'ai'; import { openai } from '@ai-sdk/openai'; interface Env { OPENAI_API_KEY: string; } const app = new Hono<{ Bindings: Env }>(); // Enable CORS for frontend app.use('*', cors()); // Chat endpoint - handles streaming responses app.post('/api/chat', async (c) => { const { messages } = await c.req.json(); // Validate input if (!Array.isArray(messages) || messages.length === 0) { return c.json({ error: 'Messages array required' }, 400); } // Stream AI response using Vercel AI SDK const result = streamText({ model: openai('gpt-4o-mini'), messages, system: 'You are a helpful assistant.', temperature: 0.7, maxTokens: 1000, }); // Return SSE stream (automatic streaming handled by AI SDK) return result.toTextStreamResponse(); }); // Optional: Add completion endpoint for non-chat use cases app.post('/api/completion', async (c) => { const { prompt } = await c.req.json(); const result = streamText({ model: openai('gpt-4o-mini'), prompt, }); return result.toTextStreamResponse(); }); export default app; /** * DEPLOYMENT: * * 1. Install dependencies: * npm install hono ai @ai-sdk/openai * * 2. Create wrangler.jsonc: * { * "name": "simple-chat", * "main": "src/worker.ts", * "compatibility_date": "2025-11-19", * "compatibility_flags": ["nodejs_compat"] * } * * 3. Set secrets: * npx wrangler secret put OPENAI_API_KEY * * 4. Deploy: * npx wrangler deploy * * That's it. No Durable Objects bindings, no migrations, no complexity. */ // ============================================================================ // FRONTEND: React Client with useChat Hook // ============================================================================ /** * Save this as: src/ChatPage.tsx * * ```typescript * import { useChat } from 'ai/react'; * * export function ChatPage() { * const { * messages, * input, * handleInputChange, * handleSubmit, * isLoading, * error * } = useChat({ * api: '/api/chat', * }); * * return ( *
{msg.content}
*