diff --git a/docs/swarms_cloud/cloudflare_workers.md b/docs/swarms_cloud/cloudflare_workers.md
index 085ca78b..ad73cce0 100644
--- a/docs/swarms_cloud/cloudflare_workers.md
+++ b/docs/swarms_cloud/cloudflare_workers.md
@@ -1,111 +1,176 @@
-# Cloudflare Workers with Swarms: Automated Cron Job Agents
+# Cloudflare Workers with Swarms: Production AI Agents
-Deploy scheduled AI agents on Cloudflare's global edge network for automated stock analysis and healthcare monitoring. This guide focuses on cron job agents that run automatically at scheduled intervals.
+Deploy AI agents on Cloudflare's edge network with automatic cron scheduling and real-time data integration. This guide shows a production-ready implementation with both HTTP endpoints and scheduled triggers.
-## Overview
+## Architecture Overview
-Cloudflare Workers with cron triggers enable automated agent execution for:
-- **Stock Market Analysis**: Daily market reports and trading insights
-- **Healthcare Monitoring**: Patient data analysis and alerts
-- **Automated Reporting**: Scheduled business intelligence
-- **Global Deployment**: Edge computing with zero cold starts
+The Cloudflare Workers pattern uses two main handlers:
+- **`fetch()`**: HTTP requests for testing and manual triggers
+- **`scheduled()`**: Cron jobs for automated execution
+
+```javascript
+export default {
+ // HTTP handler for manual testing
+ async fetch(request, env, ctx) {
+ // Handle web interface and API endpoints
+ },
+
+ // Cron handler for scheduled execution
+ async scheduled(event, env, ctx) {
+ ctx.waitUntil(handleStockAnalysis(event, env));
+ }
+};
+```
## Quick Setup
### 1. Create Worker Project
```bash
-npx create-cloudflare stock-agent worker
+npm create cloudflare@latest stock-agent
cd stock-agent
```
### 2. Configure Cron Schedule
-Edit `wrangler.toml`:
-
-```toml
-name = "stock-analysis-agent"
-main = "src/index.js"
-compatibility_date = "2024-01-01"
-
-[env.production.vars]
-SWARMS_API_KEY = "your-api-key-here"
-SLACK_WEBHOOK_URL = "optional-slack-webhook"
-
-# Stock market analysis - after market close
-[[env.production.triggers.crons]]
-cron = "0 21 * * MON-FRI" # 9 PM UTC (4 PM EST)
-
-# Healthcare monitoring - every 4 hours
-[[env.production.triggers.crons]]
-cron = "0 */4 * * *"
+Edit `wrangler.jsonc`:
+
+```jsonc
+{
+ "$schema": "node_modules/wrangler/config-schema.json",
+ "name": "stock-agent",
+ "main": "src/index.js",
+ "compatibility_date": "2025-08-03",
+ "observability": {
+ "enabled": true
+ },
+ "triggers": {
+ "crons": [
+ "0 */3 * * *" // Every 3 hours
+ ]
+ },
+ "vars": {
+ "SWARMS_API_KEY": "your-api-key"
+ }
+}
```
-## Stock Market Analysis Agent
+## Complete Minimal Implementation
-Automated daily stock analysis after market close:
+Create `src/index.js`:
```javascript
export default {
- // Cron job handler - runs automatically
+ // HTTP handler - provides web interface and manual triggers
+ async fetch(request, env, ctx) {
+ const url = new URL(request.url);
+
+ // Web interface for testing
+ if (url.pathname === '/') {
+ return new Response(`
+
+
+
+ Stock Analysis Agent
+
+
+
+ 📈 Stock Analysis Agent
+ Status: Online ✅
+
+
+
+
+
+
+
+ `, {
+ headers: { 'Content-Type': 'text/html' }
+ });
+ }
+
+ // Manual trigger endpoint
+ if (url.pathname === '/trigger') {
+ try {
+ const result = await handleStockAnalysis(null, env);
+ return new Response(JSON.stringify({
+ message: 'Analysis triggered',
+ timestamp: new Date().toISOString(),
+ result
+ }), {
+ headers: { 'Content-Type': 'application/json' }
+ });
+ } catch (error) {
+ return new Response(JSON.stringify({
+ error: error.message
+ }), {
+ status: 500,
+ headers: { 'Content-Type': 'application/json' }
+ });
+ }
+ }
+
+ return new Response('Not Found', { status: 404 });
+ },
+
+ // Cron handler - runs automatically on schedule
async scheduled(event, env, ctx) {
ctx.waitUntil(handleStockAnalysis(event, env));
}
};
+// Main analysis function used by both HTTP and cron triggers
async function handleStockAnalysis(event, env) {
+ console.log('🚀 Starting stock analysis...');
+
try {
- // Step 1: Fetch real market data from multiple sources
- const marketData = await fetchMarketData(env);
+ // Step 1: Fetch real market data (using Yahoo Finance - no API key needed)
+ const marketData = await fetchMarketData();
- // Step 2: Get market news
- const marketNews = await fetchMarketNews(env);
+ // Check if we got valid data
+ const validSymbols = Object.keys(marketData).filter(symbol => !marketData[symbol].error);
+ if (validSymbols.length === 0) {
+ throw new Error('No valid market data retrieved');
+ }
- // Step 3: Send real data to Swarms agents for analysis
+ // Step 2: Send to Swarms AI agents
const swarmConfig = {
- name: "Real-Time Stock Analysis",
- description: "Live market data analysis with AI agents",
+ name: "Stock Analysis",
+ description: "Real-time market analysis",
agents: [
{
agent_name: "Technical Analyst",
- system_prompt: `You are a professional technical analyst. Analyze the provided real market data:
- - Calculate key technical indicators (RSI, MACD, Moving Averages)
- - Identify support and resistance levels
- - Determine market trends and momentum
- - Provide trading signals and price targets
- Format your analysis professionally with specific price levels.`,
+ system_prompt: \`Analyze the provided stock data:
+ - Identify trends and key levels
+ - Provide trading signals
+ - Calculate technical indicators
+ Format analysis professionally.\`,
model_name: "gpt-4o-mini",
- max_tokens: 3000,
+ max_tokens: 1500,
temperature: 0.2
- },
- {
- agent_name: "Fundamental Analyst",
- system_prompt: `You are a fundamental market analyst. Using the provided market news and data:
- - Analyze earnings impact and company fundamentals
- - Evaluate economic indicators and Fed policy effects
- - Assess sector rotation and market sentiment
- - Identify value opportunities and risks
- Provide investment recommendations with risk assessment.`,
- model_name: "gpt-4o-mini",
- max_tokens: 3000,
- temperature: 0.3
}
],
- swarm_type: "ConcurrentWorkflow",
- task: `Analyze the following real market data and news:
-
-MARKET DATA:
-${JSON.stringify(marketData, null, 2)}
-
-MARKET NEWS:
-${marketNews}
-
-Provide comprehensive analysis with:
-1. Technical analysis with key levels
-2. Fundamental analysis with catalysts
-3. Trading recommendations
-4. Risk assessment
-5. Tomorrow's key levels to watch`,
+ swarm_type: "SequentialWorkflow",
+ task: \`Analyze this market data: \\${JSON.stringify(marketData, null, 2)}\`,
max_loops: 1
};
@@ -118,370 +183,153 @@ Provide comprehensive analysis with:
body: JSON.stringify(swarmConfig)
});
- const result = await response.json();
-
- if (response.ok) {
- console.log('✅ Real-time stock analysis completed');
- console.log('💰 Cost:', result.metadata?.billing_info?.total_cost);
-
- // Send email directly
- await sendEmailReport(env, result.output, marketData);
+ if (!response.ok) {
+ throw new Error(\`Swarms API error: \\${response.status}\`);
}
+
+ const result = await response.json();
+ console.log('✅ Analysis completed');
+
+ return {
+ success: true,
+ analysis: result.output,
+ symbolsAnalyzed: validSymbols.length,
+ cost: result.usage?.billing_info?.total_cost
+ };
+
} catch (error) {
- console.error('❌ Real-time stock analysis failed:', error);
+ console.error('❌ Analysis failed:', error.message);
+ return {
+ success: false,
+ error: error.message
+ };
}
}
-// Fetch real market data from Alpha Vantage API
-async function fetchMarketData(env) {
- const symbols = ['SPY', 'QQQ', 'AAPL', 'MSFT', 'TSLA', 'NVDA'];
+// Fetch market data from Yahoo Finance (free, no API key required)
+async function fetchMarketData() {
+ const symbols = ['SPY', 'AAPL', 'MSFT', 'TSLA'];
const marketData = {};
- for (const symbol of symbols) {
+ const promises = symbols.map(async (symbol) => {
try {
- // Get daily prices
- const priceResponse = await fetch(
- `https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=${symbol}&apikey=${env.STOCK_API_KEY}`
- );
- const priceData = await priceResponse.json();
+ const controller = new AbortController();
+ const timeout = setTimeout(() => controller.abort(), 8000);
- // Get technical indicators (RSI)
- const rsiResponse = await fetch(
- `https://www.alphavantage.co/query?function=RSI&symbol=${symbol}&interval=daily&time_period=14&series_type=close&apikey=${env.STOCK_API_KEY}`
+ const response = await fetch(
+ \`https://query1.finance.yahoo.com/v8/finance/chart/\\${symbol}\`,
+ {
+ signal: controller.signal,
+ headers: { 'User-Agent': 'Mozilla/5.0' }
+ }
);
- const rsiData = await rsiResponse.json();
-
- if (priceData['Time Series (Daily)'] && rsiData['Technical Analysis: RSI']) {
- const latestDate = Object.keys(priceData['Time Series (Daily)'])[0];
- const latestPrice = priceData['Time Series (Daily)'][latestDate];
- const latestRSI = Object.values(rsiData['Technical Analysis: RSI'])[0];
-
- marketData[symbol] = {
- price: parseFloat(latestPrice['4. close']),
- open: parseFloat(latestPrice['1. open']),
- high: parseFloat(latestPrice['2. high']),
- low: parseFloat(latestPrice['3. low']),
- volume: parseInt(latestPrice['5. volume']),
- change: parseFloat(latestPrice['4. close']) - parseFloat(latestPrice['1. open']),
- change_percent: ((parseFloat(latestPrice['4. close']) - parseFloat(latestPrice['1. open'])) / parseFloat(latestPrice['1. open']) * 100).toFixed(2),
- rsi: parseFloat(latestRSI?.RSI || 50),
- date: latestDate
- };
- }
+ clearTimeout(timeout);
- // Rate limiting - Alpha Vantage allows 5 requests per minute on free tier
- await new Promise(resolve => setTimeout(resolve, 12000));
+ if (!response.ok) throw new Error(\`HTTP \\${response.status}\`);
- } catch (error) {
- console.error(`Error fetching data for ${symbol}:`, error);
- marketData[symbol] = { error: 'Failed to fetch data' };
- }
- }
-
- return marketData;
-}
-
-// Fetch market news from Financial Modeling Prep (free tier available)
-async function fetchMarketNews(env) {
- try {
- const newsResponse = await fetch(
- `https://financialmodelingprep.com/api/v3/stock_news?tickers=AAPL,MSFT,TSLA,NVDA&limit=10&apikey=${env.FMP_API_KEY || 'demo'}`
- );
- const newsData = await newsResponse.json();
-
- if (Array.isArray(newsData)) {
- return newsData.slice(0, 5).map(article => ({
- title: article.title,
- text: article.text?.substring(0, 300) + '...',
- publishedDate: article.publishedDate,
- symbol: article.symbol,
- url: article.url
- }));
- }
- } catch (error) {
- console.error('Error fetching news:', error);
- }
-
- return "Market news temporarily unavailable";
-}
-
-// Send email report using Mailgun API
-async function sendEmailReport(env, analysis, marketData) {
- // Extract key market movers for email subject
- const movers = Object.entries(marketData)
- .filter(([symbol, data]) => data.change_percent && Math.abs(parseFloat(data.change_percent)) > 2)
- .map(([symbol, data]) => `${symbol}: ${data.change_percent}%`)
- .join(', ');
-
- const emailSubject = `📊 Daily Stock Analysis - ${new Date().toLocaleDateString()}`;
- const emailBody = `
- Daily Market Analysis Report
- Date: ${new Date().toLocaleString()}
- Key Market Movers: ${movers || 'Market stable'}
-
- AI Agent Analysis:
-
-
- Market Data Summary:
-
-
- Symbol | Price | Change % | Volume | RSI |
-
- ${Object.entries(marketData).map(([symbol, data]) => `
-
- ${symbol} |
- $${data.price?.toFixed(2) || 'N/A'} |
-
- ${data.change_percent}%
- |
- ${data.volume?.toLocaleString() || 'N/A'} |
- ${data.rsi?.toFixed(1) || 'N/A'} |
-
- `).join('')}
-
-
- Generated by Swarms AI Agent System
- `;
-
- // Send via Mailgun
- const formData = new FormData();
- formData.append('from', `Stock Analysis Agent `);
- formData.append('to', env.RECIPIENT_EMAIL);
- formData.append('subject', emailSubject);
- formData.append('html', emailBody);
-
- try {
- const response = await fetch(`https://api.mailgun.net/v3/${env.MAILGUN_DOMAIN}/messages`, {
- method: 'POST',
- headers: {
- 'Authorization': `Basic ${btoa(`api:${env.MAILGUN_API_KEY}`)}`
- },
- body: formData
- });
+ const data = await response.json();
+ const result = data.chart.result[0];
+ const meta = result.meta;
+
+ const currentPrice = meta.regularMarketPrice;
+ const previousClose = meta.previousClose;
+ const change = currentPrice - previousClose;
+ const changePercent = ((change / previousClose) * 100).toFixed(2);
+
+ return [symbol, {
+ price: currentPrice,
+ change: change,
+ change_percent: changePercent,
+ volume: meta.regularMarketVolume,
+ currency: meta.currency
+ }];
- if (response.ok) {
- console.log('✅ Email report sent successfully');
- } else {
- console.error('❌ Failed to send email:', await response.text());
+ } catch (error) {
+ return [symbol, { error: error.message }];
}
- } catch (error) {
- console.error('❌ Email sending error:', error);
- }
-}
-
-async function sendSlackNotification(webhookUrl, analysis) {
- await fetch(webhookUrl, {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({
- text: "📈 Daily Stock Market Analysis",
- blocks: [{
- type: "section",
- text: {
- type: "mrkdwn",
- text: `*Market Analysis Complete*\n\`\`\`${analysis.substring(0, 500)}...\`\`\``
- }
- }]
- })
});
-}
-```
-
-## Healthcare Monitoring Agent
-
-Automated patient monitoring and health alerts:
-```javascript
-export default {
- async scheduled(event, env, ctx) {
- // Determine which agent to run based on cron schedule
- const hour = new Date().getHours();
-
- if (hour % 4 === 0) {
- // Every 4 hours - patient monitoring
- ctx.waitUntil(handlePatientMonitoring(event, env));
+ const results = await Promise.allSettled(promises);
+ results.forEach((result) => {
+ if (result.status === 'fulfilled' && result.value) {
+ const [symbol, data] = result.value;
+ marketData[symbol] = data;
}
- }
-};
-
-async function handlePatientMonitoring(event, env) {
- const healthcareSwarm = {
- name: "Patient Monitoring System",
- description: "Automated patient health analysis and alerting",
- agents: [
- {
- agent_name: "Vital Signs Analyst",
- system_prompt: `Analyze patient vital signs data for abnormalities:
- - Heart rate patterns and irregularities
- - Blood pressure trends
- - Oxygen saturation levels
- - Temperature variations
- Flag critical conditions requiring immediate attention.`,
- model_name: "gpt-4o-mini",
- max_tokens: 2000,
- temperature: 0.1
- },
- {
- agent_name: "Risk Assessment Specialist",
- system_prompt: `Evaluate patient risk factors and health trends:
- - Medication interactions
- - Chronic condition management
- - Recovery progress assessment
- - Early warning signs detection
- Prioritize patients needing urgent care.`,
- model_name: "gpt-4o-mini",
- max_tokens: 2000,
- temperature: 0.2
- }
- ],
- swarm_type: "ConcurrentWorkflow",
- task: "Analyze current patient monitoring data and generate health status alerts for medical staff.",
- max_loops: 1
- };
-
- try {
- const response = await fetch('https://api.swarms.world/v1/swarm/completions', {
- method: 'POST',
- headers: {
- 'x-api-key': env.SWARMS_API_KEY,
- 'Content-Type': 'application/json'
- },
- body: JSON.stringify(healthcareSwarm)
- });
+ });
- const result = await response.json();
-
- if (response.ok) {
- console.log('🏥 Health monitoring completed');
-
- // Send email alerts for all monitoring results
- await sendHealthEmailAlert(env, result.output);
- }
- } catch (error) {
- console.error('❌ Health monitoring failed:', error);
- }
+ return marketData;
}
+```
-// Send healthcare email alerts
-async function sendHealthEmailAlert(env, analysis) {
- const severity = extractSeverity(analysis);
- const isUrgent = severity === 'critical' || severity === 'urgent';
-
- const emailSubject = `${isUrgent ? '🚨 URGENT' : '🏥'} Health Monitoring Alert - ${new Date().toLocaleString()}`;
- const emailBody = `
- Patient Monitoring Report
- Timestamp: ${new Date().toLocaleString()}
- Severity Level: ${severity.toUpperCase()}
-
- AI Health Analysis:
-
-
- ${isUrgent ? '⚠️ IMMEDIATE ATTENTION REQUIRED
' : ''}
-
- Generated by Swarms Healthcare Monitoring Agent
- `;
-
- // Send email using Mailgun
- const formData = new FormData();
- formData.append('from', `Healthcare Monitor `);
- formData.append('to', env.MEDICAL_TEAM_EMAIL);
- formData.append('subject', emailSubject);
- formData.append('html', emailBody);
+## Key Features Explained
- try {
- const response = await fetch(`https://api.mailgun.net/v3/${env.MAILGUN_DOMAIN}/messages`, {
- method: 'POST',
- headers: {
- 'Authorization': `Basic ${btoa(`api:${env.MAILGUN_API_KEY}`)}`
- },
- body: formData
- });
+### 1. **Dual Handler Pattern**
+- **`fetch()`**: Handles HTTP requests, provides web UI for testing
+- **`scheduled()`**: Executes on cron schedule automatically
+- **Shared Logic**: Both use the same `handleStockAnalysis()` function
- if (response.ok) {
- console.log('✅ Healthcare email alert sent successfully');
- } else {
- console.error('❌ Failed to send healthcare email:', await response.text());
- }
- } catch (error) {
- console.error('❌ Healthcare email error:', error);
- }
+### 2. **Cron Configuration**
+```jsonc
+"triggers": {
+ "crons": [
+ "0 */3 * * *" // Every 3 hours
+ "0 9 * * MON-FRI" // Weekdays at 9 AM
+ ]
}
+```
-function extractSeverity(analysis) {
- if (analysis.includes('CRITICAL')) return 'critical';
- if (analysis.includes('URGENT')) return 'urgent';
- if (analysis.includes('WARNING')) return 'warning';
- return 'normal';
-}
+### 3. **Real Data Integration**
+- **Yahoo Finance API**: Free, no API key required
+- **Error Handling**: Timeout management, fallback responses
+- **Parallel Processing**: Fetch multiple symbols simultaneously
-function getSeverityColor(severity) {
- switch(severity) {
- case 'critical': return 'red';
- case 'urgent': return 'orange';
- case 'warning': return 'yellow';
- default: return 'green';
- }
-}
-```
+### 4. **Production Features**
+- **Web Interface**: Test manually via browser
+- **Structured Responses**: Consistent JSON format
+- **Error Recovery**: Graceful failure handling
+- **Logging**: Console output for debugging
## Deployment
```bash
-# Deploy your cron job agents
+# Deploy to Cloudflare
wrangler deploy
-# Monitor logs
+# View logs
wrangler tail
-# Test cron trigger manually
-wrangler triggers cron "0 21 * * MON-FRI"
+# Test cron manually
+wrangler triggers cron "0 */3 * * *"
```
-## Cost Optimization
-
-- Use `gpt-4o-mini` for cost-effective analysis
-- Set appropriate `max_tokens` limits
-- Configure cron schedules to avoid unnecessary runs
-- Implement error handling to prevent API waste
-
## Environment Variables
-Add to `wrangler.toml`:
-
-```toml
-[env.production.vars]
-SWARMS_API_KEY = "your-swarms-api-key"
+Add to `wrangler.jsonc`:
-# Stock API Keys (get free keys from these providers)
-STOCK_API_KEY = "your-alpha-vantage-key" # Free: https://www.alphavantage.co/support/#api-key
-FMP_API_KEY = "your-fmp-key" # Free: https://financialmodelingprep.com/developer/docs
-
-# Email Configuration (Mailgun)
-MAILGUN_API_KEY = "your-mailgun-api-key" # Free: https://www.mailgun.com/
-MAILGUN_DOMAIN = "your-domain.com"
-RECIPIENT_EMAIL = "investor@yourcompany.com"
-MEDICAL_TEAM_EMAIL = "medical-team@hospital.com"
+```jsonc
+{
+ "vars": {
+ "SWARMS_API_KEY": "your-swarms-api-key",
+ "MAILGUN_API_KEY": "optional-for-emails",
+ "MAILGUN_DOMAIN": "your-domain.com",
+ "RECIPIENT_EMAIL": "alerts@company.com"
+ }
+}
```
-## API Endpoints Used
+## Testing
+
+1. **Deploy**: `wrangler deploy`
+2. **Visit URL**: Open your worker URL to see the web interface
+3. **Manual Test**: Click "Start Analysis" button
+4. **Cron Test**: `wrangler triggers cron "0 */3 * * *"`
-### Stock Data APIs
-- **Alpha Vantage**: Real-time stock prices, technical indicators (RSI, MACD)
-- **Financial Modeling Prep**: Market news, earnings data, company fundamentals
-- **Free Tier Limits**: Alpha Vantage (5 calls/min), FMP (250 calls/day)
+## Production Tips
-### Real Market Data Flow
-1. **Fetch Live Data**: Current prices, volume, technical indicators
-2. **Get Market News**: Recent earnings, economic events, analyst reports
-3. **AI Analysis**: Swarms agents analyze real data for actionable insights
-4. **Email Reports**: Professional HTML emails with analysis and data tables
+- **Error Handling**: Always wrap API calls in try-catch
+- **Timeouts**: Use AbortController for external API calls
+- **Logging**: Use console.log for debugging in Cloudflare dashboard
+- **Rate Limits**: Yahoo Finance is free but has rate limits
+- **Cost Control**: Set appropriate `max_tokens` in agent config
-### Email Features
-- **Stock Reports**: Daily market analysis with data tables and key movers
-- **Healthcare Alerts**: Color-coded severity levels with immediate attention flags
-- **HTML Formatting**: Professional email templates with styling
-- **Mailgun Integration**: Reliable email delivery service
+This minimal implementation provides a solid foundation for production AI agents on Cloudflare Workers with automated scheduling and real-time data integration.
\ No newline at end of file