Initial Open-SWE-Traces cleanup pipeline
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
"""Runtime configuration for the GLM API and local processing pipeline."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
def _get_bool(name: str, default: bool) -> bool:
|
||||
"""Read a strict boolean environment variable with a safe default."""
|
||||
|
||||
raw_value = os.getenv(name)
|
||||
if raw_value is None:
|
||||
return default
|
||||
normalized = raw_value.strip().lower()
|
||||
if normalized in {"1", "true", "yes", "on"}:
|
||||
return True
|
||||
if normalized in {"0", "false", "no", "off"}:
|
||||
return False
|
||||
raise ValueError(f"{name} must be a boolean value, got {raw_value!r}")
|
||||
|
||||
|
||||
def _get_int(name: str, default: int, minimum: int = 1) -> int:
|
||||
"""Read and validate an integer environment variable."""
|
||||
|
||||
value = int(os.getenv(name, str(default)))
|
||||
if value < minimum:
|
||||
raise ValueError(f"{name} must be at least {minimum}, got {value}")
|
||||
return value
|
||||
|
||||
|
||||
def _get_float(name: str, default: float, minimum: float = 0.0) -> float:
|
||||
"""Read and validate a floating-point environment variable."""
|
||||
|
||||
value = float(os.getenv(name, str(default)))
|
||||
if value < minimum:
|
||||
raise ValueError(f"{name} must be at least {minimum}, got {value}")
|
||||
return value
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class Settings:
|
||||
"""Immutable settings used by API clients and command-line workflows."""
|
||||
|
||||
api_key: str
|
||||
api_base: str = "https://llm-api.cowin.run"
|
||||
api_path: str = "/v1/chat/completions"
|
||||
model: str = "glm-5.2"
|
||||
timeout_seconds: float = 300.0
|
||||
max_retries: int = 3
|
||||
max_tokens: int = 8192
|
||||
temperature: float = 0.0
|
||||
reasoning_effort: str = "high"
|
||||
thinking_enabled: bool = True
|
||||
|
||||
@property
|
||||
def endpoint(self) -> str:
|
||||
"""Return the normalized absolute chat-completions URL."""
|
||||
|
||||
base = self.api_base.rstrip("/")
|
||||
path = self.api_path if self.api_path.startswith("/") else f"/{self.api_path}"
|
||||
return f"{base}{path}"
|
||||
|
||||
@classmethod
|
||||
def from_env(cls, *, require_api_key: bool = True) -> Settings:
|
||||
"""Construct settings from environment variables.
|
||||
|
||||
The API key is intentionally loaded only from ``GLM_API_KEY``. The
|
||||
project never reads a committed configuration file containing a key.
|
||||
"""
|
||||
|
||||
api_key = os.getenv("GLM_API_KEY", "").strip()
|
||||
if require_api_key and not api_key:
|
||||
raise ValueError("GLM_API_KEY is required but was not set")
|
||||
|
||||
reasoning_effort = os.getenv("GLM_REASONING_EFFORT", "high").strip().lower()
|
||||
if reasoning_effort not in {"low", "medium", "high", "max"}:
|
||||
raise ValueError(
|
||||
"GLM_REASONING_EFFORT must be one of: low, medium, high, max"
|
||||
)
|
||||
|
||||
return cls(
|
||||
api_key=api_key,
|
||||
api_base=os.getenv("GLM_API_BASE", "https://llm-api.cowin.run"),
|
||||
api_path=os.getenv("GLM_API_PATH", "/v1/chat/completions"),
|
||||
model=os.getenv("GLM_MODEL", "glm-5.2"),
|
||||
timeout_seconds=_get_float("GLM_TIMEOUT_SECONDS", 300.0, 1.0),
|
||||
max_retries=_get_int("GLM_MAX_RETRIES", 3, 1),
|
||||
max_tokens=_get_int("GLM_MAX_TOKENS", 8192, 1),
|
||||
temperature=_get_float("GLM_TEMPERATURE", 0.0, 0.0),
|
||||
reasoning_effort=reasoning_effort,
|
||||
thinking_enabled=_get_bool("GLM_THINKING_ENABLED", True),
|
||||
)
|
||||
Reference in New Issue
Block a user