config.py 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. from __future__ import annotations
  2. from functools import lru_cache
  3. from pathlib import Path
  4. from typing import Self
  5. from pydantic import Field, model_validator
  6. from pydantic_settings import BaseSettings, SettingsConfigDict
  7. from supply_agent.paths import resolve_path
  8. class Settings(BaseSettings):
  9. """Application settings loaded from environment variables or .env file."""
  10. model_config = SettingsConfigDict(
  11. env_file=".env",
  12. env_file_encoding="utf-8",
  13. extra="ignore",
  14. )
  15. # OpenRouter
  16. openrouter_api_key: str = Field(..., alias="OPENROUTER_API_KEY")
  17. openrouter_model: str = Field(
  18. default="google/gemini-2.5-flash",
  19. alias="OPENROUTER_MODEL",
  20. )
  21. openrouter_base_url: str = Field(
  22. default="https://openrouter.ai/api/v1",
  23. alias="OPENROUTER_BASE_URL",
  24. )
  25. openrouter_site_url: str = Field(default="", alias="OPENROUTER_SITE_URL")
  26. openrouter_site_name: str = Field(default="SupplyAgent", alias="OPENROUTER_SITE_NAME")
  27. # Agent
  28. agent_max_iterations: int = Field(default=20, alias="AGENT_MAX_ITERATIONS")
  29. agent_temperature: float = Field(default=0.7, alias="AGENT_TEMPERATURE")
  30. # Skills
  31. skills_dir: Path = Field(default=Path("skills"), alias="SKILLS_DIR")
  32. # Logging
  33. logs_dir: Path = Field(default=Path("logs"), alias="LOGS_DIR")
  34. log_enabled: bool = Field(default=True, alias="LOG_ENABLED")
  35. @model_validator(mode="after")
  36. def resolve_relative_paths(self) -> Self:
  37. """Resolve skills_dir and logs_dir against project root when needed."""
  38. self.skills_dir = resolve_path(self.skills_dir)
  39. self.logs_dir = resolve_path(self.logs_dir)
  40. return self
  41. @classmethod
  42. def from_env(cls, **overrides: object) -> Self:
  43. """Create settings with optional overrides (useful for testing)."""
  44. return cls(**overrides) # type: ignore[arg-type]
  45. @lru_cache
  46. def get_settings() -> Settings:
  47. return Settings() # type: ignore[call-arg]