mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-29 01:31:41 +00:00
feat(providers): add tencent-tokenhub provider support
Registers tencent-tokenhub (https://tokenhub.tencentmaas.com/v1) as a new API-key provider with model tencent/hy3-preview (256K context). - PROVIDER_REGISTRY entry + TOKENHUB_API_KEY / TOKENHUB_BASE_URL env vars - Aliases: tencent, tokenhub, tencent-cloud, tencentmaas - openai_chat transport with is_tokenhub branch for top-level reasoning_effort (Hy3 is a reasoning model) - tencent/hy3-preview:free added to OpenRouter curated list - 60+ tests (provider registry, aliases, runtime resolution, credentials, model catalog, URL mapping, context length) - Docs: integrations/providers.md, environment-variables.md, model-catalog.json Author: simonweng <simonweng@tencent.com> Salvaged from PR #16860 onto current main (resolved conflicts with #16935 Azure Anthropic env-var hint tests and the --provider choices= list removal in chat_parser).
This commit is contained in:
parent
bd10acd747
commit
a6a6cf047d
16 changed files with 654 additions and 6 deletions
|
|
@ -1763,7 +1763,6 @@ class TestAzureFoundryResolution:
|
|||
assert resolved["api_mode"] == "codex_responses"
|
||||
|
||||
|
||||
|
||||
# ──────────────────────────────────────────────────────────────────────────
|
||||
# Azure Anthropic — honor user-specified env var hints (key_env / api_key_env)
|
||||
#
|
||||
|
|
@ -1962,3 +1961,84 @@ class TestProviderEntryApiKeyEnvAlias:
|
|||
key_env so the set stays in sync with what the runtime actually reads."""
|
||||
from hermes_cli.config import _VALID_CUSTOM_PROVIDER_FIELDS
|
||||
assert "key_env" in _VALID_CUSTOM_PROVIDER_FIELDS
|
||||
# =============================================================================
|
||||
# Tencent TokenHub — API-key provider runtime resolution
|
||||
# =============================================================================
|
||||
|
||||
class TestTencentTokenhubRuntimeResolution:
|
||||
"""Verify Tencent TokenHub resolves correctly through the generic
|
||||
API-key provider path in resolve_runtime_provider."""
|
||||
|
||||
def test_resolves_with_env_key(self, monkeypatch):
|
||||
monkeypatch.setattr(rp, "resolve_provider", lambda *a, **k: "tencent-tokenhub")
|
||||
monkeypatch.setattr(rp, "_get_model_config", lambda: {})
|
||||
monkeypatch.setenv("TOKENHUB_API_KEY", "test-tokenhub-key")
|
||||
monkeypatch.delenv("TOKENHUB_BASE_URL", raising=False)
|
||||
|
||||
resolved = rp.resolve_runtime_provider(requested="tencent-tokenhub")
|
||||
|
||||
assert resolved["provider"] == "tencent-tokenhub"
|
||||
assert resolved["api_mode"] == "chat_completions"
|
||||
assert resolved["base_url"] == "https://tokenhub.tencentmaas.com/v1"
|
||||
assert resolved["api_key"] == "test-tokenhub-key"
|
||||
assert resolved["requested_provider"] == "tencent-tokenhub"
|
||||
|
||||
def test_custom_base_url_from_env(self, monkeypatch):
|
||||
monkeypatch.setattr(rp, "resolve_provider", lambda *a, **k: "tencent-tokenhub")
|
||||
monkeypatch.setattr(rp, "_get_model_config", lambda: {})
|
||||
monkeypatch.setenv("TOKENHUB_API_KEY", "test-tokenhub-key")
|
||||
monkeypatch.setenv("TOKENHUB_BASE_URL", "https://custom-proxy.example.com/v1")
|
||||
|
||||
resolved = rp.resolve_runtime_provider(requested="tencent-tokenhub")
|
||||
|
||||
assert resolved["provider"] == "tencent-tokenhub"
|
||||
assert resolved["base_url"] == "https://custom-proxy.example.com/v1"
|
||||
assert resolved["api_key"] == "test-tokenhub-key"
|
||||
|
||||
def test_config_base_url_honoured_when_provider_matches(self, monkeypatch):
|
||||
"""model.base_url in config.yaml should override the hardcoded default
|
||||
when model.provider == tencent-tokenhub."""
|
||||
monkeypatch.setattr(rp, "resolve_provider", lambda *a, **k: "tencent-tokenhub")
|
||||
monkeypatch.setattr(rp, "_get_model_config", lambda: {
|
||||
"provider": "tencent-tokenhub",
|
||||
"base_url": "https://proxy.internal.com/v1",
|
||||
})
|
||||
monkeypatch.setenv("TOKENHUB_API_KEY", "test-tokenhub-key")
|
||||
monkeypatch.delenv("TOKENHUB_BASE_URL", raising=False)
|
||||
|
||||
resolved = rp.resolve_runtime_provider(requested="tencent-tokenhub")
|
||||
|
||||
assert resolved["base_url"] == "https://proxy.internal.com/v1"
|
||||
|
||||
def test_config_base_url_ignored_for_different_provider(self, monkeypatch):
|
||||
"""model.base_url should NOT be used when model.provider doesn't match."""
|
||||
monkeypatch.setattr(rp, "resolve_provider", lambda *a, **k: "tencent-tokenhub")
|
||||
monkeypatch.setattr(rp, "_get_model_config", lambda: {
|
||||
"provider": "openrouter",
|
||||
"base_url": "https://some-other-endpoint.com/v1",
|
||||
})
|
||||
monkeypatch.setenv("TOKENHUB_API_KEY", "test-tokenhub-key")
|
||||
monkeypatch.delenv("TOKENHUB_BASE_URL", raising=False)
|
||||
|
||||
resolved = rp.resolve_runtime_provider(requested="tencent-tokenhub")
|
||||
|
||||
# Should use the default, NOT the config base_url from a different provider
|
||||
assert resolved["base_url"] == "https://tokenhub.tencentmaas.com/v1"
|
||||
|
||||
def test_explicit_override_skips_env(self, monkeypatch):
|
||||
monkeypatch.setattr(rp, "resolve_provider", lambda *a, **k: "tencent-tokenhub")
|
||||
monkeypatch.setattr(rp, "_get_model_config", lambda: {})
|
||||
monkeypatch.setenv("TOKENHUB_API_KEY", "env-key-should-lose")
|
||||
monkeypatch.delenv("TOKENHUB_BASE_URL", raising=False)
|
||||
|
||||
resolved = rp.resolve_runtime_provider(
|
||||
requested="tencent-tokenhub",
|
||||
explicit_api_key="explicit-tokenhub-key",
|
||||
explicit_base_url="https://explicit-proxy.example.com/v1/",
|
||||
)
|
||||
|
||||
assert resolved["provider"] == "tencent-tokenhub"
|
||||
assert resolved["api_key"] == "explicit-tokenhub-key"
|
||||
assert resolved["base_url"] == "https://explicit-proxy.example.com/v1"
|
||||
assert resolved["source"] == "explicit"
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue