"""
Personal Assistant Supervisor Example
This example demonstrates the tool calling pattern for multi-agent systems.
A supervisor agent coordinates specialized sub-agents (calendar and email)
that are wrapped as tools.
"""
from langchain_core.tools import tool
from langchain.agents import create_agent
from langchain.chat_models import init_chat_model
# ============================================================================
# Step 1: Define low-level API tools (stubbed)
# ============================================================================
@tool
def create_calendar_event(
title: str,
start_time: str, # ISO format: "2024-01-15T14:00:00"
end_time: str, # ISO format: "2024-01-15T15:00:00"
attendees: list[str], # email addresses
location: str = ""
) -> str:
"""Create a calendar event. Requires exact ISO datetime format."""
return f"Event created: {title} from {start_time} to {end_time} with {len(attendees)} attendees"
@tool
def send_email(
to: list[str], # email addresses
subject: str,
body: str,
cc: list[str] = []
) -> str:
"""Send an email via email API. Requires properly formatted addresses."""
return f"Email sent to {', '.join(to)} - Subject: {subject}"
@tool
def get_available_time_slots(
attendees: list[str],
date: str, # ISO format: "2024-01-15"
duration_minutes: int
) -> list[str]:
"""Check calendar availability for given attendees on a specific date."""
return ["09:00", "14:00", "16:00"]
# ============================================================================
# Step 2: Create specialized sub-agents
# ============================================================================
model = init_chat_model("claude-haiku-4-5-20251001") # for example
calendar_agent = create_agent(
model,
tools=[create_calendar_event, get_available_time_slots],
system_prompt=(
"You are a calendar scheduling assistant. "
"Parse natural language scheduling requests (e.g., 'next Tuesday at 2pm') "
"into proper ISO datetime formats. "
"Use get_available_time_slots to check availability when needed. "
"Use create_calendar_event to schedule events. "
"Always confirm what was scheduled in your final response."
)
)
email_agent = create_agent(
model,
tools=[send_email],
system_prompt=(
"You are an email assistant. "
"Compose professional emails based on natural language requests. "
"Extract recipient information and craft appropriate subject lines and body text. "
"Use send_email to send the message. "
"Always confirm what was sent in your final response."
)
)
# ============================================================================
# Step 3: Wrap sub-agents as tools for the supervisor
# ============================================================================
@tool
def schedule_event(request: str) -> str:
"""Schedule calendar events using natural language.
Use this when the user wants to create, modify, or check calendar appointments.
Handles date/time parsing, availability checking, and event creation.
Input: Natural language scheduling request (e.g., 'meeting with design team
next Tuesday at 2pm')
"""
result = calendar_agent.invoke({
"messages": [{"role": "user", "content": request}]
})
return result["messages"][-1].text
@tool
def manage_email(request: str) -> str:
"""Send emails using natural language.
Use this when the user wants to send notifications, reminders, or any email
communication. Handles recipient extraction, subject generation, and email
composition.
Input: Natural language email request (e.g., 'send them a reminder about
the meeting')
"""
result = email_agent.invoke({
"messages": [{"role": "user", "content": request}]
})
return result["messages"][-1].text
# ============================================================================
# Step 4: Create the supervisor agent
# ============================================================================
supervisor_agent = create_agent(
model,
tools=[schedule_event, manage_email],
system_prompt=(
"You are a helpful personal assistant. "
"You can schedule calendar events and send emails. "
"Break down user requests into appropriate tool calls and coordinate the results. "
"When a request involves multiple actions, use multiple tools in sequence."
)
)
# ============================================================================
# Step 5: Use the supervisor
# ============================================================================
if __name__ == "__main__":
# Example: User request requiring both calendar and email coordination
user_request = (
"Schedule a meeting with the design team next Tuesday at 2pm for 1 hour, "
"and send them an email reminder about reviewing the new mockups."
)
print("User Request:", user_request)
print("\n" + "="*80 + "\n")
for step in supervisor_agent.stream(
{"messages": [{"role": "user", "content": user_request}]}
):
for update in step.values():
for message in update.get("messages", []):
message.pretty_print()