from dataclasses import dataclass, field from typing import Dict, List, Optional, Literal, TypedDict from datetime import datetime from uuid import uuid4 import random class CharacterTemplate(TypedDict): name: str observations: List[str] reflections: List[str] plans: List[str] yaml_file: str @dataclass class Memory: """A single memory object with Stanford's architecture""" description: str creation_time: datetime = field(default_factory=datetime.now) last_accessed: datetime = field(default_factory=datetime.now) importance_score: int = 5 # 1-10 scale embedding: Optional[List[float]] = None memory_type: Literal["observation", "reflection", "plan"] = "observation" related_memories: List['Memory'] = field(default_factory=list) # IDs of supporting memories def __post_init__(self): if self.last_accessed is None: self.last_accessed = self.creation_time @dataclass class CharacterTrait: name: str description: str strength: int = 0 updated: datetime = field(default_factory=datetime.now) def change_by_probability(self, steepness: float = 1.0) -> float: """ Returns probability of trait change (0.0 to 1.0) steepness: higher values = more resistance to change steepness = 1.0 (moderate): Strength 1: 90% chance Strength 5: 50% chance Strength 9: 10% chance steepness = 2.0 (steep): Strength 1: 81% chance Strength 5: 25% chance Strength 9: 1% chance steepness = 0.5 (gradual): Strength 1: 95% chance Strength 5: 71% chance Strength 9: 32% chance """ return (10 - self.strength) / 10.0 ** steepness @dataclass class Character: name: str age: Optional[int] = None personality: str = "" occupation: str = "" location: str = "" traits: List[CharacterTrait] = field(default_factory=list) relationships: Dict[str, str] = field(default_factory=dict) goals: List[str] = field(default_factory=list) _id: str = field(default_factory=lambda: str(uuid4())[:8]) def get_trait(self, trait_name, trait_description) -> CharacterTrait: for trait in self.traits: if trait.name.lower() == trait_name.lower(): return trait self.traits.append(CharacterTrait(name=trait_name.lower(), strength=0, description=trait_description)) return self.traits[-1] def __hash__(self): return hash(self._id) def __eq__(self, other): return isinstance(other, Character) and self._id == other._id