"""Global configuration for the Unity agent. The :class:`Settings` dataclass is the single source of truth for runtime parameters such as the Unity installation path, optional LLM API keys, the default output directory and project metadata used when scaffolding a new Unity project. """ from __future__ import annotations import os from dataclasses import dataclass, field, asdict from pathlib import Path from typing import Optional DEFAULT_OUTPUT_DIR = "unity_output" DEFAULT_UNITY_VERSION = "2022.3.20f1" # Default Unity project metadata. These values are written into # ProjectSettings/ProjectSettings.asset so the editor knows what to display # in the project wizard and on the splash screen. DEFAULT_COMPANY_NAME = "UnityAgent" DEFAULT_PRODUCT_NAME = "GeneratedGame" @dataclass class Settings: """Runtime configuration shared by every tool. Parameters ---------- unity_path: Optional path to the Unity executable (``Unity.exe`` / ``Unity``). When provided, the agent can optionally invoke Unity in batch mode to validate that generated projects compile. unity_version: Target Unity version written into ``ProjectSettings.asset``. output_dir: Root directory where generated projects are written. Can be either a relative path (resolved against the current working directory) or an absolute path. company_name / product_name: Metadata written into the project settings. openai_api_key / anthropic_api_key / zai_api_key: Optional LLM provider keys. Only required if the orchestrator is wired up to call an LLM directly. overwrite: If ``True`` existing files are replaced; otherwise a ``FileExistsError`` is raised when a destination file already exists. """ unity_path: Optional[str] = None unity_version: str = DEFAULT_UNITY_VERSION output_dir: str = DEFAULT_OUTPUT_DIR company_name: str = DEFAULT_COMPANY_NAME product_name: str = DEFAULT_PRODUCT_NAME openai_api_key: Optional[str] = field(default_factory=lambda: os.environ.get("OPENAI_API_KEY")) anthropic_api_key: Optional[str] = field(default_factory=lambda: os.environ.get("ANTHROPIC_API_KEY")) zai_api_key: Optional[str] = field(default_factory=lambda: os.environ.get("ZAI_API_KEY")) overwrite: bool = True auto_create_dirs: bool = True # ------------------------------------------------------------------ # # Convenience helpers # ------------------------------------------------------------------ # @property def output_path(self) -> Path: p = Path(self.output_dir) return p if p.is_absolute() else (Path.cwd() / p) def project_path(self, project_name: str) -> Path: """Return the absolute path to a named project inside ``output_dir``.""" return self.output_path / project_name def to_dict(self) -> dict: return asdict(self) @classmethod def from_env(cls) -> "Settings": """Build a :class:`Settings` instance populated from environment vars.""" return cls( unity_path=os.environ.get("UNITY_PATH"), unity_version=os.environ.get("UNITY_VERSION", DEFAULT_UNITY_VERSION), output_dir=os.environ.get("UNITY_AGENT_OUTPUT_DIR", DEFAULT_OUTPUT_DIR), company_name=os.environ.get("UNITY_COMPANY_NAME", DEFAULT_COMPANY_NAME), product_name=os.environ.get("UNITY_PRODUCT_NAME", DEFAULT_PRODUCT_NAME), )