fix(providers): register Alibaba China + Token Plan provider profiles (#73265)
The models.dev catalog advertises alibaba-cn, alibaba-coding-plan-cn, and alibaba-token-plan(-cn), and resolve_provider_full()'s catalog chain lets the CLI --provider path resolve them — but auth.resolve_provider() (the credential/runtime path used by 'hermes chat') consults only PROVIDER_REGISTRY and raised "Unknown provider 'alibaba-coding-plan-cn'" (hermes_cli/auth.py:1937). PROVIDER_REGISTRY auto-extends from provider profiles (auth.py:461-490), so the fix registers the missing profiles at that chokepoint: alibaba-cn joins the alibaba plugin, alibaba-coding-plan-cn joins alibaba-coding-plan, and a new alibaba-token-plan plugin registers both regional token-plan tiers. Names match the catalog keys exactly. No core edits — plugins/model-providers is the designed extension path.
This commit is contained in:
@@ -1,7 +1,14 @@
|
||||
"""Alibaba Cloud Coding Plan provider profile.
|
||||
"""Alibaba Cloud Coding Plan provider profiles.
|
||||
|
||||
Separate from the standard `alibaba` profile because it hits a different
|
||||
endpoint (coding-intl.dashscope.aliyuncs.com) with a dedicated API key tier.
|
||||
|
||||
Region split, mirroring the base DashScope pair (#73265):
|
||||
- ``alibaba-coding-plan`` → coding-intl.dashscope.aliyuncs.com (international)
|
||||
- ``alibaba-coding-plan-cn`` → coding.dashscope.aliyuncs.com (mainland China)
|
||||
|
||||
Profile names match the models.dev catalog keys exactly so model metadata
|
||||
lines up and ``model.provider: alibaba-coding-plan-cn`` resolves at runtime.
|
||||
"""
|
||||
|
||||
from providers import register_provider
|
||||
@@ -18,4 +25,16 @@ alibaba_coding_plan = ProviderProfile(
|
||||
auth_type="api_key",
|
||||
)
|
||||
|
||||
alibaba_coding_plan_cn = ProviderProfile(
|
||||
name="alibaba-coding-plan-cn",
|
||||
aliases=("alibaba-coding-cn", "dashscope-coding-cn"),
|
||||
display_name="Alibaba Cloud (Coding Plan, China)",
|
||||
description="Alibaba Cloud Coding Plan, mainland-China endpoint",
|
||||
signup_url="https://help.aliyun.com/zh/model-studio/",
|
||||
env_vars=("ALIBABA_CODING_PLAN_API_KEY", "DASHSCOPE_API_KEY", "ALIBABA_CODING_PLAN_CN_BASE_URL"),
|
||||
base_url="https://coding.dashscope.aliyuncs.com/v1",
|
||||
auth_type="api_key",
|
||||
)
|
||||
|
||||
register_provider(alibaba_coding_plan)
|
||||
register_provider(alibaba_coding_plan_cn)
|
||||
|
||||
42
plugins/model-providers/alibaba-token-plan/__init__.py
Normal file
42
plugins/model-providers/alibaba-token-plan/__init__.py
Normal file
@@ -0,0 +1,42 @@
|
||||
"""Alibaba Cloud Token Plan (Model Studio flat-token tier) provider profiles.
|
||||
|
||||
Token Plan is a separate purchase tier from both standard DashScope and the
|
||||
Coding Plan, with its own dedicated endpoints and API key
|
||||
(``ALIBABA_TOKEN_PLAN_API_KEY``). Both regional endpoints speak the
|
||||
OpenAI-compatible chat-completions protocol:
|
||||
|
||||
- ``alibaba-token-plan`` → token-plan.ap-southeast-1.maas.aliyuncs.com (international)
|
||||
- ``alibaba-token-plan-cn`` → token-plan.cn-beijing.maas.aliyuncs.com (mainland China)
|
||||
|
||||
Profile names match the models.dev catalog keys exactly so model metadata
|
||||
lines up and ``model.provider: alibaba-token-plan-cn`` resolves at runtime
|
||||
instead of failing with "Unknown provider" (#73265).
|
||||
"""
|
||||
|
||||
from providers import register_provider
|
||||
from providers.base import ProviderProfile
|
||||
|
||||
alibaba_token_plan = ProviderProfile(
|
||||
name="alibaba-token-plan",
|
||||
aliases=("dashscope-token-plan",),
|
||||
display_name="Alibaba Cloud (Token Plan)",
|
||||
description="Alibaba Cloud Model Studio Token Plan (flat-token tier)",
|
||||
signup_url="https://help.aliyun.com/zh/model-studio/",
|
||||
env_vars=("ALIBABA_TOKEN_PLAN_API_KEY", "ALIBABA_TOKEN_PLAN_BASE_URL"),
|
||||
base_url="https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
|
||||
auth_type="api_key",
|
||||
)
|
||||
|
||||
alibaba_token_plan_cn = ProviderProfile(
|
||||
name="alibaba-token-plan-cn",
|
||||
aliases=("dashscope-token-plan-cn",),
|
||||
display_name="Alibaba Cloud (Token Plan, China)",
|
||||
description="Alibaba Cloud Model Studio Token Plan, mainland-China endpoint",
|
||||
signup_url="https://help.aliyun.com/zh/model-studio/",
|
||||
env_vars=("ALIBABA_TOKEN_PLAN_API_KEY", "ALIBABA_TOKEN_PLAN_CN_BASE_URL"),
|
||||
base_url="https://token-plan.cn-beijing.maas.aliyuncs.com/compatible-mode/v1",
|
||||
auth_type="api_key",
|
||||
)
|
||||
|
||||
register_provider(alibaba_token_plan)
|
||||
register_provider(alibaba_token_plan_cn)
|
||||
5
plugins/model-providers/alibaba-token-plan/plugin.yaml
Normal file
5
plugins/model-providers/alibaba-token-plan/plugin.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
name: alibaba-token-plan-provider
|
||||
kind: model-provider
|
||||
version: 1.0.0
|
||||
description: Alibaba Cloud Model Studio Token Plan (international + China endpoints)
|
||||
author: Nous Research
|
||||
@@ -1,4 +1,13 @@
|
||||
"""Alibaba Cloud DashScope provider profile."""
|
||||
"""Alibaba Cloud DashScope provider profiles.
|
||||
|
||||
DashScope has region-split endpoints with the same key type:
|
||||
- ``alibaba`` → dashscope-intl.aliyuncs.com (international)
|
||||
- ``alibaba-cn`` → dashscope.aliyuncs.com (mainland China)
|
||||
|
||||
Profile names match the models.dev catalog keys exactly
|
||||
(``alibaba`` / ``alibaba-cn``) so model metadata lines up and
|
||||
``model.provider: alibaba-cn`` resolves at runtime (#73265).
|
||||
"""
|
||||
|
||||
from providers import register_provider
|
||||
from providers.base import ProviderProfile
|
||||
@@ -10,4 +19,14 @@ alibaba = ProviderProfile(
|
||||
base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
|
||||
)
|
||||
|
||||
alibaba_cn = ProviderProfile(
|
||||
name="alibaba-cn",
|
||||
aliases=("dashscope-cn", "alibaba-cloud-cn"),
|
||||
display_name="Alibaba Cloud DashScope (China)",
|
||||
description="Alibaba Cloud DashScope, mainland-China endpoint",
|
||||
env_vars=("DASHSCOPE_API_KEY",),
|
||||
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
|
||||
)
|
||||
|
||||
register_provider(alibaba)
|
||||
register_provider(alibaba_cn)
|
||||
|
||||
@@ -262,3 +262,60 @@ class TestQwenProfile:
|
||||
|
||||
|
||||
|
||||
def test_build_api_kwargs_extras_empty(self):
|
||||
p = ProviderProfile(name="test")
|
||||
eb, tl = p.build_api_kwargs_extras()
|
||||
assert eb == {}
|
||||
assert tl == {}
|
||||
|
||||
|
||||
class TestAlibabaRegionalAndTokenPlanProfiles:
|
||||
"""#73265: the models.dev catalog advertises alibaba-cn /
|
||||
alibaba-token-plan(-cn) / alibaba-coding-plan-cn, but none were registered
|
||||
at runtime — `model.provider: alibaba-coding-plan-cn` failed with
|
||||
"Unknown provider" and users were forced onto the `custom` escape hatch.
|
||||
Profile names intentionally match the catalog keys exactly so model
|
||||
metadata lines up."""
|
||||
|
||||
def test_alibaba_cn_registered(self):
|
||||
p = get_provider_profile("alibaba-cn")
|
||||
assert p is not None and p.name == "alibaba-cn"
|
||||
assert p.base_url == "https://dashscope.aliyuncs.com/compatible-mode/v1"
|
||||
assert "DASHSCOPE_API_KEY" in p.env_vars
|
||||
|
||||
def test_alibaba_coding_plan_cn_registered(self):
|
||||
p = get_provider_profile("alibaba-coding-plan-cn")
|
||||
assert p is not None and p.name == "alibaba-coding-plan-cn"
|
||||
assert p.base_url == "https://coding.dashscope.aliyuncs.com/v1"
|
||||
assert "ALIBABA_CODING_PLAN_API_KEY" in p.env_vars
|
||||
|
||||
def test_alibaba_token_plan_registered(self):
|
||||
p = get_provider_profile("alibaba-token-plan")
|
||||
assert p is not None and p.name == "alibaba-token-plan"
|
||||
assert p.base_url == "https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1"
|
||||
assert "ALIBABA_TOKEN_PLAN_API_KEY" in p.env_vars
|
||||
|
||||
def test_alibaba_token_plan_cn_registered(self):
|
||||
p = get_provider_profile("alibaba-token-plan-cn")
|
||||
assert p is not None and p.name == "alibaba-token-plan-cn"
|
||||
assert p.base_url == "https://token-plan.cn-beijing.maas.aliyuncs.com/compatible-mode/v1"
|
||||
assert "ALIBABA_TOKEN_PLAN_API_KEY" in p.env_vars
|
||||
|
||||
def test_cn_variants_resolve_in_auth_registry(self, monkeypatch):
|
||||
"""The reporter's exact failure site: ``auth.resolve_provider()`` only
|
||||
consults PROVIDER_REGISTRY (auto-extended from provider profiles,
|
||||
hermes_cli/auth.py:461-490) and raised
|
||||
"Unknown provider 'alibaba-coding-plan-cn'" (hermes_cli/auth.py:1937)
|
||||
even though the models.dev catalog advertised the id — the
|
||||
resolve_provider_full() catalog chain covers only the CLI --provider
|
||||
path, not the credential/runtime path."""
|
||||
from hermes_cli.auth import PROVIDER_REGISTRY, resolve_provider
|
||||
monkeypatch.setenv("DASHSCOPE_API_KEY", "sk-test")
|
||||
monkeypatch.setenv("ALIBABA_CODING_PLAN_API_KEY", "sk-test")
|
||||
monkeypatch.setenv("ALIBABA_TOKEN_PLAN_API_KEY", "sk-test")
|
||||
for pid in ("alibaba-cn", "alibaba-coding-plan-cn",
|
||||
"alibaba-token-plan", "alibaba-token-plan-cn"):
|
||||
assert pid in PROVIDER_REGISTRY, f"{pid} missing from PROVIDER_REGISTRY"
|
||||
assert resolve_provider(pid) == pid
|
||||
assert (PROVIDER_REGISTRY["alibaba-token-plan-cn"].inference_base_url
|
||||
== "https://token-plan.cn-beijing.maas.aliyuncs.com/compatible-mode/v1")
|
||||
|
||||
Reference in New Issue
Block a user