Files
api/app/agents/calendar_agent.py
2026-03-02 13:18:53 +01:00

77 lines
2.4 KiB
Python

"""Calendar agent — events, conflict detection, and scheduling."""
from __future__ import annotations
import json
from typing import Any
from langchain_core.messages import HumanMessage, SystemMessage
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from app.config.settings import settings
from app.core.agent_registry import ChatAgent, registry
_SYSTEM_PROMPT = (
"You are a calendar management assistant. Help the user manage events, "
"detect scheduling conflicts, and suggest reschedules.\n"
"Rules:\n"
" - Work exclusively with event metadata provided in context\n"
" - Never store or reference raw calendar data\n"
" - date_range format: ISO 8601 interval, e.g. '2024-01-01/2024-01-07'\n"
" - Always confirm the date/time scope of any operation"
)
@tool
async def list_events(date_range: str) -> str:
"""List calendar events in a date range (ISO 8601 interval, e.g. '2024-01-01/2024-01-07')."""
return json.dumps({
"action": "list",
"table": "events",
"filters": {"date_range": date_range},
})
@tool
async def detect_conflicts(events: str) -> str:
"""Detect scheduling conflicts in a JSON array of event metadata objects."""
return json.dumps({
"action": "analyse",
"table": "events",
"input": events,
"result": "conflicts_detected",
})
@tool
async def suggest_reschedule(conflict: str) -> str:
"""Suggest a reschedule for a conflicting event. Pass the conflict as a JSON string."""
return json.dumps({
"action": "suggest_reschedule",
"table": "events",
"input": conflict,
})
@registry.register
class CalendarAgent(ChatAgent):
def get_name(self) -> str:
return "calendar_agent"
def get_description(self) -> str:
return "Calendar management: events, conflicts, scheduling"
def get_tools(self) -> list[Any]:
return [list_events, detect_conflicts, suggest_reschedule]
async def handle(self, query: str, context: dict[str, Any]) -> str:
llm = ChatOpenAI(model="gpt-4o", temperature=0, api_key=settings.OPENAI_API_KEY)
messages = [
SystemMessage(content=_SYSTEM_PROMPT),
HumanMessage(
content=f"User query: {query}\nContext: {json.dumps(context)[:1000]}"
),
]
return await self._tool_loop(llm, messages, self.get_tools())