fix(ui): register tencent in the Add Model provider dropdown

The Add Model provider dropdown is driven by the proxy's
/public/providers/fields endpoint, which serves
provider_create_fields.json. Tencent was frozen in the test's
ADD_MODEL_UNLISTED_PROVIDERS set, so it never appeared in the dropdown.

Add a Tencent entry (optional api_base + required api_key, matching
TENCENT_API_BASE/TENCENT_API_KEY) and unfreeze it in the backend test.
Register Tencent in the UI Providers enum, provider_map, and placeholder
map so the dropdown resolves the display name and model placeholder.
This commit is contained in:
Jim Aldon D'Souza 2026-09-12 17:10:50 -07:00
parent d4a72e7372
commit ab87d47707
4 changed files with 68 additions and 1 deletions

View file

@ -2925,6 +2925,34 @@
],
"default_model_placeholder": "soniox/stt-async-v5"
},
{
"provider": "Tencent",
"provider_display_name": "Tencent",
"litellm_provider": "tencent",
"credential_fields": [
{
"key": "api_base",
"label": "API Base",
"placeholder": "https://tokenhub-intl.tencentcloudmaas.com/v1",
"tooltip": null,
"required": false,
"field_type": "text",
"options": null,
"default_value": null
},
{
"key": "api_key",
"label": "API Key",
"placeholder": null,
"tooltip": null,
"required": true,
"field_type": "password",
"options": null,
"default_value": null
}
],
"default_model_placeholder": "tencent/deepseek-v4-pro"
},
{
"provider": "TEXT_COMPLETION_CODESTRAL",
"provider_display_name": "Text-Completion-Codestral",

View file

@ -346,6 +346,38 @@ def test_chatgpt_provider_fields():
assert chatgpt["credential_fields"] == []
def test_tencent_provider_fields():
"""Tencent TokenHub must be selectable in the Add Model flow.
The dropdown is driven entirely by /public/providers/fields, so a missing
entry means Tencent cannot be added through the UI at all. The credential
fields must match what the backend honors: a required api_key (TENCENT_API_KEY)
and an optional api_base override (TENCENT_API_BASE).
"""
app_instance = FastAPI()
app_instance.include_router(router)
test_client = TestClient(app_instance)
response = test_client.get("/public/providers/fields")
assert response.status_code == 200
providers = response.json()
tencent = next((p for p in providers if p["provider"] == "Tencent"), None)
assert tencent is not None, "Tencent provider entry not found"
assert tencent["provider_display_name"] == "Tencent"
assert tencent["litellm_provider"] == LlmProviders.TENCENT.value
assert tencent["default_model_placeholder"].startswith("tencent/")
fields_by_key = {f["key"]: f for f in tencent["credential_fields"]}
assert fields_by_key["api_key"]["required"] is True
assert fields_by_key["api_key"]["field_type"] == "password"
assert fields_by_key["api_base"]["field_type"] == "text"
assert fields_by_key["api_base"]["required"] is False
ADD_MODEL_UNLISTED_PROVIDERS: Final = frozenset(
{
"a2a",
@ -381,7 +413,6 @@ ADD_MODEL_UNLISTED_PROVIDERS: Final = frozenset(
"scaleway",
"stability",
"synthetic",
"tencent",
"tensormesh",
"text-completion-inception",
"valkey",

View file

@ -176,6 +176,7 @@ describe("provider_info_helpers", () => {
Providers.PETALS,
Providers.PG_VECTOR,
Providers.PREDIBASE,
Providers.Tencent,
Providers.WANDB,
Providers.ZAI,
];
@ -286,6 +287,10 @@ describe("provider_info_helpers", () => {
expect(getPlaceholder("CHATGPT")).toBe("chatgpt/gpt-5.4");
});
it("should return a tencent/ placeholder for the Tencent provider", () => {
expect(getPlaceholder(Providers.Tencent)).toBe("tencent/deepseek-v4-pro");
});
it("should return default gpt-3.5-turbo placeholder for unknown provider", () => {
expect(getPlaceholder("UnknownProvider" as any)).toBe("gpt-3.5-turbo");
});

View file

@ -163,6 +163,7 @@ export enum Providers {
Snowflake = "Snowflake",
Soniox = "Soniox",
TEXT_COMPLETION_CODESTRAL = "Text-Completion-Codestral",
Tencent = "Tencent",
TogetherAI = "TogetherAI",
TOPAZ = "Topaz",
Triton = "Triton",
@ -279,6 +280,7 @@ export const provider_map: Record<string, string> = {
Snowflake: "snowflake",
Soniox: "soniox",
TEXT_COMPLETION_CODESTRAL: "text-completion-codestral",
Tencent: "tencent",
TogetherAI: "together_ai",
TOPAZ: "topaz",
Triton: "triton",
@ -441,6 +443,7 @@ const providerPlaceholderMap: Partial<Record<Providers, string>> = {
[Providers.SageMaker]: "sagemaker/jumpstart-dft-meta-textgeneration-llama-2-7b",
[Providers.SCX_AI]: "scx-ai/GLM-5.2",
[Providers.Snowflake]: "snowflake/mistral-7b",
[Providers.Tencent]: "tencent/deepseek-v4-pro",
[Providers.Vertex_AI]: "gemini-pro",
[Providers.VolcEngine]: "volcengine/<any-model-on-volcengine>",
[Providers.Voyage]: "voyage/",