Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions gateway/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -722,10 +722,12 @@ def load_gateway_config() -> GatewayConfig:
# Primary source: config.yaml
try:
import yaml
from hermes_cli.config import _expand_env_vars
config_yaml_path = _home / "config.yaml"
if config_yaml_path.exists():
with open(config_yaml_path, encoding="utf-8") as f:
yaml_cfg = yaml.safe_load(f) or {}
yaml_cfg = _expand_env_vars(yaml_cfg) or {}

# Map config.yaml keys → GatewayConfig.from_dict() schema.
# Each key overwrites whatever gateway.json may have set.
Expand Down
7 changes: 6 additions & 1 deletion gateway/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -1466,7 +1466,12 @@ def _resolve_gateway_model(config: dict | None = None) -> str:
back to the hardcoded default which fails when the active provider is
openai-codex.
"""
cfg = config if config is not None else _load_gateway_config()
if config is None:
cfg = _load_gateway_runtime_config()
else:
from hermes_cli.config import _expand_env_vars

cfg = _expand_env_vars(config)
model_cfg = cfg.get("model", {})
if isinstance(model_cfg, str):
return model_cfg
Expand Down
21 changes: 21 additions & 0 deletions tests/gateway/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,27 @@ def test_bridges_discord_allow_from_from_config_yaml(self, tmp_path, monkeypatch
"123456789012345678,999888777666555444"
)

def test_bridges_telegram_allow_from_env_template_from_config_yaml(self, tmp_path, monkeypatch):
"""telegram.allow_from should expand ${VAR} before auth env bridging."""
hermes_home = tmp_path / ".hermes"
hermes_home.mkdir()
config_path = hermes_home / "config.yaml"
config_path.write_text(
"telegram:\n"
" token: fake-token\n"
" allow_from: ${TG_ALLOWED_USER}\n",
encoding="utf-8",
)

monkeypatch.setenv("HERMES_HOME", str(hermes_home))
monkeypatch.setenv("TG_ALLOWED_USER", "123456789")
monkeypatch.delenv("TELEGRAM_ALLOWED_USERS", raising=False)

config = load_gateway_config()

assert config.platforms[Platform.TELEGRAM].extra["allow_from"] == "123456789"
assert os.environ.get("TELEGRAM_ALLOWED_USERS") == "123456789"

def test_bridges_discord_platform_extra_allow_from_to_env(self, tmp_path, monkeypatch):
"""platforms.discord.extra.allow_from should reach DISCORD_ALLOWED_USERS too."""
hermes_home = tmp_path / ".hermes"
Expand Down
8 changes: 8 additions & 0 deletions tests/gateway/test_runtime_config_env_expansion.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ def test_load_prefill_messages_expands_env_var_path(monkeypatch, gateway_home):
assert gateway_run.GatewayRunner._load_prefill_messages() == prefill


def test_resolve_gateway_model_expands_env_var_template(monkeypatch, gateway_home):
_write_config(gateway_home, "model: ${GW_MODEL}\n")
monkeypatch.setenv("GW_MODEL", "gpt-5.5")

assert gateway_run._resolve_gateway_model() == "gpt-5.5"
assert gateway_run._resolve_gateway_model({"model": "${GW_MODEL}"}) == "gpt-5.5"


@pytest.mark.parametrize(
("config_body", "env_name", "env_value", "loader_name", "expected"),
[
Expand Down
Loading