|
26 | 26 | ).decode("utf-8") |
27 | 27 |
|
28 | 28 |
|
29 | | -# Load .env file with override so .env values always win over shell environment |
| 29 | +# override=True so .env always wins over the shell's possibly-stale credentials. |
30 | 30 | load_dotenv(override=True) |
31 | 31 |
|
32 | | -# For certain keys, we want .env values to take precedence over shell environment |
33 | | -# because the shell may have outdated/different credentials |
34 | 32 | env_values = dotenv_values(".env") |
35 | 33 | for key in [ |
36 | 34 | "ANTHROPIC_API_KEY", |
@@ -79,52 +77,43 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: |
79 | 77 | _reject_removed_default_knobs() |
80 | 78 | super().__init__(*args, **kwargs) |
81 | 79 |
|
82 | | - # API Keys (for Claude Code agent only) |
83 | 80 | anthropic_api_key: str | None = None |
84 | 81 |
|
85 | | - # Paths |
86 | 82 | runs_dir: Path = Path("runs") # Base directory for timestamped runs |
87 | 83 |
|
88 | | - # API Backend routing |
89 | 84 | api_backend: ApiBackend = ApiBackend.DIRECT |
90 | 85 |
|
91 | | - # AWS Bedrock settings (used when api_backend == "bedrock") |
92 | 86 | aws_bearer_token_bedrock: str | None = None |
93 | 87 | aws_region: str | None = None |
94 | 88 | bedrock_model: str | None = None # Cross-region model ID |
95 | 89 | bedrock_small_model: str | None = None # Cross-region small model ID |
96 | 90 |
|
97 | | - # HAZARD: these map to the ANTHROPIC_* vars, but ONLY inside the SDK subprocess |
98 | | - # env. Deliberately NOT named anthropic_*, so the export loop below cannot leak |
99 | | - # ANTHROPIC_BASE_URL process-wide and redirect the judge's own client. |
| 91 | + # HAZARD: these map to the ANTHROPIC_* vars ONLY inside the SDK subprocess env. |
| 92 | + # NOT named anthropic_*, so the export loop cannot leak ANTHROPIC_BASE_URL |
| 93 | + # process-wide and redirect the judge's own client. |
100 | 94 | litellm_base_url: str | None = None |
101 | 95 | litellm_auth_token: str | None = None |
102 | 96 | litellm_model: str | None = None |
103 | 97 | litellm_small_model: str | None = None |
104 | | - # Must point at the SAME file the proxy writes. When set and present, the harness |
105 | | - # joins each call's ACTUAL cost onto the turn; unset or missing => static pricing. |
| 98 | + # Must point at the SAME file the proxy writes; unset or missing => static pricing. |
106 | 99 | # Rationale: .claude/notes/reporting.md § Cost joining |
107 | 100 | litellm_cost_log: str | None = None |
108 | 101 |
|
109 | 102 | # CODEX_MODEL is the fallback when a task doesn't pin agent.model. For Azure set |
110 | | - # CODEX_API_VERSION too and use the deployment name as the model. CODEX_BASE_URL |
111 | | - # / CODEX_API_VERSION / CODEX_API_KEY are read via os.getenv in the agent. |
| 103 | + # CODEX_API_VERSION too and use the deployment name as the model. |
112 | 104 | codex_model: str | None = None |
113 | 105 |
|
114 | 106 | # GEMINI_API_KEY is read from .env here so the export loop re-publishes it to |
115 | 107 | # os.environ, where the SDK looks for it. ANTIGRAVITY_MODEL is the fallback. |
116 | 108 | gemini_api_key: str | None = None |
117 | 109 | antigravity_model: str | None = None |
118 | 110 |
|
119 | | - # Logging |
120 | 111 | log_level: str = "INFO" # Default log level (DEBUG, INFO, WARNING, ERROR, CRITICAL) |
121 | 112 | log_to_file: bool = False # Whether to enable file logging |
122 | 113 |
|
123 | | - # On by default via the baked-in connection string. TELEMETRY_ENABLED is the |
124 | | - # single canonical disable gate. |
| 114 | + # On by default via the baked-in connection string, which any set value (env |
| 115 | + # or .env) overrides. TELEMETRY_ENABLED is the single canonical disable gate. |
125 | 116 | telemetry_enabled: bool = True |
126 | | - # Defaults to the embedded coder-eval resource; any set value (env or .env, via |
127 | | - # the aliases below) overrides it — pydantic-settings prefers env over default. |
128 | 117 | telemetry_connection_string: str | None = Field( |
129 | 118 | default=_DEFAULT_TELEMETRY_CONNECTION_STRING, |
130 | 119 | validation_alias=AliasChoices( |
@@ -180,8 +169,7 @@ def _validate_litellm_settings(self) -> None: |
180 | 169 | f"LiteLLM-endpoint routing is enabled but missing required settings: {', '.join(missing)}." |
181 | 170 | + " Please set them in your .env file." |
182 | 171 | ) |
183 | | - # Reject a malformed base_url here so the downstream preflight and |
184 | | - # environment_info get a well-formed absolute URL. |
| 172 | + # Reject a malformed base_url so the preflight and environment_info get a well-formed URL. |
185 | 173 | parts = urlsplit(self.litellm_base_url or "") |
186 | 174 | if parts.scheme not in ("http", "https") or not parts.hostname: |
187 | 175 | raise ValueError( |
@@ -215,15 +203,12 @@ def validate_api_keys(self, agent_type: str) -> None: |
215 | 203 | return |
216 | 204 |
|
217 | 205 |
|
218 | | -# Global settings instance |
219 | 206 | settings = Settings() |
220 | 207 |
|
221 | | -# For external libraries that read os.getenv() rather than the Settings object. |
222 | | -# Non-None values only, stringified. |
| 208 | +# For external libraries that read os.getenv(); non-None values only, stringified. |
223 | 209 | for key, value in settings.model_dump().items(): |
224 | 210 | if value is not None: |
225 | 211 | env_key = key.upper() |
226 | | - # Convert Path objects and other types to strings |
227 | 212 | if isinstance(value, Path): |
228 | 213 | os.environ[env_key] = str(value) |
229 | 214 | elif isinstance(value, bool): |
|
0 commit comments