from __future__ import annotations from datetime import datetime, timezone from typing import Any, Literal from pydantic import BaseModel, ConfigDict, Field from time_machine.domain.models import ( AudioResult, CharacterPortrait, Destination, ImmersiveScene, Narration, Persona, Souvenir, Transcript, VisualArtifact, ) def utc_now() -> datetime: return datetime.now(timezone.utc) class TemporalEvent(BaseModel): model_config = ConfigDict(extra="forbid") event_type: str message: str | None = None created_at: datetime = Field(default_factory=utc_now) metadata: dict[str, Any] = Field(default_factory=dict) class MachineStateEvent(TemporalEvent): event_type: Literal["machine_state"] = "machine_state" state: str class DestinationEvent(TemporalEvent): event_type: Literal["destination"] = "destination" destination: Destination class PersonaEvent(TemporalEvent): event_type: Literal["persona"] = "persona" persona: Persona class TranscriptEvent(TemporalEvent): event_type: Literal["transcript"] = "transcript" transcript: Transcript class ConversationTextEvent(TemporalEvent): event_type: Literal["conversation_text"] = "conversation_text" text: str is_final: bool = True class AudioEvent(TemporalEvent): event_type: Literal["audio"] = "audio" audio: AudioResult class SceneEvent(TemporalEvent): event_type: Literal["scene"] = "scene" scene: ImmersiveScene class PortraitEvent(TemporalEvent): event_type: Literal["portrait"] = "portrait" portrait: CharacterPortrait class NarrationEvent(TemporalEvent): event_type: Literal["narration"] = "narration" narration: Narration class VisualArtifactEvent(TemporalEvent): event_type: Literal["visual_artifact"] = "visual_artifact" artifact: VisualArtifact class SouvenirEvent(TemporalEvent): event_type: Literal["souvenir"] = "souvenir" souvenir: Souvenir class ErrorEvent(TemporalEvent): event_type: Literal["error"] = "error" severity: Literal["recoverable", "fatal"] = "recoverable"