mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
fix(setup): validate base URL input in hermes model flow (#8264)
Reject non-URL values (e.g. shell commands typed by mistake) in the base URL prompt during provider setup. Previously any string was saved as-is to .env, breaking connectivity when the garbage value was used as the API endpoint. Adds http:// / https:// prefix check with a clear error message. The custom-endpoint flow already had this validation (line 1620); this brings the generic API-key provider flow to parity. Triggered by a user support case where 'nano ~/.hermes/.env' was accidentally entered as GLM_BASE_URL during Z.AI setup.
This commit is contained in:
parent
a1220977d3
commit
ae6820a45a
2 changed files with 78 additions and 2 deletions
|
|
@ -257,3 +257,76 @@ class TestProviderPersistsAfterModelSave:
|
|||
assert model.get("provider") == "opencode-go"
|
||||
assert model.get("default") == "minimax-m2.5"
|
||||
assert model.get("api_mode") == "anthropic_messages"
|
||||
|
||||
|
||||
class TestBaseUrlValidation:
|
||||
"""Reject non-URL values in the base URL prompt (e.g. shell commands)."""
|
||||
|
||||
def test_invalid_base_url_rejected(self, config_home, monkeypatch, capsys):
|
||||
"""Typing a non-URL string should not be saved as the base URL."""
|
||||
from hermes_cli.auth import PROVIDER_REGISTRY
|
||||
|
||||
pconfig = PROVIDER_REGISTRY.get("zai")
|
||||
if not pconfig:
|
||||
pytest.skip("zai not in PROVIDER_REGISTRY")
|
||||
|
||||
monkeypatch.setenv("GLM_API_KEY", "test-key")
|
||||
|
||||
from hermes_cli.main import _model_flow_api_key_provider
|
||||
from hermes_cli.config import load_config, get_env_value
|
||||
|
||||
# User types a shell command instead of a URL at the base URL prompt
|
||||
with patch("hermes_cli.auth._prompt_model_selection", return_value="glm-5"), \
|
||||
patch("hermes_cli.auth.deactivate_provider"), \
|
||||
patch("builtins.input", return_value="nano ~/.hermes/.env"):
|
||||
_model_flow_api_key_provider(load_config(), "zai", "old-model")
|
||||
|
||||
# The garbage value should NOT have been saved
|
||||
saved = get_env_value("GLM_BASE_URL") or ""
|
||||
assert not saved or saved.startswith(("http://", "https://")), \
|
||||
f"Non-URL value was saved as GLM_BASE_URL: {saved}"
|
||||
captured = capsys.readouterr()
|
||||
assert "Invalid URL" in captured.out
|
||||
|
||||
def test_valid_base_url_accepted(self, config_home, monkeypatch):
|
||||
"""A proper URL should be saved normally."""
|
||||
from hermes_cli.auth import PROVIDER_REGISTRY
|
||||
|
||||
pconfig = PROVIDER_REGISTRY.get("zai")
|
||||
if not pconfig:
|
||||
pytest.skip("zai not in PROVIDER_REGISTRY")
|
||||
|
||||
monkeypatch.setenv("GLM_API_KEY", "test-key")
|
||||
|
||||
from hermes_cli.main import _model_flow_api_key_provider
|
||||
from hermes_cli.config import load_config, get_env_value
|
||||
|
||||
with patch("hermes_cli.auth._prompt_model_selection", return_value="glm-5"), \
|
||||
patch("hermes_cli.auth.deactivate_provider"), \
|
||||
patch("builtins.input", return_value="https://custom.z.ai/api/paas/v4"):
|
||||
_model_flow_api_key_provider(load_config(), "zai", "old-model")
|
||||
|
||||
saved = get_env_value("GLM_BASE_URL") or ""
|
||||
assert saved == "https://custom.z.ai/api/paas/v4"
|
||||
|
||||
def test_empty_base_url_keeps_default(self, config_home, monkeypatch):
|
||||
"""Pressing Enter (empty) should not change the base URL."""
|
||||
from hermes_cli.auth import PROVIDER_REGISTRY
|
||||
|
||||
pconfig = PROVIDER_REGISTRY.get("zai")
|
||||
if not pconfig:
|
||||
pytest.skip("zai not in PROVIDER_REGISTRY")
|
||||
|
||||
monkeypatch.setenv("GLM_API_KEY", "test-key")
|
||||
monkeypatch.delenv("GLM_BASE_URL", raising=False)
|
||||
|
||||
from hermes_cli.main import _model_flow_api_key_provider
|
||||
from hermes_cli.config import load_config, get_env_value
|
||||
|
||||
with patch("hermes_cli.auth._prompt_model_selection", return_value="glm-5"), \
|
||||
patch("hermes_cli.auth.deactivate_provider"), \
|
||||
patch("builtins.input", return_value=""):
|
||||
_model_flow_api_key_provider(load_config(), "zai", "old-model")
|
||||
|
||||
saved = get_env_value("GLM_BASE_URL") or ""
|
||||
assert saved == "", "Empty input should not save a base URL"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue