.do
DeployCode Deployment

Deploy as Agents

Deploy MDX Functions as autonomous AI agents

Deploy MDX Functions as Agents

Documentation Status: This documentation describes the planned API design for the .do platform. Code examples represent the intended interface and may not reflect the current implementation state. See roadmap for implementation status.

Transform your MDX functions into autonomous AI agents that can execute tasks, make decisions, and interact with users and systems independently.

Overview

When you deploy MDX functions as agents, they become:

  • Autonomous - Can operate independently without constant human oversight
  • Intelligent - Make decisions based on context and goals
  • Reactive - Respond to events and triggers automatically
  • Collaborative - Work with other agents and humans
  • Persistent - Maintain state and memory across interactions
flowchart TB A[MDX Functions] --> B[Agent Deployment] B --> C[Agent Capabilities] C --> D[Decision Making] C --> E[Memory & Context] C --> F[Event Triggers] C --> G[Human-in-the-Loop] D --> H[Autonomous Actions] E --> H F --> H G --> H H --> I[AI Models] H --> J[Database] H --> K[External APIs] H --> L[Human Review]

Creating an Agent from MDX

Basic Agent

Take an MDX function and deploy it as an agent:

---
title: Customer Support Agent
description: Automated customer support assistant
---

export async function handleSupportRequest(request) {
  // Analyze the request
  const analysis = await $.ai.analyze(request.message, {
    intent: true,
    sentiment: true,
    urgency: true
  })

// Route based on urgency
if (analysis.urgency === 'high') {
await $.human.notify({
type: 'urgent_support',
request,
analysis
})
}

// Generate response
const response = await $.ai.generateText({
prompt: 'Provide helpful support response',
context: {
request: request.message,
analysis,
knowledgeBase: await $.db.articles.search(analysis.topic)
}
})

// Send response
await $.email.send.message({
to: request.email,
subject: `Re: ${request.subject}`,
body: response
})

// Track interaction
return await $.db.interactions.create({
type: 'support',
request,
response,
analysis,
timestamp: new Date()
})
}

Deploy as an agent:

export const supportAgent = $.agent({
  name: 'Customer Support Agent',
  description: 'Handles customer support requests automatically',

  // Import the MDX function as a capability
  capabilities: {
    handleSupportRequest,
  },

  // Define when the agent should act
  triggers: [
    $.on('support.request.created', (event) => handleSupportRequest(event.request)),
    $.on('email.received', (event) => event.subject.includes('support') && handleSupportRequest(event)),
  ],

  // Agent configuration
  config: {
    model: 'claude-sonnet-4.5',
    temperature: 0.7,
    maxTokens: 2000,
  },
})

Agent Capabilities

Decision Making

Agents can make autonomous decisions:

---
title: Content Moderator
description: Automatically moderate user-generated content
---

export async function moderateContent(content) {
  // Analyze content
  const analysis = await $.ai.moderate(content.text, {
    checkFor: ['spam', 'abuse', 'inappropriate', 'harmful']
  })

// Make decision
if (analysis.violations.length === 0) {
// Approve automatically
await $.db.content.update(content.id, { status: 'approved' })
return { action: 'approved', automated: true }
}

if (analysis.severity === 'high') {
// Reject automatically
await $.db.content.update(content.id, { status: 'rejected' })
await $.user.notify(content.authorId, {
type: 'content_rejected',
reason: analysis.violations
})
return { action: 'rejected', automated: true, reason: analysis }
}

// Send for human review
await $.human.request({
type: 'content_review',
content,
analysis,
assignee: 'moderation_team'
})

return { action: 'pending_review', automated: false }
}

Memory and Context

Agents maintain state across interactions:

---
title: Sales Assistant
description: Personalized sales assistance with context
---

export async function assistCustomer(customerId, message) {
  // Retrieve customer context
  const context = await $.agent.memory.get(customerId, {
    include: ['previous_interactions', 'preferences', 'purchase_history']
  })

// Generate personalized response
const response = await $.ai.generateText({
prompt: 'Provide personalized sales assistance',
context: {
customer: context,
message,
catalog: await $.db.products.find({ available: true })
}
})

// Update memory
await $.agent.memory.update(customerId, {
lastInteraction: new Date(),
messages: [...context.messages, { role: 'user', content: message }],
intent: await $.ai.analyze(message, { intent: true })
})

return response
}

Multi-Step Workflows

Agents can orchestrate complex workflows:

---
title: Content Publisher
description: Automated content publishing workflow
---

export async function publishContent(contentId) {
  const content = await $.db.content.findById(contentId)

// Step 1: Generate SEO metadata
const seo = await $.ai.generate.metadata({
title: content.title,
body: content.body,
type: 'article'
})

// Step 2: Generate images
const images = await $.ai.generateImages({
prompts: extractImageNeeds(content.body),
style: 'professional'
})

// Step 3: Optimize content
const optimized = await $.ai.optimize(content.body, {
for: ['readability', 'seo', 'engagement']
})

// Step 4: Schedule social media
const scheduled = await $.social.schedule.posts([
{
platform: 'twitter',
content: generateTweet(content),
time: 'optimal'
},
{
platform: 'linkedin',
content: generateLinkedInPost(content),
time: 'optimal'
}
])

// Step 5: Publish
await $.db.content.update(contentId, {
status: 'published',
seo,
images,
body: optimized,
publishedAt: new Date(),
socialSchedule: scheduled
})

return { success: true, contentId, scheduled }
}

Agent Teams

graph TB A[Agent Team] --> B[Content Creator] A --> C[SEO Optimizer] A --> D[Publisher] E[Task] --> B B --> F[Generate Content] F --> C C --> G[Optimize for SEO] G --> D D --> H[Publish & Distribute] H --> I[Website] H --> J[Social Media] H --> K[Email]

Combine multiple agents to work together:

export const marketingTeam = $.agent.team({
  name: 'Marketing Team',
  agents: [
    {
      role: 'content_creator',
      agent: contentCreatorAgent,
      responsibilities: ['Generate blog posts', 'Create social content'],
    },
    {
      role: 'seo_optimizer',
      agent: seoOptimizerAgent,
      responsibilities: ['Optimize for search', 'Generate metadata'],
    },
    {
      role: 'publisher',
      agent: publisherAgent,
      responsibilities: ['Schedule posts', 'Manage distribution'],
    },
  ],

  // Define team workflow
  workflow: async (task) => {
    // Content creator generates
    const content = await contentCreatorAgent.execute(task)

    // SEO optimizer enhances
    const optimized = await seoOptimizerAgent.execute(content)

    // Publisher distributes
    const published = await publisherAgent.execute(optimized)

    return published
  },
})

Agent Configuration

Deployment Config

// do.config.ts
export default {
  agents: [
    {
      name: 'support-agent',
      source: './agents/support.mdx',
      deployment: {
        triggers: ['support.request.created', 'email.received'],
        schedule: null, // event-driven only
        concurrency: 10, // handle 10 requests concurrently
        timeout: 300000, // 5 minute timeout
        retries: 3,
      },
      environment: {
        AI_MODEL: 'claude-sonnet-4.5',
        KNOWLEDGE_BASE_ID: 'kb_123',
        NOTIFY_ON_ESCALATION: '[email protected]',
      },
    },
    {
      name: 'content-moderator',
      source: './agents/moderator.mdx',
      deployment: {
        triggers: ['content.submitted'],
        schedule: '*/5 * * * *', // also check every 5 minutes
        concurrency: 50,
        timeout: 30000,
      },
    },
  ],
}

Environment Variables

# .env
AI_MODEL=claude-sonnet-4.5
AI_TEMPERATURE=0.7
AI_MAX_TOKENS=2000
AGENT_MEMORY_STORE=redis://localhost:6379
AGENT_LOG_LEVEL=info

Monitoring and Observability

Agent Dashboard

Monitor agent performance in real-time:

// Access agent metrics
const metrics = await $.agent.metrics.get('support-agent', {
  period: 'last_24h',
})

console.log({
  requestsHandled: metrics.total,
  averageResponseTime: metrics.avgResponseTime,
  successRate: metrics.successRate,
  escalations: metrics.escalations,
  cost: metrics.aiCost,
})

Logging and Tracing

// Enable detailed logging
export const agent = $.agent({
  name: 'Debug Agent',
  capabilities: { myFunction },
  config: {
    logging: {
      level: 'debug',
      includeContext: true,
      includePrompts: true,
      redact: ['email', 'phone', 'ssn'],
    },
    tracing: {
      enabled: true,
      sampleRate: 1.0,
    },
  },
})

Best Practices

Error Handling

Always handle errors gracefully:

export async function robustAgentFunction(input) {
  try {
    const result = await processInput(input)
    return { success: true, result }
  } catch (error) {
    // Log error
    await $.log.error('Agent function failed', {
      error: error.message,
      input,
      stack: error.stack
    })

    // Notify humans if critical
    if (error.critical) {
      await $.human.notify({
        type: 'agent_failure',
        error,
        input
      })
    }

    return { success: false, error: error.message }

}
}

Rate Limiting

Respect API limits and costs:

export const agent = $.agent({
  name: 'Rate Limited Agent',
  capabilities: { myFunction },
  config: {
    rateLimit: {
      requests: 100,
      period: '1m',
    },
    costLimit: {
      amount: 10.0,
      period: '1h',
      currency: 'USD',
    },
  },
})

Testing

Test agents before deployment:

import { test } from 'vitest'

test('support agent handles request', async () => {
  const request = {
    email: '[email protected]',
    subject: 'Need help',
    message: 'How do I reset my password?',
  }

  const result = await handleSupportRequest(request)

  expect(result).toHaveProperty('type', 'support')
  expect(result.response).toBeDefined()
})

Production Deployment

Deployment Strategy

// Production deployment configuration
export default {
  agents: [
    {
      name: 'production-agent',
      source: './agents/support.mdx',
      deployment: {
        strategy: 'blue-green', // 'blue-green' | 'canary' | 'rolling'

        // Blue-green deployment
        blueGreen: {
          enabled: true,
          healthCheckUrl: '/health',
          healthCheckInterval: 30000,
          switchoverDelay: 60000,
        },

        // Canary deployment
        canary: {
          enabled: false,
          initialTraffic: 0.05, // 5% traffic to canary
          incrementBy: 0.1,
          incrementInterval: 300000, // 5 minutes
          successThreshold: 0.99,
        },

        // Rolling deployment
        rolling: {
          enabled: false,
          batchSize: 2,
          healthCheckDelay: 10000,
        },
      },
    },
  ],
}

Health Checks

// Health check implementation
export async function healthCheck() {
  return {
    status: 'healthy',
    checks: {
      database: await checkDatabase(),
      ai: await checkAI(),
      memory: await checkMemory(),
    },
    timestamp: new Date().toISOString(),
  }
}

async function checkDatabase() {
  try {
    await $.db.ping()
    return { status: 'healthy', latency: 5 }
  } catch (error) {
    return { status: 'unhealthy', error: error.message }
  }
}

async function checkAI() {
  try {
    const start = Date.now()
    await $.ai.ping()
    return { status: 'healthy', latency: Date.now() - start }
  } catch (error) {
    return { status: 'unhealthy', error: error.message }
  }
}

async function checkMemory() {
  const usage = process.memoryUsage()
  const limit = 1024 * 1024 * 1024 // 1GB
  return {
    status: usage.heapUsed < limit ? 'healthy' : 'warning',
    heapUsed: usage.heapUsed,
    heapTotal: usage.heapTotal,
  }
}

Readiness Probes

export async function readinessCheck() {
  // Check if agent is ready to accept traffic
  const checks = await Promise.all([
    checkModelLoaded(),
    checkKnowledgeBaseReady(),
    checkMemoryStoreConnected(),
  ])

  const allReady = checks.every(check => check.ready)

  return {
    ready: allReady,
    checks,
  }
}

async function checkModelLoaded() {
  try {
    const loaded = await $.ai.models.check('claude-sonnet-4.5')
    return { ready: loaded, service: 'ai-model' }
  } catch (error) {
    return { ready: false, service: 'ai-model', error: error.message }
  }
}

Production Monitoring

// Comprehensive monitoring setup
export default {
  agents: [
    {
      name: 'production-agent',
      monitoring: {
        // Metrics
        metrics: {
          enabled: true,
          interval: 30000, // 30 seconds
          metrics: [
            'requests_total',
            'requests_duration',
            'errors_total',
            'ai_tokens_used',
            'memory_usage',
            'cpu_usage',
          ],
        },

        // Logging
        logging: {
          level: 'info', // 'debug' | 'info' | 'warn' | 'error'
          structured: true,
          includeContext: true,
          excludeFields: ['apiKey', 'password'],
          destinations: [
            { type: 'console' },
            { type: 'file', path: '/var/log/agents/production.log' },
            { type: 'cloudwatch', logGroup: '/agents/production' },
          ],
        },

        // Tracing
        tracing: {
          enabled: true,
          provider: 'opentelemetry',
          endpoint: 'https://trace.example.do',
          sampleRate: 1.0, // 100% in production
          includeHeaders: false,
        },

        // Alerting
        alerts: [
          {
            name: 'high-error-rate',
            condition: 'error_rate > 0.05',
            duration: '5m',
            severity: 'critical',
            notify: ['[email protected]', 'pagerduty'],
            actions: ['scale-up', 'notify-on-call'],
          },
          {
            name: 'high-latency',
            condition: 'p95_latency > 5000',
            duration: '10m',
            severity: 'warning',
            notify: ['[email protected]'],
          },
          {
            name: 'memory-high',
            condition: 'memory_usage > 0.85',
            duration: '3m',
            severity: 'warning',
            notify: ['[email protected]'],
            actions: ['scale-up'],
          },
        ],
      },
    },
  ],
}

CI/CD Pipeline

# .github/workflows/deploy-agent.yml
name: Deploy Agent to Production

on:
  push:
    branches: [main]
    paths:
      - 'agents/**'
      - '.github/workflows/deploy-agent.yml'

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install pnpm
        uses: pnpm/action-setup@v2

      - name: Install dependencies
        run: pnpm install

      - name: Run tests
        run: pnpm test agents/

      - name: Type check
        run: pnpm typecheck

      - name: Lint
        run: pnpm lint agents/

  build:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Build agent
        run: pnpm build:agent

      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: agent-build
          path: dist/agents/

  deploy-staging:
    needs: build
    runs-on: ubuntu-latest
    environment: staging
    steps:
      - name: Download artifact
        uses: actions/download-artifact@v4
        with:
          name: agent-build

      - name: Deploy to staging
        run: |
          pnpm do deploy:agent --env staging
        env:
          DO_TOKEN: ${{ secrets.DO_STAGING_TOKEN }}

      - name: Wait for health check
        run: |
          for i in {1..30}; do
            if curl -f https://staging-agent.example.do/health; then
              echo "Health check passed"
              exit 0
            fi
            echo "Waiting for health check... ($i/30)"
            sleep 10
          done
          echo "Health check failed"
          exit 1

      - name: Run smoke tests
        run: pnpm test:e2e --env staging

  deploy-production:
    needs: deploy-staging
    runs-on: ubuntu-latest
    environment: production
    steps:
      - name: Download artifact
        uses: actions/download-artifact@v4
        with:
          name: agent-build

      - name: Deploy to production (blue-green)
        run: |
          # Deploy to green environment
          pnpm do deploy:agent --env production --slot green

          # Wait for green to be healthy
          pnpm do wait-healthy --slot green --timeout 300

          # Switch traffic to green
          pnpm do switch-traffic --from blue --to green

          # Monitor for issues
          sleep 300

          # If no issues, keep green as active
          # Otherwise rollback happens automatically
        env:
          DO_TOKEN: ${{ secrets.DO_PRODUCTION_TOKEN }}

      - name: Verify deployment
        run: |
          curl -f https://agent.example.do/health
          pnpm do verify-deployment --env production

      - name: Notify Slack
        if: always()
        uses: slackapi/slack-github-action@v1
        with:
          payload: |
            {
              "text": "Agent deployment ${{ job.status }}: ${{ github.event.head_commit.message }}",
              "status": "${{ job.status }}"
            }
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}

Rollback Procedures

# Manual rollback commands
# List recent deployments
pnpm do deployments list --agent production-agent

# Output:
# ID        VERSION  STATUS    DEPLOYED_AT           TRAFFIC
# dep_123   v1.2.5   active    2024-01-15 10:30:00   100%
# dep_122   v1.2.4   standby   2024-01-14 09:15:00   0%
# dep_121   v1.2.3   archived  2024-01-13 14:22:00   0%

# Rollback to previous version
pnpm do rollback --agent production-agent

# Rollback to specific version
pnpm do rollback --agent production-agent --version v1.2.4

# Automatic rollback on failure
pnpm do deploy:agent --auto-rollback \
  --failure-threshold 0.05 \
  --monitoring-period 300

Automated Rollback Configuration

export default {
  agents: [
    {
      name: 'production-agent',
      deployment: {
        autoRollback: {
          enabled: true,

          // Trigger conditions
          triggers: [
            {
              metric: 'error_rate',
              threshold: 0.05,
              duration: '5m',
            },
            {
              metric: 'p99_latency',
              threshold: 10000,
              duration: '3m',
            },
            {
              metric: 'health_check_failures',
              threshold: 3,
              duration: '1m',
            },
          ],

          // Rollback behavior
          behavior: {
            immediate: true,
            notifyBefore: true,
            retainLogs: true,
            createIncident: true,
          },
        },
      },
    },
  ],
}

Production Troubleshooting

# View agent logs
pnpm do logs --agent production-agent --tail 100

# Stream live logs
pnpm do logs --agent production-agent --follow

# Filter by level
pnpm do logs --agent production-agent --level error

# View metrics
pnpm do metrics --agent production-agent --period 1h

# Debug mode (temporary)
pnpm do debug enable --agent production-agent --duration 10m

# Check agent status
pnpm do status --agent production-agent

# Output:
# Agent: production-agent
# Status: running
# Version: v1.2.5
# Uptime: 5d 3h 22m
# Requests/min: 145
# Error rate: 0.2%
# P95 latency: 234ms
# Memory: 456MB / 1GB (45%)
# CPU: 12%

# Restart agent
pnpm do restart --agent production-agent

# Scale agent
pnpm do scale --agent production-agent --replicas 5

Performance Optimization

// Production performance configuration
export default {
  agents: [
    {
      name: 'production-agent',
      performance: {
        // Caching
        cache: {
          enabled: true,
          provider: 'redis',
          ttl: 3600,
          keyPrefix: 'agent:production',

          // Cache frequently accessed data
          strategies: {
            'user-data': { ttl: 300 },
            'knowledge-base': { ttl: 86400 },
            'model-responses': { ttl: 1800 },
          },
        },

        // Connection pooling
        database: {
          pool: {
            min: 5,
            max: 20,
            acquireTimeout: 30000,
            idleTimeout: 600000,
          },
        },

        // Request batching
        batching: {
          enabled: true,
          maxBatchSize: 50,
          maxWaitTime: 100, // ms
        },

        // Resource limits
        limits: {
          memory: '1GB',
          cpu: '1000m', // 1 CPU core
          concurrency: 100,
          queueSize: 1000,
        },

        // Optimization flags
        optimize: {
          enableJIT: true,
          enableV8Flags: ['--max-old-space-size=1024'],
          preloadModels: true,
          warmupRequests: 10,
        },
      },
    },
  ],
}

Security Hardening

export default {
  agents: [
    {
      name: 'production-agent',
      security: {
        // Authentication
        auth: {
          required: true,
          methods: ['jwt', 'api-key'],
          jwtSecret: process.env.JWT_SECRET,
          tokenExpiry: '1h',
        },

        // Rate limiting
        rateLimit: {
          windowMs: 60000, // 1 minute
          max: 100, // 100 requests per minute
          skipSuccessfulRequests: false,
          standardHeaders: true,
        },

        // Input validation
        validation: {
          enabled: true,
          sanitize: true,
          maxPayloadSize: '10mb',
          allowedOrigins: ['https://app.example.do'],
        },

        // Secrets management
        secrets: {
          provider: 'aws-secrets-manager',
          autoRotate: true,
          rotationInterval: '30d',
        },

        // Network security
        network: {
          allowedIPs: ['10.0.0.0/8'],
          requireHTTPS: true,
          enableCORS: true,
          corsOrigins: ['https://app.example.do'],
        },

        // Audit logging
        audit: {
          enabled: true,
          logLevel: 'all',
          includePayload: false,
          retention: '90d',
        },
      },
    },
  ],
}

Disaster Recovery

export default {
  agents: [
    {
      name: 'production-agent',
      disasterRecovery: {
        // Backup strategy
        backup: {
          enabled: true,
          schedule: '0 2 * * *', // Daily at 2 AM
          retention: 30, // days
          destinations: ['s3://backups/agents'],
        },

        // Multi-region deployment
        regions: ['us-east-1', 'us-west-2', 'eu-west-1'],
        failover: {
          enabled: true,
          automatic: true,
          healthCheckInterval: 30000,
          failoverThreshold: 3,
        },

        // Data replication
        replication: {
          enabled: true,
          mode: 'async',
          lag: 'max-10s',
        },

        // Recovery procedures
        recovery: {
          rto: 300, // Recovery Time Objective: 5 minutes
          rpo: 60, // Recovery Point Objective: 1 minute
          runbooks: [
            'https://docs.example.do/runbooks/agent-recovery',
          ],
        },
      },
    },
  ],
}

Load Testing

// Load test configuration
import { loadTest } from '@dotdo/testing'

await loadTest({
  agent: 'production-agent',

  // Test scenarios
  scenarios: [
    {
      name: 'normal-load',
      duration: '10m',
      vus: 100, // virtual users
      rps: 50, // requests per second
    },
    {
      name: 'peak-load',
      duration: '5m',
      vus: 500,
      rps: 250,
    },
    {
      name: 'stress-test',
      duration: '2m',
      vus: 1000,
      rps: 500,
    },
  ],

  // Assertions
  thresholds: {
    'http_req_duration': ['p(95)<500', 'p(99)<1000'],
    'http_req_failed': ['rate<0.01'],
    'http_reqs': ['rate>45'],
  },

  // Reporting
  reports: {
    output: 'test-results/load-test.html',
    realtime: true,
    webhooks: ['https://metrics.example.do/load-test'],
  },
})
    • Agents Framework - Complete agent capabilities
    • Functions - Function types and composition
  • Workflows - Deploy as workflows
  • Services - Deploy as services
  • Configuration - Deployment configuration
  • Build Process - Build pipeline