This is a production-ready Cloudflare Agent implementation using the Cloudflare Agents SDK, Durable Objects, and TypeScript. It demonstrates all the required features including persistent state, real-time streaming, LLM integration, scheduled tasks, human-in-the-loop flows, web browsing, and optional RAG with Vectorize.
✅ Persistent Per-Agent State: Uses Durable Object's built-in SQL for conversation history and metadata storage ✅ Real-time Client Streaming: WebSocket implementation for live communication ✅ LLM Integration: Cloudflare AI SDK integration with OpenAI models ✅ Scheduled Background Tasks: Nightly cleanup and maintenance tasks ✅ Human-in-the-Loop Flow: Review system for sensitive messages ✅ Web Browsing Tool: Fetch and extract content from URLs ✅ Vectorize-backed RAG: Optional semantic retrieval with toggle ✅ Typesafe & Testable: Strict TypeScript with unit tests ✅ Deployable: Wrangler configuration for easy deployment
# Bootstrap from starter
npm create cloudflare@latest -- --template=cloudflare/agents-starter
# Install dependencies
npm install
# Set up environment variables
echo "OPENAI_API_KEY=your_openai_api_key_here" > .dev.vars
# Run locally
npm run start
# Deploy
npx wrangler@latest deploy├── src/
│ ├── MyAgent.ts # Main Agent class implementation
│ ├── server.ts # Worker entry point and HTTP handlers
│ ├── websocket.ts # WebSocket handling for real-time streaming
│ ├── tools.ts # AI tools (browse web, RAG search)
│ └── utils.ts # Utility functions
├── demo/
│ └── index.html # Demo client for testing WebSocket connection
├── tests/
│ ├── index.test.ts # Main test file
│ ├── MyAgent.test.ts # Unit tests for Agent logic
│ └── MyAgentDatabase.test.ts # Database schema tests
├── wrangler.jsonc # Wrangler configuration with DO bindings
├── package.json # Dependencies and scripts
├── tsconfig.json # TypeScript configuration
└── README.md # This file
The MyAgent class extends Cloudflare's Agent and implements all required functionality:
- init(): Initializes database tables and agent state
- handleMessage(): Processes incoming messages with AI or flags for review
- summarizeConversation(): Generates conversation summaries using LLM
- scheduledTask(): Runs periodic cleanup and maintenance
- approveReview(): Handles human approval for sensitive messages
- browseWeb(): Fetches and extracts content from URLs
- ragSearch(): Performs semantic search with Vectorize
The implementation includes WebSocket support for real-time communication between clients and the agent. The WebSocketHandler class manages connections and message routing.
Uses Durable Object's built-in SQL database for:
- Conversation history storage
- Pending review items
- Agent state management
Messages containing "sensitive" or "important" keywords, or every 5th message, are flagged for human review. The system provides HTTP endpoints to:
- List pending reviews
- Approve or reject messages
The agent can fetch content from URLs with:
- Environment variable toggle (
BROWSING_ENABLED) - Simple HTML text extraction
- Error handling and length limits
Semantic search integration with:
- Environment variable toggle (
VECTORIZE_ENABLED) - Mock implementation for demonstration
- Easy replacement with actual Vectorize calls
Create a .dev.vars file for local development:
OPENAI_API_KEY=your_openai_api_key_here
BROWSING_ENABLED=true
VECTORIZE_ENABLED=trueFor production, use Wrangler secrets:
npx wrangler secret put OPENAI_API_KEYRun unit tests with:
npm run testTests cover:
- Agent initialization
- Message handling
- Conversation summarization
- State management
- Database schema validation
-
Set up secrets:
npx wrangler secret put OPENAI_API_KEY
-
Deploy:
npx wrangler@latest deploy
POST /api/approve-review- Approve/reject pending reviewsGET /api/pending-reviews- List pending reviewsPOST /api/trigger-scheduled-task- Manually trigger scheduled tasks
- API keys stored as secrets, never in code
- Web browsing has environment toggle for security
- Human review for sensitive operations
- Input validation and error handling
- Deployment fails: Verify Wrangler configuration matches class names
- WebSocket issues: Check CORS settings and connection URLs
- AI errors: Ensure API key is set and valid
- SQL errors: Verify database schema and migrations
To extend functionality:
- Add new tools in tools.ts
- Implement new methods in MyAgent.ts
- Add new endpoints in server.ts
- Update tests in MyAgent.test.ts
MIT