| 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" | |