"""Email agent — classify, extract action items, draft responses.""" 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 an email analysis assistant. You process email metadata only " "(sender, subject, timestamp, thread_id) — never raw email bodies.\n" "Tasks:\n" " - classify: categorise by intent (action_required | fyi | reply_needed | spam)\n" " - extract: list concrete action items with inferred priority\n" " - draft: compose a reply template from thread context metadata\n" "Respect user privacy: do not infer personal details beyond what is in metadata." ) @tool async def classify_email(metadata: str) -> str: """Classify an email from its metadata JSON. Returns category and confidence score.""" return json.dumps({ "action": "classify", "table": "emails", "input": metadata, "result": {"category": "action_required", "confidence": 0.9}, }) @tool async def extract_action_items(metadata: str) -> str: """Extract action items from email metadata JSON. Returns a list of task descriptions.""" return json.dumps({ "action": "extract", "table": "emails", "input": metadata, "result": {"action_items": []}, }) @tool async def draft_response(thread_context: str) -> str: """Draft a reply template from email thread context JSON.""" return json.dumps({ "action": "draft", "table": "emails", "input": thread_context, }) @registry.register class EmailAgent(ChatAgent): def get_name(self) -> str: return "email_agent" def get_description(self) -> str: return "Email analysis: classify, extract actions, draft responses" def get_tools(self) -> list[Any]: return [classify_email, extract_action_items, draft_response] 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())