manikandanj's picture
Prepare AI Time Machine hackathon Space
5862322 verified
Raw
History Blame Contribute Delete
5.34 kB
from __future__ import annotations
from datetime import datetime, timezone
from typing import Any, Literal
from uuid import uuid4
from pydantic import BaseModel, ConfigDict, Field, computed_field
def utc_now() -> datetime:
return datetime.now(timezone.utc)
class StrictModel(BaseModel):
model_config = ConfigDict(extra="forbid", validate_assignment=True)
class VisualMotif(StrictModel):
key: str
label: str
palette: list[str] = Field(default_factory=list)
motion: str | None = None
class Destination(StrictModel):
year: str
place: str
mode: Literal["past", "future", "strange"]
atmosphere: str
visual_preset_key: str
visual_motifs: list[VisualMotif] = Field(default_factory=list)
temporal_oddity: str | None = None
class Persona(StrictModel):
name: str
local_identifier: str | None = None
role: str
immediate_situation: str
daily_concern: str
secret_or_desire: str
worldview_constraints: list[str] = Field(default_factory=list)
voice_theory: str
speaking_style: str
safety_notes: list[str] = Field(default_factory=list)
class VoiceProfile(StrictModel):
voice_id: str
description: str
pace: Literal["slow", "medium", "fast"] = "medium"
emotion: str = "curious"
accent_hint: str | None = None
class ConversationTurn(StrictModel):
role: Literal["user", "character", "machine"]
text: str
audio_path: str | None = None
metadata: dict[str, Any] = Field(default_factory=dict)
created_at: datetime = Field(default_factory=utc_now)
class ConversationHistory(StrictModel):
turns: list[ConversationTurn] = Field(default_factory=list)
def append(self, turn: ConversationTurn) -> None:
self.turns.append(turn)
def character_turns(self) -> list[ConversationTurn]:
return [turn for turn in self.turns if turn.role == "character"]
class ConversationResponse(StrictModel):
text: str
prosody_hint: str | None = None
ui_signal_event: str | None = None
class Transcript(StrictModel):
text: str
confidence: float | None = Field(default=None, ge=0, le=1)
language: str | None = None
is_final: bool = True
class AudioResult(StrictModel):
path: str | None = None
mime_type: str = "audio/wav"
duration_seconds: float | None = Field(default=None, ge=0)
description: str | None = None
class ImmersiveScene(StrictModel):
prompt: str
image_b64: str | None = None
mime_type: str = "image/png"
ambient_key: str = "temporal_storm"
visual_style: str = "surreal cinematic time portal"
description: str | None = None
class CharacterPortrait(StrictModel):
prompt: str
image_b64: str | None = None
mime_type: str = "image/png"
description: str | None = None
class Narration(StrictModel):
text: str
audio: AudioResult | None = None
voice_profile: VoiceProfile | None = None
class VisualArtifact(StrictModel):
title: str
kind: str
description: str
prompt: str
image_b64: str | None = None
mime_type: str = "image/png"
class Souvenir(StrictModel):
destination: str
contact: str
quote: str
artifact: str
stamp_name: str
summary: str
class EncounterSession(StrictModel):
session_id: str
encounter_id: str = Field(default_factory=lambda: str(uuid4()))
destination: Destination | None = None
persona: Persona | None = None
voice_profile: VoiceProfile | None = None
scene: ImmersiveScene | None = None
portrait: CharacterPortrait | None = None
narration: Narration | None = None
artifact: VisualArtifact | None = None
history: ConversationHistory = Field(default_factory=ConversationHistory)
souvenir: Souvenir | None = None
created_at: datetime = Field(default_factory=utc_now)
updated_at: datetime = Field(default_factory=utc_now)
def touch(self) -> None:
self.updated_at = utc_now()
class SavedEncounter(StrictModel):
encounter_id: str
session_id: str
path: str
saved_at: datetime = Field(default_factory=utc_now)
class ModelSpec(StrictModel):
role: str
provider: str
model_id: str
parameters_billion: float = Field(ge=0)
enabled: bool = True
runtime: str
license: str | None = None
notes: str | None = None
class ModelBudget(StrictModel):
models: list[ModelSpec] = Field(default_factory=list)
parameter_limit_billion: float = 32.0
@computed_field
@property
def enabled_parameters_billion(self) -> float:
return round(
sum(model.parameters_billion for model in self.models if model.enabled),
3,
)
@computed_field
@property
def largest_enabled_parameters_billion(self) -> float:
enabled = [model.parameters_billion for model in self.models if model.enabled]
return round(max(enabled, default=0.0), 3)
@computed_field
@property
def is_within_limit(self) -> bool:
return all(
model.parameters_billion <= self.parameter_limit_billion
for model in self.models
if model.enabled
)