Skip to content

Commit fd52490

Browse files
committed
feat: update to ${VAR}
1 parent f257016 commit fd52490

File tree

1 file changed

+37
-16
lines changed

1 file changed

+37
-16
lines changed

openevolve/config.py

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"""
44

55
import os
6+
import re
67
from dataclasses import asdict, dataclass, field
78
from pathlib import Path
89
from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Union
@@ -13,15 +14,45 @@
1314
from openevolve.llm.base import LLMInterface
1415

1516

17+
_ENV_VAR_PATTERN = re.compile(r"^\$\{([^}]+)\}$") # ${VAR}
18+
19+
20+
def _resolve_env_var(value: Optional[str]) -> Optional[str]:
21+
"""
22+
Resolve ${VAR} environment variable reference in a string value.
23+
In current implementation pattern must match the entire string (e.g., "${OPENAI_API_KEY}"),
24+
not embedded within other text.
25+
26+
Args:
27+
value: The string value that may contain ${VAR} syntax
28+
29+
Returns:
30+
The resolved value with environment variable expanded, or original value if no match
31+
32+
Raises:
33+
ValueError: If the environment variable is referenced but not set
34+
"""
35+
if value is None:
36+
return None
37+
38+
match = _ENV_VAR_PATTERN.match(value)
39+
if not match:
40+
return value
41+
42+
var_name = match.group(1)
43+
env_value = os.environ.get(var_name)
44+
if env_value is None:
45+
raise ValueError(f"Environment variable {var_name} is not set")
46+
return env_value
47+
48+
1649
@dataclass
1750
class LLMModelConfig:
1851
"""Configuration for a single LLM model"""
1952

2053
# API configuration
2154
api_base: str = None
22-
api_key: Optional[Union[str, Dict[str, str]]] = (
23-
None # either api_key or from_env: api_key_var_name
24-
)
55+
api_key: Optional[str] = None
2556
name: str = None
2657

2758
# Custom LLM client
@@ -48,18 +79,8 @@ class LLMModelConfig:
4879
reasoning_effort: Optional[str] = None
4980

5081
def __post_init__(self):
51-
"""Post-initialization to set up API key"""
52-
if self.api_key is not None:
53-
if isinstance(self.api_key, dict):
54-
env_var_name = self.api_key.get("from_env")
55-
if env_var_name is None:
56-
raise ValueError(
57-
f"api_key is a dict but 'from_env' key is not set: {self.api_key}"
58-
)
59-
key = os.environ.get(env_var_name)
60-
if key is None:
61-
raise ValueError(f"Environment variable {env_var_name} is not set")
62-
self.api_key = key
82+
"""Post-initialization to resolve ${VAR} env var references in api_key"""
83+
self.api_key = _resolve_env_var(self.api_key)
6384

6485

6586
@dataclass
@@ -97,7 +118,7 @@ class LLMConfig(LLMModelConfig):
97118

98119
def __post_init__(self):
99120
"""Post-initialization to set up model configurations"""
100-
super().__post_init__() # resolve from_env for api_key at LLMConfig level
121+
super().__post_init__() # Resolve ${VAR} in api_key at LLMConfig level
101122

102123
# Handle backward compatibility for primary_model(_weight) and secondary_model(_weight).
103124
if self.primary_model:

0 commit comments

Comments
 (0)