fix(providers): add missing modelsUrl for qwen-cloud-token-plan (#13764)

Merged. One missing field, one very concrete symptom: without `modelsUrl` the import silently fell back to the local catalog with "API unavailable". The test asserts both the registry entry and the derivation, so a future registry edit cannot drop it again.

Validated as a combined board first (this PR merged with the 21 siblings of the same wave on the release tip): eslint with the frozen suppressions, typecheck:core, check:open-sse-typecheck, complexity, cognitive-complexity, changelog-integrity, i18n new-key coverage, docs-counts, docs-sync, migration-numbering, provider-consistency and a duplicate-identifier audit all green, plus 176 passing / 0 failing focused node:test cases across the 25 test files the wave touches and the dashboard test under Vitest (2/0). Then re-validated alone on the fresh tip before this merge: conflicts re-resolved, file sizes rebaselined for this PR's own growth, eslint and this PR's focused tests re-run.

Thank you.
This commit is contained in:
lorenzozane
2026-09-17 00:07:39 +08:00
committed by GitHub
parent e7999c477b
commit ed2e22197a
2 changed files with 48 additions and 0 deletions

View File

@@ -7,6 +7,7 @@ export const qwen_cloud_token_planProvider: RegistryEntry = {
executor: "default",
baseUrl:
"https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1/chat/completions",
modelsUrl: "https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1/models",
authType: "apikey",
authHeader: "bearer",
models: [

View File

@@ -0,0 +1,47 @@
import test from "node:test";
import assert from "node:assert/strict";
import { qwen_cloud_token_planProvider } from "../../open-sse/config/providers/registry/qwen-cloud-token-plan/index.ts";
import { deriveConfigFromRegistryModelsUrl } from "../../src/app/api/providers/[id]/models/discoveryConfig.ts";
const SPEC_MODELS_URL =
"https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1/models";
test("qwen-cloud-token-plan registry entry exposes the live /v1/models URL", () => {
assert.equal(qwen_cloud_token_planProvider.id, "qwen-cloud-token-plan");
// Without modelsUrl, deriveConfigFromRegistryModelsUrl() returns undefined and
// model discovery falls back to the local catalog
// ("API unavailable — using local catalog", issue #13506).
assert.equal(qwen_cloud_token_planProvider.modelsUrl, SPEC_MODELS_URL);
});
test("deriveConfigFromRegistryModelsUrl covers qwen-cloud-token-plan", () => {
const config = deriveConfigFromRegistryModelsUrl("qwen-cloud-token-plan");
assert.ok(config, "expected a discovery config derived from the registry modelsUrl");
assert.equal(config.url, SPEC_MODELS_URL);
assert.equal(config.method, "GET");
assert.equal(config.authHeader, "Authorization");
assert.equal(config.authPrefix, "Bearer ");
});
test("derived config parses the token-plan OpenAI-style list response", () => {
const config = deriveConfigFromRegistryModelsUrl("qwen-cloud-token-plan");
assert.ok(config);
// Shape verified manually against the live endpoint in issue #13506.
const live = {
first_id: "model-id-0",
data: [
{ created: 1785722409, owned_by: "system", id: "qwen3.8-max", object: "model" },
{ created: 1787731683, owned_by: "system", id: "qwen3.8-flash", object: "model" },
],
last_id: "model-id-11",
has_more: false,
object: "list",
};
const models = config.parseResponse(live) as Array<{ id: string }>;
assert.equal(models.length, 2);
assert.deepEqual(
models.map((m) => m.id),
["qwen3.8-max", "qwen3.8-flash"]
);
});