"""Central configuration for the Qt5→Qt6 migration pipeline.""" from __future__ import annotations import os from pathlib import Path from dotenv import load_dotenv _DOTENV_LOADED = False def _get_env(name: str) -> str: """Read env var from runtime first, then .env as fallback.""" value = os.getenv(name, "") if value: return value global _DOTENV_LOADED if not _DOTENV_LOADED: load_dotenv(dotenv_path=Path.cwd() / ".env", override=False) load_dotenv(override=False) _DOTENV_LOADED = True return os.getenv(name, "") def _require_env(name: str) -> str: value = _get_env(name) if not value: raise RuntimeError( f"Missing required environment variable: {name}. " "Set runtime env vars or provide them via .env." ) return value # --------------------------------------------------------------------------- # Scaleway API # --------------------------------------------------------------------------- # Runtime credentials/config (must exist in runtime env or .env). SCW_ACCESS_KEY: str = _require_env("SCW_ACCESS_KEY") SCW_SECRET_KEY: str = _require_env("SCW_SECRET_KEY") SCW_DEFAULT_ORGANIZATION_ID: str = _require_env("SCW_DEFAULT_ORGANIZATION_ID") SCW_DEFAULT_PROJECT_ID: str = _require_env("SCW_DEFAULT_PROJECT_ID") SCW_SERVERLESS: str = _require_env("SCW_SERVERLESS") API_KEY: str = SCW_SECRET_KEY BASE_URL: str = f"https://api.scaleway.ai/{SCW_SERVERLESS}/v1/chat/completions" API_TIMEOUT: float = 120.0 # seconds per HTTP request API_MAX_TOKENS: int = 8192 # Model selection profile (CLI-selectable) MODEL_GLM: str = "glm-5.2" MODEL_QWEN: str = "qwen3.5-397b-a17b" DEFAULT_MODEL_FAMILY: str = "glm" LARGE_FILE_THRESHOLD: int = 1_000 # --------------------------------------------------------------------------- # Concurrency # --------------------------------------------------------------------------- MAX_CONCURRENT_TASKS: int = 3 # parallel file workers per track # --------------------------------------------------------------------------- # Chunking # --------------------------------------------------------------------------- CHUNK_SIZE_LINES: int = 500 # max lines per chunk when splitting large files # --------------------------------------------------------------------------- # Time budgets (seconds) # Soft budget → warning logged, migration continues # Hard budget → file goes to quarantine immediately # --------------------------------------------------------------------------- SOFT_BUDGET_PER_FILE: float = 10 * 60 # 10 min HARD_BUDGET_SMALL_FILE: float = 10 * 60 # 10 min (≤ LARGE_FILE_THRESHOLD lines) HARD_BUDGET_LARGE_FILE: float = 25 * 60 # 25 min (> LARGE_FILE_THRESHOLD lines) # --------------------------------------------------------------------------- # Retry / quality # --------------------------------------------------------------------------- MAX_RETRIES: int = 3 # per file, per track # Warnings: collected and reported but do NOT block quality gates. # Set to True only if you want -Werror behaviour (future option). WARNINGS_ARE_BLOCKING: bool = False # --------------------------------------------------------------------------- # Paths # --------------------------------------------------------------------------- WORKSPACE_ROOT: Path = Path("workspace") # git worktrees live here QUARANTINE_DIR: Path = Path("quarantine") # quarantine JSON + MD tickets REPORTS_DIR: Path = Path("reports") # batch comparison reports TESTS_DIR_NAME: str = "tests_generated" # relative to each worktree root # --------------------------------------------------------------------------- # Track identifiers # --------------------------------------------------------------------------- TRACK_A_ID: str = "track_a_conservative" TRACK_B_ID: str = "track_b_modern"