Spaces:
Running on Zero
Running on Zero
| """Configuration helpers for the GCMD classifier MVP.""" | |
| from __future__ import annotations | |
| import os | |
| from collections.abc import Mapping | |
| from pydantic import BaseModel, ConfigDict, Field | |
| class ModelSettings(BaseModel): | |
| """Model and prompt settings loaded from environment-compatible mappings.""" | |
| model_config = ConfigDict(extra="forbid", frozen=True) | |
| provider: str = "fake" | |
| model_name: str = "fake-model" | |
| temperature: float = Field(default=0.0, ge=0.0) | |
| timeout_seconds: float = Field(default=30.0, gt=0.0) | |
| max_retries: int = Field(default=2, ge=0) | |
| prompt_version_topic: str = "topic-v1" | |
| prompt_version_term: str = "term-v1" | |
| prompt_version_variable: str = "variable-v1" | |
| api_key_env_var: str = "OPENAI_API_KEY" | |
| include_cost_metadata: bool = True | |
| def from_environment(cls, env: Mapping[str, str] | None = None) -> ModelSettings: | |
| """Load model settings from an environment mapping without reading secrets.""" | |
| source = os.environ if env is None else env | |
| return cls( | |
| provider=source.get("MODEL_PROVIDER", cls.model_fields["provider"].default), | |
| model_name=source.get("MODEL_NAME", cls.model_fields["model_name"].default), | |
| temperature=_float_env( | |
| source, | |
| "MODEL_TEMPERATURE", | |
| cls.model_fields["temperature"].default, | |
| ), | |
| timeout_seconds=_float_env( | |
| source, | |
| "MODEL_TIMEOUT_SECONDS", | |
| cls.model_fields["timeout_seconds"].default, | |
| ), | |
| max_retries=_int_env( | |
| source, | |
| "MODEL_MAX_RETRIES", | |
| cls.model_fields["max_retries"].default, | |
| ), | |
| prompt_version_topic=source.get( | |
| "PROMPT_VERSION_TOPIC", | |
| cls.model_fields["prompt_version_topic"].default, | |
| ), | |
| prompt_version_term=source.get( | |
| "PROMPT_VERSION_TERM", | |
| cls.model_fields["prompt_version_term"].default, | |
| ), | |
| prompt_version_variable=source.get( | |
| "PROMPT_VERSION_VARIABLE", | |
| cls.model_fields["prompt_version_variable"].default, | |
| ), | |
| api_key_env_var=source.get( | |
| "MODEL_API_KEY_ENV_VAR", | |
| cls.model_fields["api_key_env_var"].default, | |
| ), | |
| include_cost_metadata=_bool_env( | |
| source, | |
| "MODEL_INCLUDE_COST_METADATA", | |
| cls.model_fields["include_cost_metadata"].default, | |
| ), | |
| ) | |
| def prompt_version_for_stage(self, stage: str) -> str: | |
| """Return the configured prompt version for a model-call stage.""" | |
| if stage == "topic": | |
| return self.prompt_version_topic | |
| if stage == "term": | |
| return self.prompt_version_term | |
| if stage == "variable": | |
| return self.prompt_version_variable | |
| raise ValueError(f"Unknown prompt stage: {stage}") | |
| def _float_env(source: Mapping[str, str], name: str, default: float) -> float: | |
| value = source.get(name) | |
| return default if value is None else float(value) | |
| def _int_env(source: Mapping[str, str], name: str, default: int) -> int: | |
| value = source.get(name) | |
| return default if value is None else int(value) | |
| def _bool_env(source: Mapping[str, str], name: str, default: bool) -> bool: | |
| value = source.get(name) | |
| if value is None: | |
| return default | |
| return value.strip().lower() in {"1", "true", "yes", "on"} | |