"""Runtime configuration, entirely from the environment. Nothing here has a value that would be wrong to commit, so the defaults are the lab's real endpoints. The one secret — this agent's Keycloak client secret — has no default and fails loudly if unset. """ from __future__ import annotations from pydantic import Field from pydantic_settings import BaseSettings, SettingsConfigDict class Settings(BaseSettings): model_config = SettingsConfigDict(env_prefix="ASSISTANT_", env_file=".env") # --- identity ----------------------------------------------------------- keycloak_realm_url: str = "https://keycloak.sttlab.local/realms/classic-models" client_id: str = "classic-models-agent-assistant" client_secret: str = Field(..., description="Keycloak client secret; no default on purpose") # --- inference ---------------------------------------------------------- # This agent has no data of its own. The only thing it may reach besides # other agents is the inference endpoint, and the realm enforces exactly # that: `classic-models-agent-assistant` is granted two optional scopes, one # per specialist plus this one. Every domain audience it could ask for comes # back `Invalid scopes`. llm_base_url: str = "https://llm-dev.sttlab.local/llm/v1" llm_model: str = "google/gemini-3.7-flash" llm_scope: str = "llm-proxy-audience" # --- transport ---------------------------------------------------------- # The lab uses a private CA. Point this at the bundle rather than disabling # verification. See the note on `.local` names in the README: macOS resolves # them through mDNS and takes ~5s per host, which is why the timeout is not # the usual 5 or 10. ca_bundle: str | None = None http_timeout: float = 60.0 # A turn that fans out and loops has to stop somewhere. Counted in # delegations, not in model calls — one specialist consulted twice for the # same question is the loop worth catching. max_delegations: int = 8 host: str = "0.0.0.0" port: int = 8080 # Advertised in the Agent Card, so it must be the URL other callers reach, # not the bind address. public_url: str = "http://localhost:8080/" @property def token_endpoint(self) -> str: return f"{self.keycloak_realm_url}/protocol/openid-connect/token" @property def verify(self) -> str | bool: return self.ca_bundle if self.ca_bundle else True