from datetime import datetime from enum import StrEnum from typing import Any, Literal from uuid import UUID, uuid4 from pydantic import BaseModel, ConfigDict, Field class ActionStatus(StrEnum): CREATED = "created" PENDING_REVIEW = "pending_review" APPROVED = "approved" REJECTED = "rejected" EXECUTED = "executed" EXECUTION_FAILED = "execution_failed" class EventType(StrEnum): CONVERSATION_EVENT = "ConversationEvent" ACTION_CREATED = "ActionCreated" ACTION_REJECTED = "ActionRejected" ACTION_EXECUTED = "ActionExecuted" API_CALL_GENERATED = "ApiCallGenerated" MEMORY_UPDATED = "MemoryUpdated" CONVERSATION_SUMMARIZED = "ConversationSummarized" class TranscriptChunk(BaseModel): speaker: str timestamp: datetime text: str = Field(min_length=1) class ConversationEvent(BaseModel): id: UUID = Field(default_factory=uuid4) request_id: str meeting_id: str = "demo-meeting" chunk: TranscriptChunk class ToolDefinition(BaseModel): name: str description: str method: Literal["GET", "POST", "PATCH", "PUT", "DELETE"] path: str schema: dict[str, Any] required: list[str] = Field(default_factory=list) path_params: list[str] = Field(default_factory=list) class PlannerDecision(BaseModel): intent: str confidence: float = Field(ge=0, le=1) reasoning: str tool: str | None = None arguments: dict[str, Any] = Field(default_factory=dict) extracted_entities: dict[str, Any] = Field(default_factory=dict) class ValidationResult(BaseModel): valid: bool errors: list[str] = Field(default_factory=list) class PolicyResult(BaseModel): allowed: bool reasons: list[str] = Field(default_factory=list) class PendingActionCreate(BaseModel): meeting_id: str tool: str intent: str reasoning: str confidence: float payload: dict[str, Any] extracted_entities: dict[str, Any] = Field(default_factory=dict) validation: ValidationResult policy: PolicyResult class PendingActionRead(PendingActionCreate): model_config = ConfigDict(from_attributes=True) id: int status: ActionStatus created_at: datetime updated_at: datetime execution_result: dict[str, Any] | None = None class PendingActionUpdate(BaseModel): payload: dict[str, Any] | None = None class TaskCreate(BaseModel): title: str assignee: str | None = None due_date: datetime | None = None status: Literal["pending", "in_progress", "done"] = "pending" class TaskPatch(BaseModel): title: str | None = None assignee: str | None = None due_date: datetime | None = None status: Literal["pending", "in_progress", "done"] | None = None class TaskRead(TaskCreate): model_config = ConfigDict(from_attributes=True) id: int created_at: datetime class NoteCreate(BaseModel): content: str category: Literal["general", "preference", "vendor", "budget"] = "general" class NoteRead(NoteCreate): model_config = ConfigDict(from_attributes=True) id: int created_at: datetime class ReservationCreate(BaseModel): vendor: str reservation_date: datetime status: Literal["pending", "reserved", "cancelled"] = "pending" class ReservationPatch(BaseModel): vendor: str | None = None reservation_date: datetime | None = None status: Literal["pending", "reserved", "cancelled"] | None = None class ReservationRead(BaseModel): model_config = ConfigDict(from_attributes=True) id: int vendor: str reservation_date: datetime status: str created_at: datetime class DashboardRead(BaseModel): transcript: list[TranscriptChunk] context: dict[str, Any] memories: list[dict[str, Any]] pending_actions: list[PendingActionRead] tasks: list[TaskRead] notes: list[NoteRead] reservations: list[ReservationRead] events: list[dict[str, Any]] class TranscriptSegment(BaseModel): id: str speaker: str original_text: str edited_text: str start_ms: int end_ms: int class TranscriptionJobRead(BaseModel): job_id: str status: Literal["uploading", "queued", "processing", "completed", "error"] transcription_id: str | None = None segments: list[TranscriptSegment] = Field(default_factory=list) generated_action_ids: list[int] = Field(default_factory=list) error: str | None = None created_at: datetime