"""Matrix configuration loader utility. Provides a typed dataclass for Matrix world configuration and a loader that fetches settings from YAML with sensible defaults. """ import logging from dataclasses import dataclass, field from pathlib import Path from typing import Any import yaml logger = logging.getLogger(__name__) @dataclass class PointLight: """A single point light in the Matrix world.""" color: str = "#FFFFFF" intensity: float = 1.0 position: dict[str, float] = field(default_factory=lambda: {"x": 0, "y": 0, "z": 0}) @classmethod def from_dict(cls, data: dict[str, Any]) -> "PointLight": """Create a PointLight from a dictionary with defaults.""" return cls( color=data.get("color", "#FFFFFF"), intensity=data.get("intensity", 1.0), position=data.get("position", {"x": 0, "y": 0, "z": 0}), ) def _default_point_lights_factory() -> list[PointLight]: """Factory function for default point lights.""" return [ PointLight( color="#FFAA55", # Warm amber (Workshop) intensity=1.2, position={"x": 0, "y": 5, "z": 0}, ), PointLight( color="#3B82F6", # Cool blue (Matrix) intensity=0.8, position={"x": -5, "y": 3, "z": -5}, ), PointLight( color="#A855F7", # Purple accent intensity=0.6, position={"x": 5, "y": 3, "z": 5}, ), ] @dataclass class LightingConfig: """Lighting configuration for the Matrix world.""" ambient_color: str = "#FFAA55" # Warm amber (Workshop warmth) ambient_intensity: float = 0.5 point_lights: list[PointLight] = field(default_factory=_default_point_lights_factory) @classmethod def from_dict(cls, data: dict[str, Any] | None) -> "LightingConfig": """Create a LightingConfig from a dictionary with defaults.""" if data is None: data = {} point_lights_data = data.get("point_lights", []) point_lights = ( [PointLight.from_dict(pl) for pl in point_lights_data] if point_lights_data else _default_point_lights_factory() ) return cls( ambient_color=data.get("ambient_color", "#FFAA55"), ambient_intensity=data.get("ambient_intensity", 0.5), point_lights=point_lights, ) @dataclass class EnvironmentConfig: """Environment settings for the Matrix world.""" rain_enabled: bool = False starfield_enabled: bool = True fog_color: str = "#0f0f23" fog_density: float = 0.02 @classmethod def from_dict(cls, data: dict[str, Any] | None) -> "EnvironmentConfig": """Create an EnvironmentConfig from a dictionary with defaults.""" if data is None: data = {} return cls( rain_enabled=data.get("rain_enabled", False), starfield_enabled=data.get("starfield_enabled", True), fog_color=data.get("fog_color", "#0f0f23"), fog_density=data.get("fog_density", 0.02), ) @dataclass class FeaturesConfig: """Feature toggles for the Matrix world.""" chat_enabled: bool = True visitor_avatars: bool = True pip_familiar: bool = True workshop_portal: bool = True @classmethod def from_dict(cls, data: dict[str, Any] | None) -> "FeaturesConfig": """Create a FeaturesConfig from a dictionary with defaults.""" if data is None: data = {} return cls( chat_enabled=data.get("chat_enabled", True), visitor_avatars=data.get("visitor_avatars", True), pip_familiar=data.get("pip_familiar", True), workshop_portal=data.get("workshop_portal", True), ) @dataclass class AgentConfig: """Configuration for a single Matrix agent.""" name: str = "" role: str = "" enabled: bool = True @classmethod def from_dict(cls, data: dict[str, Any]) -> "AgentConfig": """Create an AgentConfig from a dictionary with defaults.""" return cls( name=data.get("name", ""), role=data.get("role", ""), enabled=data.get("enabled", True), ) @dataclass class AgentsConfig: """Agent registry configuration.""" default_count: int = 5 max_count: int = 20 agents: list[AgentConfig] = field(default_factory=list) @classmethod def from_dict(cls, data: dict[str, Any] | None) -> "AgentsConfig": """Create an AgentsConfig from a dictionary with defaults.""" if data is None: data = {} agents_data = data.get("agents", []) agents = [AgentConfig.from_dict(a) for a in agents_data] if agents_data else [] return cls( default_count=data.get("default_count", 5), max_count=data.get("max_count", 20), agents=agents, ) @dataclass class MatrixConfig: """Complete Matrix world configuration. Combines lighting, environment, features, and agent settings into a single configuration object. """ lighting: LightingConfig = field(default_factory=LightingConfig) environment: EnvironmentConfig = field(default_factory=EnvironmentConfig) features: FeaturesConfig = field(default_factory=FeaturesConfig) agents: AgentsConfig = field(default_factory=AgentsConfig) @classmethod def from_dict(cls, data: dict[str, Any] | None) -> "MatrixConfig": """Create a MatrixConfig from a dictionary with defaults for missing sections.""" if data is None: data = {} return cls( lighting=LightingConfig.from_dict(data.get("lighting")), environment=EnvironmentConfig.from_dict(data.get("environment")), features=FeaturesConfig.from_dict(data.get("features")), agents=AgentsConfig.from_dict(data.get("agents")), ) def to_dict(self) -> dict[str, Any]: """Convert the configuration to a plain dictionary.""" return { "lighting": { "ambient_color": self.lighting.ambient_color, "ambient_intensity": self.lighting.ambient_intensity, "point_lights": [ { "color": pl.color, "intensity": pl.intensity, "position": pl.position, } for pl in self.lighting.point_lights ], }, "environment": { "rain_enabled": self.environment.rain_enabled, "starfield_enabled": self.environment.starfield_enabled, "fog_color": self.environment.fog_color, "fog_density": self.environment.fog_density, }, "features": { "chat_enabled": self.features.chat_enabled, "visitor_avatars": self.features.visitor_avatars, "pip_familiar": self.features.pip_familiar, "workshop_portal": self.features.workshop_portal, }, "agents": { "default_count": self.agents.default_count, "max_count": self.agents.max_count, "agents": [ {"name": a.name, "role": a.role, "enabled": a.enabled} for a in self.agents.agents ], }, } def load_from_yaml(path: str | Path) -> MatrixConfig: """Load Matrix configuration from a YAML file. Missing keys are filled with sensible defaults. If the file cannot be read or parsed, returns a fully default configuration. Args: path: Path to the YAML configuration file. Returns: A MatrixConfig instance with loaded or default values. """ path = Path(path) if not path.exists(): logger.warning("Matrix config file not found: %s, using defaults", path) return MatrixConfig() try: with open(path, encoding="utf-8") as f: raw_data = yaml.safe_load(f) if not isinstance(raw_data, dict): logger.warning("Matrix config invalid format, using defaults") return MatrixConfig() return MatrixConfig.from_dict(raw_data) except yaml.YAMLError as exc: logger.warning("Matrix config YAML parse error: %s, using defaults", exc) return MatrixConfig() except OSError as exc: logger.warning("Matrix config read error: %s, using defaults", exc) return MatrixConfig()