Download backend/app/interactive/models.py from ruslanmv/HomePilot: direct link, hf CLI and curl.
- Browser
- Download file 13.1 kB
-
https://huggingface.co/spaces/ruslanmv/HomePilot/resolve/main/backend/app/interactive/models.py
- Command line
-
hf download hf://spaces/ruslanmv/HomePilot/backend/app/interactive/models.py
-
curl -L -o models.py https://huggingface.co/spaces/ruslanmv/HomePilot/resolve/main/backend/app/interactive/models.py
13.1 kB
| """ | |
| Pydantic data contracts for the interactive service. | |
| One model per concept β read-side rows returned by the repo and | |
| write-side create/update payloads used by the router. Field names | |
| map 1:1 to the column names in ``store.py`` so downstream | |
| conversions stay mechanical. | |
| All models allow extra fields on read (``model_config`` below) so | |
| future batches can add columns without breaking existing clients. | |
| """ | |
| from __future__ import annotations | |
| from typing import Any, Dict, List, Literal, Optional | |
| from pydantic import BaseModel, ConfigDict, Field | |
| # Shared config β be permissive on input/output so adding fields | |
| # later never 422s a caller. | |
| _PERMISSIVE = ConfigDict(extra="allow", populate_by_name=True) | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Enumerations (stable string literals) | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| ExperienceMode = Literal[ | |
| "sfw_general", | |
| "sfw_education", | |
| "language_learning", | |
| "enterprise_training", | |
| "social_romantic", | |
| "mature_gated", | |
| ] | |
| ExperienceStatus = Literal[ | |
| "draft", "planning", "building", "ready", "published", "archived", | |
| ] | |
| NodeKind = Literal["scene", "decision", "merge", "ending", "assessment", "remediation"] | |
| EdgeTriggerKind = Literal["choice", "hotspot", "timer", "auto", "fallback", "intent"] | |
| TurnRole = Literal["user", "assistant", "system"] | |
| EventKind = Literal[ | |
| "start", "enter_node", "choose", "hotspot", "drop_off", | |
| "complete", "policy_block", "error", | |
| ] | |
| ProgressionScheme = Literal[ | |
| "xp_level", "mastery", "cefr", "affinity_tier", "certification", | |
| ] | |
| # PublishChannel spans every channel any interactive publisher can | |
| # emit today. Kept as a broad union (rather than an enum) so new | |
| # delivery targets land as additive string additions β the publisher | |
| # + frontend picker enforce which subset is actively wired at runtime. | |
| PublishChannel = Literal[ | |
| "web_embed", "studio_preview", "export", | |
| "lms", "kiosk", "api", | |
| ] | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Experience | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| class ExperienceCreate(BaseModel): | |
| model_config = _PERMISSIVE | |
| title: str | |
| description: str = "" | |
| objective: str = "" | |
| experience_mode: ExperienceMode = "sfw_general" | |
| policy_profile_id: str = "sfw_general" | |
| audience_profile: Dict[str, Any] = Field(default_factory=dict) | |
| project_type: str = "standard" | |
| studio_video_id: Optional[str] = None | |
| tags: List[str] = Field(default_factory=list) | |
| class ExperienceUpdate(BaseModel): | |
| model_config = _PERMISSIVE | |
| title: Optional[str] = None | |
| description: Optional[str] = None | |
| objective: Optional[str] = None | |
| experience_mode: Optional[ExperienceMode] = None | |
| policy_profile_id: Optional[str] = None | |
| audience_profile: Optional[Dict[str, Any]] = None | |
| project_type: Optional[str] = None | |
| status: Optional[ExperienceStatus] = None | |
| tags: Optional[List[str]] = None | |
| class Experience(BaseModel): | |
| model_config = _PERMISSIVE | |
| id: str | |
| user_id: str | |
| studio_video_id: str = "" | |
| title: str | |
| description: str = "" | |
| objective: str = "" | |
| experience_mode: ExperienceMode = "sfw_general" | |
| policy_profile_id: str = "sfw_general" | |
| audience_profile: Dict[str, Any] = Field(default_factory=dict) | |
| project_type: str = "standard" | |
| branch_count: int = 0 | |
| max_depth: int = 0 | |
| status: ExperienceStatus = "draft" | |
| tags: List[str] = Field(default_factory=list) | |
| created_at: Optional[str] = None | |
| updated_at: Optional[str] = None | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Graph β nodes + edges | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| class NodeCreate(BaseModel): | |
| model_config = _PERMISSIVE | |
| kind: NodeKind = "scene" | |
| title: str = "" | |
| narration: str = "" | |
| image_prompt: str = "" | |
| video_prompt: str = "" | |
| duration_sec: int = 5 | |
| storyboard: Dict[str, Any] = Field(default_factory=dict) | |
| interaction_layout: Dict[str, Any] = Field(default_factory=dict) | |
| asset_ids: List[str] = Field(default_factory=list) | |
| class NodeUpdate(BaseModel): | |
| model_config = _PERMISSIVE | |
| kind: Optional[NodeKind] = None | |
| title: Optional[str] = None | |
| narration: Optional[str] = None | |
| image_prompt: Optional[str] = None | |
| video_prompt: Optional[str] = None | |
| duration_sec: Optional[int] = None | |
| storyboard: Optional[Dict[str, Any]] = None | |
| interaction_layout: Optional[Dict[str, Any]] = None | |
| asset_ids: Optional[List[str]] = None | |
| class Node(BaseModel): | |
| model_config = _PERMISSIVE | |
| id: str | |
| experience_id: str | |
| kind: NodeKind | |
| title: str = "" | |
| narration: str = "" | |
| image_prompt: str = "" | |
| video_prompt: str = "" | |
| duration_sec: int = 5 | |
| storyboard: Dict[str, Any] = Field(default_factory=dict) | |
| interaction_layout: Dict[str, Any] = Field(default_factory=dict) | |
| asset_ids: List[str] = Field(default_factory=list) | |
| created_at: Optional[str] = None | |
| updated_at: Optional[str] = None | |
| class EdgeCreate(BaseModel): | |
| model_config = _PERMISSIVE | |
| from_node_id: str | |
| to_node_id: str | |
| trigger_kind: EdgeTriggerKind | |
| trigger_payload: Dict[str, Any] = Field(default_factory=dict) | |
| ordinal: int = 0 | |
| class Edge(BaseModel): | |
| model_config = _PERMISSIVE | |
| id: str | |
| experience_id: str | |
| from_node_id: str | |
| to_node_id: str | |
| trigger_kind: EdgeTriggerKind | |
| trigger_payload: Dict[str, Any] = Field(default_factory=dict) | |
| ordinal: int = 0 | |
| created_at: Optional[str] = None | |
| class NodeVariant(BaseModel): | |
| model_config = _PERMISSIVE | |
| id: str | |
| node_id: str | |
| language: str | |
| narration: str = "" | |
| subtitles: str = "" | |
| audio_asset_id: str = "" | |
| video_asset_id: str = "" | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Runtime β sessions / turns / events | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| class Session(BaseModel): | |
| model_config = _PERMISSIVE | |
| id: str | |
| experience_id: str | |
| viewer_ref: str = "" | |
| current_node_id: str = "" | |
| language: str = "en" | |
| personalization: Dict[str, Any] = Field(default_factory=dict) | |
| consent_version: str = "" | |
| started_at: Optional[str] = None | |
| last_event_at: Optional[str] = None | |
| completed_at: Optional[str] = None | |
| class SessionTurn(BaseModel): | |
| model_config = _PERMISSIVE | |
| id: str | |
| session_id: str | |
| turn_role: TurnRole | |
| text: str | |
| action_id: str = "" | |
| node_id: str = "" | |
| created_at: Optional[str] = None | |
| class SessionEvent(BaseModel): | |
| model_config = _PERMISSIVE | |
| id: str | |
| session_id: str | |
| ts: Optional[str] = None | |
| event_kind: EventKind | |
| node_id: str = "" | |
| edge_id: str = "" | |
| action_id: str = "" | |
| payload: Dict[str, Any] = Field(default_factory=dict) | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Character + assets | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| class CharacterState(BaseModel): | |
| model_config = _PERMISSIVE | |
| id: str | |
| session_id: str | |
| persona_id: str = "" | |
| mood: str = "neutral" | |
| affinity_score: float = 0.5 | |
| outfit_state: Dict[str, Any] = Field(default_factory=dict) | |
| recent_flags: List[str] = Field(default_factory=list) | |
| language: str = "en" | |
| updated_at: Optional[str] = None | |
| class CharacterAsset(BaseModel): | |
| model_config = _PERMISSIVE | |
| id: str | |
| persona_id: str | |
| asset_id: str | |
| kind: str | |
| mood_tags: List[str] = Field(default_factory=list) | |
| action_tags: List[str] = Field(default_factory=list) | |
| language: str = "" | |
| outfit_tags: List[str] = Field(default_factory=list) | |
| duration_sec: float = 0.0 | |
| intensity: float = 0.5 | |
| created_at: Optional[str] = None | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Actions + progression | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| class ActionCreate(BaseModel): | |
| model_config = _PERMISSIVE | |
| label: str | |
| intent_code: str = "" | |
| required_level: int = 1 | |
| required_scheme: str = "xp_level" | |
| required_metric_key: str = "level" | |
| policy_scope: List[str] = Field(default_factory=list) | |
| cooldown_sec: int = 0 | |
| mood_delta: Dict[str, Any] = Field(default_factory=dict) | |
| xp_award: int = 0 | |
| max_uses_per_session: int = 0 | |
| repeat_penalty: float = 0.0 | |
| requires_consent: str = "" | |
| applicable_modes: List[str] = Field(default_factory=list) | |
| category: str = "expression" | |
| edit_recipe: Dict[str, Any] = Field(default_factory=dict) | |
| ordinal: int = 0 | |
| class Action(BaseModel): | |
| model_config = _PERMISSIVE | |
| id: str | |
| experience_id: str | |
| label: str | |
| intent_code: str = "" | |
| required_level: int = 1 | |
| required_scheme: str = "xp_level" | |
| required_metric_key: str = "level" | |
| policy_scope: List[str] = Field(default_factory=list) | |
| cooldown_sec: int = 0 | |
| mood_delta: Dict[str, Any] = Field(default_factory=dict) | |
| xp_award: int = 0 | |
| max_uses_per_session: int = 0 | |
| repeat_penalty: float = 0.0 | |
| requires_consent: str = "" | |
| applicable_modes: List[str] = Field(default_factory=list) | |
| category: str = "expression" | |
| edit_recipe: Dict[str, Any] = Field(default_factory=dict) | |
| ordinal: int = 0 | |
| created_at: Optional[str] = None | |
| class ProgressMetric(BaseModel): | |
| model_config = _PERMISSIVE | |
| id: str | |
| session_id: str | |
| scheme: ProgressionScheme | |
| metric_key: str | |
| metric_value: float | |
| updated_at: Optional[str] = None | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Personalization + intent map | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| class PersonalizationRule(BaseModel): | |
| model_config = _PERMISSIVE | |
| id: str | |
| experience_id: str | |
| name: str | |
| condition: Dict[str, Any] = Field(default_factory=dict) | |
| action: Dict[str, Any] = Field(default_factory=dict) | |
| priority: int = 100 | |
| enabled: bool = True | |
| created_at: Optional[str] = None | |
| class IntentMapEntry(BaseModel): | |
| model_config = _PERMISSIVE | |
| id: str | |
| experience_id: str | |
| intent_code: str | |
| action_id: str = "" | |
| fallback_node_id: str = "" | |
| priority: int = 100 | |
| applicable_modes: List[str] = Field(default_factory=list) | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Publishing + QA | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| class Publication(BaseModel): | |
| model_config = _PERMISSIVE | |
| id: str | |
| experience_id: str | |
| channel: PublishChannel | |
| manifest_url: str = "" | |
| version: int = 1 | |
| metadata: Dict[str, Any] = Field(default_factory=dict) | |
| published_at: Optional[str] = None | |
| class QAReport(BaseModel): | |
| model_config = _PERMISSIVE | |
| id: str | |
| experience_id: str | |
| kind: str # 'walk' | 'lint' | 'content_check' | |
| summary: Dict[str, Any] = Field(default_factory=dict) | |
| issues: List[Dict[str, Any]] = Field(default_factory=list) | |
| created_at: Optional[str] = None | |