Files
OmniRoute/tests/unit/modelscope-provider.test.ts
Diego Rodrigues de Sa e Souza 7aaf109c0c feat(providers): add ModelScope OpenAI-compatible provider (#5965)
* feat(providers): add ModelScope OpenAI-compatible provider

Ports ModelScope (Alibaba 魔搭) as a new API-key, OpenAI-compatible
provider — upstream 9router PR #1764. The upstream PR hardcoded
`https://api-inference.modelscope.ai/...` (`.ai` TLD); verified against
ModelScope's own API-Inference docs and third-party integration guides
that the real production domain is `api-inference.modelscope.cn`
(`.cn` TLD) and shipped that instead. Also drops the PR's static
5-model snapshot in favor of `passthroughModels: true` with an empty
seed list + `modelsUrl`, since ModelScope's open-model catalog moves
fast.

Updates the providers-constants-split characterization test's hardcoded
APIKEY_PROVIDERS count (159 -> 160) to match the new entry.

Co-authored-by: Umar Javed <114807145+tn5052@users.noreply.github.com>
Inspired-by: https://github.com/decolua/9router/pull/1764

* chore(changelog): restore release entries + add modelscope bullet

* test(golden): regenerate translate-path for modelscope provider

---------

Co-authored-by: Umar Javed <114807145+tn5052@users.noreply.github.com>
2026-07-03 00:38:06 -03:00

66 lines
3.0 KiB
TypeScript

import test from "node:test";
import assert from "node:assert/strict";
import { modelscopeProvider } from "../../open-sse/config/providers/registry/modelscope/index.ts";
import { REGISTRY } from "../../open-sse/config/providerRegistry.ts";
import { APIKEY_PROVIDERS } from "../../src/shared/constants/providers/apikey/index.ts";
import { AI_PROVIDERS, getProviderById } from "../../src/shared/constants/providers.ts";
// Upstream 9router PR #1764 (@tn5052) ports ModelScope (Alibaba 魔搭) as an OpenAI-compatible
// BYOK free-tier provider. The upstream PR hardcoded `https://api-inference.modelscope.ai/...`
// (`.ai` TLD) — ModelScope's own docs confirm the real production domain is
// `api-inference.modelscope.cn` (`.cn` TLD). This suite locks in the verified domain and
// guards against a regression back to the unverified `.ai` domain.
test("providers-shape: modelscope is registered in APIKEY_PROVIDERS metadata", () => {
assert.ok("modelscope" in APIKEY_PROVIDERS, "modelscope missing from APIKEY_PROVIDERS");
const meta = (APIKEY_PROVIDERS as Record<string, Record<string, unknown>>).modelscope;
assert.equal(meta.id, "modelscope");
assert.equal(meta.alias, "ms");
assert.equal(meta.name, "ModelScope");
assert.equal(meta.website, "https://modelscope.cn");
assert.equal(meta.hasFree, true);
});
test("providers-shape: modelscope is a canonical AI_PROVIDERS entry resolvable by id", () => {
assert.ok("modelscope" in AI_PROVIDERS, "modelscope missing from AI_PROVIDERS");
const provider = getProviderById("modelscope");
assert.ok(provider, "getProviderById('modelscope') returned nothing");
assert.equal(provider?.id, "modelscope");
});
test("registry resolution: modelscope resolves in the provider REGISTRY as OpenAI-compatible", () => {
assert.ok("modelscope" in REGISTRY, "modelscope missing from REGISTRY");
const entry = REGISTRY.modelscope;
assert.equal(entry.format, "openai");
assert.equal(entry.executor, "default");
assert.equal(entry.authType, "apikey");
assert.equal(entry.authHeader, "bearer");
assert.equal(entry, modelscopeProvider);
});
test("registry resolution: modelscope uses passthrough models with an empty static seed list", () => {
assert.equal(modelscopeProvider.passthroughModels, true);
assert.deepEqual(modelscopeProvider.models, []);
assert.equal(
modelscopeProvider.modelsUrl,
"https://api-inference.modelscope.cn/v1/models",
"modelsUrl must point at the verified .cn domain"
);
});
test("baseUrl guard: modelscope targets the verified api-inference.modelscope.cn domain (not .ai)", () => {
assert.equal(
modelscopeProvider.baseUrl,
"https://api-inference.modelscope.cn/v1/chat/completions"
);
assert.ok(
modelscopeProvider.baseUrl.includes("api-inference.modelscope.cn"),
`baseUrl must use the verified .cn domain, got: ${modelscopeProvider.baseUrl}`
);
assert.ok(
!modelscopeProvider.baseUrl.includes("modelscope.ai"),
"baseUrl must not regress to the upstream PR's unverified .ai domain"
);
});