| """Environment-only runtime configuration for the GAIA agent."""
|
|
|
| from __future__ import annotations
|
|
|
| import os
|
| from dataclasses import dataclass
|
| from pathlib import Path
|
|
|
|
|
| def _int(name: str, default: int) -> int:
|
| try:
|
| return int(os.getenv(name, str(default)))
|
| except ValueError as exc:
|
| raise ValueError(f"{name} must be an integer") from exc
|
|
|
|
|
| def _float(name: str, default: float) -> float:
|
| try:
|
| return float(os.getenv(name, str(default)))
|
| except ValueError as exc:
|
| raise ValueError(f"{name} must be a number") from exc
|
|
|
|
|
| def _bool(name: str, default: bool) -> bool:
|
| value = os.getenv(name)
|
| if value is None:
|
| return default
|
| return value.strip().lower() in {"1", "true", "yes", "on"}
|
|
|
|
|
| @dataclass(frozen=True)
|
| class Settings:
|
| api_url: str
|
| hf_token: str | None
|
| model_id: str
|
| vision_model_id: str
|
| inference_provider: str | None
|
| asr_model_id: str
|
| cache_dir: Path
|
| request_timeout: float
|
| retries: int
|
| backoff_seconds: float
|
| max_steps: int
|
| use_cache: bool
|
| stockfish_path: str | None
|
| fallback_model_id: str | None = None
|
| fallback_provider: str | None = None
|
| worker_limit: int = 3
|
| model_requests_per_minute: float = 20.0
|
| search_requests_per_minute: float = 30.0
|
| user_agent: str = "GAIA-Level1-Agent/1.0 (public Hugging Face Space)"
|
| agent_code_url: str | None = None
|
| allow_inline_agent_code: bool = False
|
| local_model_id: str | None = None
|
| local_model_url: str = "http://127.0.0.1:11434/v1"
|
| prefer_local_model: bool = False
|
|
|
| @classmethod
|
| def from_env(cls) -> Settings:
|
| root = Path(os.getenv("GAIA_CACHE_DIR", "data"))
|
| provider = (
|
| os.getenv("HF_PROVIDER") or os.getenv("HF_INFERENCE_PROVIDER") or None
|
| )
|
| return cls(
|
| api_url=os.getenv(
|
| "GAIA_API_URL", "https://agents-course-unit4-scoring.hf.space"
|
| ).rstrip("/"),
|
| hf_token=os.getenv("HF_TOKEN") or None,
|
| model_id=os.getenv("MODEL_ID")
|
| or os.getenv("GAIA_MODEL_ID", "openai/gpt-oss-120b"),
|
| vision_model_id=os.getenv(
|
| "GAIA_VISION_MODEL_ID", "Qwen/Qwen3-VL-235B-A22B-Instruct"
|
| ),
|
| inference_provider=provider,
|
| asr_model_id=os.getenv("GAIA_ASR_MODEL_ID", "openai/whisper-large-v3"),
|
| cache_dir=root,
|
| request_timeout=_float("GAIA_REQUEST_TIMEOUT", 60.0),
|
| retries=max(1, _int("GAIA_RETRIES", 3)),
|
| backoff_seconds=max(0.0, _float("GAIA_BACKOFF_SECONDS", 1.0)),
|
| max_steps=max(1, _int("GAIA_MAX_STEPS", 10)),
|
| use_cache=_bool("GAIA_USE_CACHE", True),
|
| stockfish_path=os.getenv("STOCKFISH_PATH") or None,
|
| fallback_model_id=os.getenv("FALLBACK_MODEL_ID") or "openai/gpt-oss-20b",
|
| fallback_provider=os.getenv("HF_FALLBACK_PROVIDER") or None,
|
| worker_limit=max(1, _int("GAIA_WORKERS", 3)),
|
| model_requests_per_minute=max(
|
| 1.0, _float("GAIA_MODEL_REQUESTS_PER_MINUTE", 20.0)
|
| ),
|
| search_requests_per_minute=max(
|
| 1.0, _float("GAIA_SEARCH_REQUESTS_PER_MINUTE", 30.0)
|
| ),
|
| user_agent=os.getenv(
|
| "GAIA_USER_AGENT",
|
| "GAIA-Level1-Agent/1.0 (public Hugging Face Space)",
|
| ),
|
| agent_code_url=os.getenv("GAIA_AGENT_CODE_URL") or None,
|
| allow_inline_agent_code=_bool("GAIA_ALLOW_INLINE_AGENT_CODE", False),
|
| local_model_id=os.getenv("GAIA_LOCAL_MODEL_ID") or None,
|
| local_model_url=os.getenv(
|
| "GAIA_LOCAL_MODEL_URL", "http://127.0.0.1:11434/v1"
|
| ).rstrip("/"),
|
| prefer_local_model=_bool("GAIA_PREFER_LOCAL_MODEL", False),
|
| )
|
|
|
| def require_hf_token(self) -> str:
|
| if not self.hf_token:
|
| raise RuntimeError(
|
| "HF_TOKEN is required for inference. Add it as a Hugging Face Space secret."
|
| )
|
| return self.hf_token
|
|
|