from __future__ import annotations from typing import Literal from pydantic import BaseModel, Field class EmailData(BaseModel): subject: str body: str class ClassifyRequest(BaseModel): email_data: EmailData provider: Literal["openai", "anthropic"] | None = None model: str | None = None base_url: str | None = None api_key: str | None = Field(default=None, exclude=True) temperature: float | None = None message_id: str | None = None thread_id: str | None = None from_address: str | None = None received_at: str | None = None class ClassificationDetails(BaseModel): summary: str | None = None suggested_title: str | None = None suggested_notes: str | None = None deadline: str | None = None people: list[str] = Field(default_factory=list) organizations: list[str] = Field(default_factory=list) attachments_referenced: list[str] = Field(default_factory=list) next_steps: list[str] = Field(default_factory=list) key_points: list[str] = Field(default_factory=list) source_signals: list[str] = Field(default_factory=list) dedupe_key: str | None = None class TodoistSyncResult(BaseModel): status: Literal["created", "updated", "unchanged", "disabled", "skipped", "error"] task_id: str | None = None comment_added: bool = False dedupe_match: Literal["message_id", "thread_id", "fingerprint", "none"] = "none" message: str | None = None class ClassificationResult(BaseModel): needs_action: bool category: Literal["action_required", "question", "fyi", "newsletter", "promotional", "automated", "alert", "uncategorized"] priority: Literal["high", "medium", "low"] task_description: str | None = None reasoning: str confidence: float details: ClassificationDetails | None = None todoist: TodoistSyncResult | None = None