mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-25 17:18:11 +00:00
fix(models): resolve custom provider model ids
Map picker-prefixed custom provider selections back to their configured model IDs before validation, persistence, and API requests. Fixes #68347
This commit is contained in:
parent
199f558058
commit
8ca4c745d0
2 changed files with 77 additions and 0 deletions
|
|
@ -965,6 +965,38 @@ def _configured_provider_matches(
|
|||
return matches
|
||||
|
||||
|
||||
def _resolve_named_custom_model_id(
|
||||
model_name: str,
|
||||
target_provider: str,
|
||||
custom_providers: Optional[list],
|
||||
) -> str:
|
||||
"""Map a picker-prefixed custom model selection to its configured ID."""
|
||||
provider = str(target_provider or "").strip().lower()
|
||||
if not provider.startswith("custom:") or "/" not in model_name:
|
||||
return model_name
|
||||
|
||||
prefix, candidate = model_name.split("/", 1)
|
||||
prefix = prefix.strip().lower()
|
||||
candidate = candidate.strip()
|
||||
if not prefix or not candidate:
|
||||
return model_name
|
||||
|
||||
for entry in custom_providers or []:
|
||||
if not isinstance(entry, dict):
|
||||
continue
|
||||
entry_slugs = {
|
||||
custom_provider_slug(str(entry.get(key) or "")).lower()
|
||||
for key in ("name", "provider_key")
|
||||
if str(entry.get(key) or "").strip()
|
||||
}
|
||||
if provider not in entry_slugs or f"custom:{prefix}" not in entry_slugs:
|
||||
continue
|
||||
for model_id in _declared_model_ids(entry.get("models")):
|
||||
if model_id.lower() == candidate.lower():
|
||||
return model_id
|
||||
return model_name
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Core model-switching pipeline
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
@ -1447,6 +1479,9 @@ def switch_model(
|
|||
api_mode = determine_api_mode(target_provider, base_url)
|
||||
|
||||
# --- Normalize model name for target provider ---
|
||||
new_model = _resolve_named_custom_model_id(
|
||||
new_model, target_provider, custom_providers
|
||||
)
|
||||
new_model = normalize_model_for_provider(new_model, target_provider)
|
||||
|
||||
# --- Validate ---
|
||||
|
|
|
|||
|
|
@ -283,6 +283,48 @@ def test_switch_model_accepts_explicit_named_custom_provider(monkeypatch):
|
|||
assert result.api_key == "no-key-required"
|
||||
|
||||
|
||||
def test_picker_selection_resolves_named_custom_provider_model_id(monkeypatch):
|
||||
"""Picker prefixes must not leak into a named custom provider API model id."""
|
||||
monkeypatch.setattr(
|
||||
"hermes_cli.runtime_provider.resolve_runtime_provider",
|
||||
lambda **kwargs: {
|
||||
"api_key": "test-key",
|
||||
"base_url": "https://token.sensenova.cn/v1",
|
||||
"api_mode": "chat_completions",
|
||||
},
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"hermes_cli.models.validate_requested_model",
|
||||
lambda *a, **k: _MOCK_VALIDATION,
|
||||
)
|
||||
monkeypatch.setattr("hermes_cli.model_switch.get_model_info", lambda *a, **k: None)
|
||||
monkeypatch.setattr(
|
||||
"hermes_cli.model_switch.get_model_capabilities",
|
||||
lambda *a, **k: None,
|
||||
)
|
||||
|
||||
result = switch_model(
|
||||
raw_input="sensenova/deepseek-v4-flash",
|
||||
current_provider="openai-codex",
|
||||
current_model="gpt-5.4",
|
||||
explicit_provider="custom:sensenova",
|
||||
user_providers={},
|
||||
custom_providers=[
|
||||
{
|
||||
"name": "sensenova",
|
||||
"base_url": "https://token.sensenova.cn/v1",
|
||||
"models": [
|
||||
{"id": "deepseek-v4-flash", "name": "deepseek-v4-flash"}
|
||||
],
|
||||
}
|
||||
],
|
||||
)
|
||||
|
||||
assert result.success is True
|
||||
assert result.target_provider == "custom:sensenova"
|
||||
assert result.new_model == "deepseek-v4-flash"
|
||||
|
||||
|
||||
def test_list_groups_same_name_custom_providers_into_one_row(monkeypatch):
|
||||
"""Multiple custom_providers entries sharing a name should produce one row
|
||||
with all models collected, not N duplicate rows."""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue