daimon.email
ExamplesFrameworks

CrewAI Integration

Email-capable CrewAI agents

Overview

Integrate daimon.email into CrewAI multi-agent systems, enabling your crew members to handle email tasks as part of collaborative workflows.

Info

Multi-agent email: Create specialized agents within a crew that handle email operations (inbox creation, monitoring, sending) while other agents focus on their core tasks.

Installation

npm install crewai daimon-email
# or
pip install crewai daimon-email

Complete Implementation

from crewai import Agent, Task, Crew, Process
from crewai_tools import BaseTool
from daimon_email import DaimonClient
from pydantic import BaseModel, Field
import json

# Initialize daimon.email client
daimon_client = DaimonClient(api_key=os.getenv('DAIMON_API_KEY'))

# Store created inboxes in crew context
crew_inboxes = {}

# Tool 1: Create Inbox
class CreateInboxTool(BaseTool):
    name: str = "Create Email Inbox"
    description: str = "Create a new email inbox for the crew. Returns email address and inbox ID."

    def _run(self, username: str) -> str:
        inbox = daimon_client.inboxes.create(
            username=username,
            client_id=f'crewai-{username}-{int(time.time())}'
        )

        inbox_data = {
            'email': inbox['result']['address'],
            'inbox_id': inbox['result']['id'],
            'api_key': inbox['result']['api_key']
        }

        # Store for crew use
        crew_inboxes[inbox_data['inbox_id']] = inbox_data

        return json.dumps(inbox_data)

# Tool 2: Check Messages
class CheckMessagesTool(BaseTool):
    name: str = "Check Email Messages"
    description: str = "Check for new messages in an inbox. Input: inbox_id"

    def _run(self, inbox_id: str) -> str:
        messages = daimon_client.inboxes.messages.list(inbox_id)

        return json.dumps([
            {
                'from': m['from'],
                'subject': m['subject'],
                'body': m.get('reply_body') or m['body'],
                'received_at': m['received_at'],
                'cta_links': m.get('cta_links', [])
            }
            for m in messages[:10]  # Limit to 10 most recent
        ])

# Tool 3: Send Email
class SendEmailTool(BaseTool):
    name: str = "Send Email"
    description: str = "Send an email from an inbox. Input: JSON with inbox_id, to, subject, body"

    def _run(self, inbox_id: str, to: str, subject: str, body: str) -> str:
        try:
            result = daimon_client.inboxes.send(inbox_id, {
                'to': to,
                'subject': subject,
                'body': body
            })

            return json.dumps({
                'success': True,
                'message_id': result['message_id']
            })
        except Exception as error:
            return json.dumps({
                'success': False,
                'error': str(error)
            })

# Create specialized agents
email_manager = Agent(
    role='Email Manager',
    goal='Manage email infrastructure for the crew',
    backstory='You are responsible for creating inboxes, monitoring messages, and coordinating email operations.',
    tools=[CreateInboxTool(), CheckMessagesTool(), SendEmailTool()],
    verbose=True
)

customer_support = Agent(
    role='Customer Support Specialist',
    goal='Provide excellent customer support via email',
    backstory='You handle customer inquiries with empathy and efficiency.',
    tools=[CheckMessagesTool(), SendEmailTool()],
    verbose=True
)

researcher = Agent(
    role='Research Analyst',
    goal='Analyze incoming emails for insights',
    backstory='You extract key information and action items from email communications.',
    tools=[CheckMessagesTool()],
    verbose=True
)

# Define tasks
task1 = Task(
    description='Create a new inbox with username "crew-support"',
    agent=email_manager,
    expected_output='Email address and inbox ID'
)

task2 = Task(
    description='Monitor the inbox for new customer inquiries',
    agent=customer_support,
    expected_output='Summary of incoming messages',
    context=[task1]  # Depends on task1
)

task3 = Task(
    description='Analyze customer emails and identify common themes',
    agent=researcher,
    expected_output='Report on customer email patterns',
    context=[task2]
)

task4 = Task(
    description='Send personalized responses to all customer inquiries',
    agent=customer_support,
    expected_output='List of sent responses',
    context=[task2, task3]
)

# Create and run the crew
crew = Crew(
    agents=[email_manager, customer_support, researcher],
    tasks=[task1, task2, task3, task4],
    process=Process.sequential,
    verbose=True
)

result = crew.kickoff()

print("Crew Result:")
print(result)
import { Agent, Task, Crew } from '@crewai/crewai';
import { DaimonClient } from 'daimon-email';

// TypeScript implementation
// Note: CrewAI is primarily Python-based
// This is a conceptual TypeScript equivalent

interface EmailTool {
  name: string;
  description: string;
  run: (args: any) => Promise<string>;
}

const daimonClient = new DaimonClient({ apiKey: process.env.DAIMON_API_KEY });
const crewInboxes = new Map();

// Create tools
const createInboxTool: EmailTool = {
  name: 'create_inbox',
  description: 'Create a new email inbox',
  run: async ({ username }) => {
    const inbox = await daimonClient.inboxes.create({
      username,
      clientId: `crewai-${username}-${Date.now()}`
    });

    const inboxData = {
      email: inbox.result.address,
      inboxId: inbox.result.id,
      apiKey: inbox.result.apiKey
    };

    crewInboxes.set(inboxData.inboxId, inboxData);
    return JSON.stringify(inboxData);
  }
};

const checkMessagesTool: EmailTool = {
  name: 'check_messages',
  description: 'Check for new messages',
  run: async ({ inboxId }) => {
    const messages = await daimonClient.inboxes.messages.list(inboxId);
    return JSON.stringify(messages.slice(0, 10));
  }
};

const sendEmailTool: EmailTool = {
  name: 'send_email',
  description: 'Send an email',
  run: async ({ inboxId, to, subject, body }) => {
    try {
      const result = await daimonClient.inboxes.send(inboxId, {
        to,
        subject,
        body
      });
      return JSON.stringify({ success: true, messageId: result.messageId });
    } catch (error: any) {
      return JSON.stringify({ success: false, error: error.message });
    }
  }
};

// Create agents (conceptual)
const emailManager = new Agent({
  role: 'Email Manager',
  goal: 'Manage email infrastructure',
  tools: [createInboxTool, checkMessagesTool, sendEmailTool]
});

const customerSupport = new Agent({
  role: 'Customer Support',
  goal: 'Handle customer emails',
  tools: [checkMessagesTool, sendEmailTool]
});

// Create crew and run
const crew = new Crew({
  agents: [emailManager, customerSupport],
  tasks: [/* tasks */],
  process: 'sequential'
});

await crew.kickoff();

Use Case: Customer Support Crew

from crewai import Agent, Task, Crew, Process

# Specialized crew for customer support
support_crew = Crew(
    agents=[
        Agent(
            role='Email Monitor',
            goal='Monitor support inbox and categorize incoming emails',
            tools=[CheckMessagesTool()],
            backstory='You watch for new support tickets and prioritize them.'
        ),
        Agent(
            role='Support Responder',
            goal='Draft appropriate responses to customer inquiries',
            tools=[SendEmailTool()],
            backstory='You craft helpful, professional responses to customers.'
        ),
        Agent(
            role='Quality Assurance',
            goal='Review responses before sending',
            tools=[],
            backstory='You ensure all responses meet quality standards.'
        )
    ],
    tasks=[
        Task(
            description='Check support inbox for new messages',
            expected_output='List of new support tickets'
        ),
        Task(
            description='Draft responses for each ticket',
            expected_output='Drafted email responses'
        ),
        Task(
            description='Review and approve responses',
            expected_output='Approved responses ready to send'
        ),
        Task(
            description='Send approved responses',
            expected_output='Confirmation of sent emails'
        )
    ],
    process=Process.sequential
)

# Run the crew
result = support_crew.kickoff()

Use Case: Lead Generation Crew

# Crew for sales lead generation
sales_crew = Crew(
    agents=[
        Agent(
            role='Lead Qualifier',
            goal='Create inbox and monitor for inbound leads',
            tools=[CreateInboxTool(), CheckMessagesTool()],
            backstory='You identify and qualify incoming sales leads.'
        ),
        Agent(
            role='Outreach Specialist',
            goal='Send personalized outreach emails',
            tools=[SendEmailTool()],
            backstory='You craft compelling outreach messages.'
        ),
        Agent(
            role='Follow-up Manager',
            goal='Track responses and send follow-ups',
            tools=[CheckMessagesTool(), SendEmailTool()],
            backstory='You ensure no lead falls through the cracks.'
        )
    ],
    tasks=[
        Task(
            description='Create inbox "sales-leads" and monitor for inquiries',
            expected_output='New lead emails'
        ),
        Task(
            description='Send personalized outreach to 10 prospects',
            expected_output='List of sent outreach emails'
        ),
        Task(
            description='Check for responses and send follow-ups',
            expected_output='Follow-up emails sent'
        )
    ],
    process=Process.sequential
)

result = sales_crew.kickoff()

Advanced: Hierarchical Process

# Manager agent coordinates email operations
manager = Agent(
    role='Email Operations Manager',
    goal='Coordinate all email activities across the crew',
    tools=[CreateInboxTool(), CheckMessagesTool()],
    backstory='You oversee email operations and delegate tasks.',
    allow_delegation=True
)

# Hierarchical crew with manager
hierarchical_crew = Crew(
    agents=[manager, email_manager, customer_support, researcher],
    tasks=[/* tasks */],
    process=Process.hierarchical,
    manager_llm='gpt-4'
)

result = hierarchical_crew.kickoff()

Crew Memory & Context

from crewai import Crew, Process
from crewai.memory import ConversationMemory

# Crew with memory of email operations
crew = Crew(
    agents=[email_manager, customer_support],
    tasks=[task1, task2, task3],
    process=Process.sequential,
    memory=ConversationMemory(),  # Remembers inbox IDs, past emails, etc.
    verbose=True
)

# Agent can reference previous inboxes without re-creating
result = crew.kickoff(
    inputs={
        'inbox_username': 'support-crew',
        'customer_email': 'customer@example.com'
    }
)

Integration with CrewAI Manager

from crewai import CrewManager

# Manage multiple crews with email capabilities
manager = CrewManager()

# Support crew
support_crew = Crew(
    agents=[/* support agents */],
    tasks=[/* support tasks */]
)

# Sales crew
sales_crew = Crew(
    agents=[/* sales agents */],
    tasks=[/* sales tasks */]
)

# Coordinate crews
manager.add_crew('support', support_crew)
manager.add_crew('sales', sales_crew)

# Run crews in parallel
results = manager.kickoff_all()

Error Handling

class SafeSendEmailTool(BaseTool):
    name: str = "Safe Send Email"
    description: str = "Send email with error handling"

    def _run(self, inbox_id: str, to: str, subject: str, body: str) -> str:
        try:
            result = daimon_client.inboxes.send(inbox_id, {
                'to': to,
                'subject': subject,
                'body': body
            })

            return json.dumps({'success': True, 'message_id': result['message_id']})

        except Exception as error:
            if hasattr(error, 'code') and error.code == 'SEND_REQUIRES_PAID':
                return json.dumps({
                    'success': False,
                    'error': 'UPGRADE_REQUIRED',
                    'message': 'Please upgrade to paid tier to send emails',
                    'upgrade_url': error.upgrade_context.get('operator_action_url')
                })
            else:
                return json.dumps({
                    'success': False,
                    'error': str(error)
                })

Testing Your Crew

# Test crew with mock inbox
def test_support_crew():
    # Create test inbox
    inbox = daimon_client.inboxes.create(
        username='test-crew',
        client_id='test-crew-1'
    )

    # Run crew
    result = support_crew.kickoff(
        inputs={'inbox_id': inbox['result']['id']}
    )

    # Verify results
    assert 'email sent' in result.lower()

    # Clean up
    daimon_client.inboxes.delete(inbox['result']['id'])

Next Steps