| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 |
- from __future__ import annotations
- from functools import lru_cache
- from pathlib import Path
- from typing import Self
- from pydantic import Field, model_validator
- from pydantic_settings import BaseSettings, SettingsConfigDict
- from supply_agent.paths import resolve_path
- class Settings(BaseSettings):
- """Application settings loaded from environment variables or .env file."""
- model_config = SettingsConfigDict(
- env_file=".env",
- env_file_encoding="utf-8",
- extra="ignore",
- )
- # OpenRouter
- openrouter_api_key: str = Field(..., alias="OPENROUTER_API_KEY")
- openrouter_model: str = Field(
- default="google/gemini-2.5-flash",
- alias="OPENROUTER_MODEL",
- )
- openrouter_base_url: str = Field(
- default="https://openrouter.ai/api/v1",
- alias="OPENROUTER_BASE_URL",
- )
- openrouter_site_url: str = Field(default="", alias="OPENROUTER_SITE_URL")
- openrouter_site_name: str = Field(default="SupplyAgent", alias="OPENROUTER_SITE_NAME")
- # Agent
- agent_max_iterations: int = Field(default=20, alias="AGENT_MAX_ITERATIONS")
- agent_temperature: float = Field(default=0.7, alias="AGENT_TEMPERATURE")
- # Skills
- skills_dir: Path = Field(default=Path("skills"), alias="SKILLS_DIR")
- # Logging
- logs_dir: Path = Field(default=Path("logs"), alias="LOGS_DIR")
- log_enabled: bool = Field(default=True, alias="LOG_ENABLED")
- @model_validator(mode="after")
- def resolve_relative_paths(self) -> Self:
- """Resolve skills_dir and logs_dir against project root when needed."""
- self.skills_dir = resolve_path(self.skills_dir)
- self.logs_dir = resolve_path(self.logs_dir)
- return self
- @classmethod
- def from_env(cls, **overrides: object) -> Self:
- """Create settings with optional overrides (useful for testing)."""
- return cls(**overrides) # type: ignore[arg-type]
- @lru_cache
- def get_settings() -> Settings:
- return Settings() # type: ignore[call-arg]
|