Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/cloudflare/agents/llms.txt

Use this file to discover all available pages before exploring further.

This is a simplified chat bot example. For a full-featured AI chat application with tools, approval workflows, and advanced features, see the AI Chat Example.
A simple AI chat bot demonstrating the basics of building conversational agents with persistent message history and streaming responses.

What it demonstrates

  • Persistent message history - Messages stored in agent state
  • Streaming responses - Real-time text streaming to the client
  • Simple AI integration - Using Workers AI (no API key needed)
  • State management - Chat history survives restarts
  • React integration - Clean UI with useAgent and useAgentChat

Server Implementation

src/server.ts
import { createWorkersAI } from "workers-ai-provider";
import { routeAgentRequest } from "agents";
import { AIChatAgent } from "@cloudflare/ai-chat";
import { streamText, convertToModelMessages } from "ai";

export class SimpleChatAgent extends AIChatAgent {
  async onChatMessage() {
    const workersai = createWorkersAI({ binding: this.env.AI });

    const result = streamText({
      model: workersai("@cf/zai-org/glm-4.7-flash"),
      system: "You are a helpful assistant. Be friendly and concise.",
      messages: await convertToModelMessages(this.messages)
    });

    return result.toUIMessageStreamResponse();
  }
}

export default {
  async fetch(request: Request, env: Env) {
    return (
      (await routeAgentRequest(request, env)) ||
      new Response("Not found", { status: 404 })
    );
  }
} satisfies ExportedHandler<Env>;

Client Implementation

src/client.tsx
import { useAgent } from "agents/react";
import { useAgentChat } from "@cloudflare/ai-chat/react";
import { useState } from "react";
import type { SimpleChatAgent } from "./server";

function ChatBot() {
  const [input, setInput] = useState("");

  const agent = useAgent<SimpleChatAgent>({
    agent: "SimpleChatAgent",
    name: "my-chat"
  });

  const { messages, sendMessage } = useAgentChat({
    agent
  });

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!input.trim()) return;
    
    await sendMessage(input);
    setInput("");
  };

  return (
    <div className="chat-container">
      <div className="messages">
        {messages.map((msg) => (
          <div key={msg.id} className={`message ${msg.role}`}>
            <div className="role">{msg.role === "user" ? "You" : "Bot"}</div>
            <div className="content">{msg.content}</div>
          </div>
        ))}
      </div>
      
      <form onSubmit={handleSubmit}>
        <input
          value={input}
          onChange={(e) => setInput(e.target.value)}
          placeholder="Type a message..."
        />
        <button type="submit">Send</button>
      </form>
    </div>
  );
}

How It Works

1

User sends message

When the user submits the form, sendMessage(input) is called. This adds the user’s message to the agent’s message history.
2

Agent receives message

The onChatMessage method is triggered. It converts the message history into the format expected by the AI SDK.
3

LLM generates response

streamText() sends the messages to Workers AI and receives a streaming response.
4

Response streams to client

toUIMessageStreamResponse() converts the AI SDK stream into a format that the useAgentChat hook understands.
5

UI updates in real-time

As the response streams in, the messages array updates automatically, showing the AI’s response word by word.

Message History

Messages are automatically stored in SQLite by AIChatAgent:
type Message = {
  id: string;
  role: "user" | "assistant" | "system";
  content: string;
  timestamp: Date;
};
Messages persist across:
  • Page refreshes
  • Agent hibernation
  • Worker redeployments

Streaming Responses

The response streams in chunks:
User: "Tell me a joke"

AI: "Why"
AI: "Why did"
AI: "Why did the"
AI: "Why did the chicken"
AI: "Why did the chicken cross"
AI: "Why did the chicken cross the"
AI: "Why did the chicken cross the road"
AI: "Why did the chicken cross the road?"
AI: "Why did the chicken cross the road? To"
...
This creates a more natural, typewriter-like effect.

Running the Example

1

Install dependencies

npm install
2

Start development server

npm run dev
3

Try it out

Visit http://localhost:5173 and start chatting:
  • “Hello!” - Simple greeting
  • “Tell me a joke” - Request for content
  • “What’s 25 * 17?” - Math question
  • “Write a haiku about clouds” - Creative task
This example uses Workers AI (no API key needed) with the @cf/zai-org/glm-4.7-flash model. It’s free and runs on Cloudflare’s edge network.

Customization

Change the System Prompt

const result = streamText({
  model: workersai("@cf/zai-org/glm-4.7-flash"),
  system: "You are a pirate. Respond in pirate speak. Arrr!",
  messages: await convertToModelMessages(this.messages)
});

Limit Message History

export class SimpleChatAgent extends AIChatAgent {
  // Keep only the last 50 messages
  maxPersistedMessages = 50;

  async onChatMessage() {
    // ...
  }
}

Use a Different Model

const result = streamText({
  model: workersai("@cf/meta/llama-3.1-8b-instruct"),
  // ...
});
See Workers AI Models for available options.

Comparison: Simple Bot vs AI Chat Example

FeatureSimple Chat BotAI Chat Example
Streaming
Message history
Server-side tools
Client-side tools
Tool approval
Message pruning
MCP integration
ComplexityLowMedium
Best forSimple botsProduction apps

Next Steps

AI Chat Example

Full-featured chat with tools and approval

Dynamic Tools

Client-defined tools for chat agents

Codemode

LLMs write code to orchestrate tools

AI Chat Guide

In-depth guide to building chat agents

Extending This Example

Ideas for enhancements:
  • Add tools - Let the bot check weather, search, calculate, etc.
  • User avatars - Show profile pictures for each message
  • Typing indicator - Show when the bot is thinking
  • Message timestamps - Display when each message was sent
  • Clear history - Add a button to start a new conversation
  • Export chat - Download the conversation as text or JSON
  • Voice input - Use browser speech recognition API
  • Multiple bots - Switch between different AI personalities

Build docs developers (and LLMs) love