mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-25 08:32:11 +03:00
* fix(providers): complete Hack Club AI removal from shared catalog (#11176) PR #11118/#11123 removed hackclub from the open-sse REGISTRY but the canonical shared catalog kept the entry, so the dashboard, alias resolver, icon registry, onboarding i18n strings and the generated provider reference kept advertising a provider the router no longer serves. Removed: - APIKEY_PROVIDERS hackclub entry (id + "hc" alias) in apikey/gateways.ts - hackclub from ProviderIcon KNOWN_SVGS + public/providers/hackclub.svg asset - providers.onboardingProviderDescriptions.hackclub from all 43 locales - stale comments referencing hackclub as a living provider (web-cookie.ts, registry/huggingchat, registry/g4f-groq, registry/freetheai, test prose) Count cascade 351 -> 350 (measured per-file; the live catalog union across all 11 provider collections goes 351 -> 350): - README.md, AGENTS.md, llm.txt + 42 i18n llm.txt mirrors (byte-identical bodies, docs-sync gate green), package.json description - docs/reference/PROVIDER_REFERENCE.md regenerated (gen-provider-reference) - canonical numbers in readme-hero/promise-pillars/comparison-table/ cli-terminal SVGs (docs-counts-sync STRICT gate green) Kept intentionally (historical records, not catalog): - CHANGELOG.md + docs/i18n/*/CHANGELOG.md entries from when the provider was added (#2339, #2611) — release history - src/lib/db/migrations/162_remove_hackclub_provider.sql — the removal migration itself - tests/unit/remove-hackclub-11118.test.ts — the REGISTRY removal guard Validation: new tests/unit/hackclub-removed.test.ts (5 asserts: catalog absence, hc alias free, structural grep over provider sources, icon/asset gone, i18n key gone) fails before / passes after; provider sibling tests 46 pass; provider-catalog consumer batch 268 pass; typecheck:core clean; eslint clean on touched files; check:provider-consistency OK (350 canonical); check:docs-counts-sync + check:docs-sync green. Closes #11176 * test(providers): align APIKEY split count after hackclub removal (232 -> 231) (#11176) --------- Co-authored-by: Xiangzhe <bakryun0718@proton.me>
98 lines
4.4 KiB
TypeScript
98 lines
4.4 KiB
TypeScript
/**
|
|
* Provider alias uniqueness — no two provider IDs may share the same short alias.
|
|
*
|
|
* Before this guard, three aliases collided in the registry and the LAST entry in
|
|
* iteration order silently won, emitting a startup warning and shadowing a real
|
|
* provider:
|
|
* - "kimi" → kimi-web (shadowed the kimi provider that gained a dedicated executor)
|
|
* - "hc" → the provider that held it shadowed huggingchat (it was later
|
|
* removed entirely, #11176; huggingchat keeps its own id as alias)
|
|
*
|
|
* The decision: the primary provider keeps the short alias; the web/secondary
|
|
* variant takes its own id as alias. This test pins both the global uniqueness
|
|
* invariant (so future additions can't silently re-collide) and the specific
|
|
* resolutions for the affected providers, across BOTH alias sources
|
|
* (open-sse registry + src/shared providers map).
|
|
*/
|
|
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
|
|
import { PROVIDER_ID_TO_ALIAS } from "../../open-sse/config/providerModels.ts";
|
|
import {
|
|
resolveProviderId,
|
|
getProviderAlias,
|
|
APIKEY_PROVIDERS,
|
|
WEB_COOKIE_PROVIDERS,
|
|
} from "../../src/shared/constants/providers.ts";
|
|
|
|
test("no two provider IDs share the same alias in the open-sse registry", () => {
|
|
const aliasToIds = new Map<string, string[]>();
|
|
for (const [id, alias] of Object.entries(PROVIDER_ID_TO_ALIAS)) {
|
|
const ids = aliasToIds.get(alias) ?? [];
|
|
ids.push(id);
|
|
aliasToIds.set(alias, ids);
|
|
}
|
|
|
|
const collisions = [...aliasToIds.entries()].filter(([, ids]) => ids.length > 1);
|
|
assert.deepEqual(
|
|
collisions,
|
|
[],
|
|
`Alias collisions detected (each alias must map to exactly one provider id): ${collisions
|
|
.map(([alias, ids]) => `"${alias}" → ${ids.join(", ")}`)
|
|
.join("; ")}`
|
|
);
|
|
});
|
|
|
|
test("primary providers keep the short alias; web variants use their own id", () => {
|
|
// open-sse registry (source of the startup warning + chat routing)
|
|
assert.equal(PROVIDER_ID_TO_ALIAS["qwen-web"], "qwen-web");
|
|
assert.equal(PROVIDER_ID_TO_ALIAS.kimi, "kimi");
|
|
assert.equal(PROVIDER_ID_TO_ALIAS["kimi-web"], "kimi-web");
|
|
assert.equal(PROVIDER_ID_TO_ALIAS.huggingchat, "huggingchat");
|
|
});
|
|
|
|
test("src/shared providers map resolves the same aliases unambiguously", () => {
|
|
// alias → id
|
|
assert.equal(resolveProviderId("kimi"), "kimi");
|
|
// id used as alias for the secondary variants
|
|
assert.equal(resolveProviderId("qwen-web"), "qwen-web");
|
|
assert.equal(resolveProviderId("kimi-web"), "kimi-web");
|
|
assert.equal(resolveProviderId("huggingchat"), "huggingchat");
|
|
// id → alias
|
|
assert.equal(getProviderAlias("kimi"), "kimi");
|
|
});
|
|
|
|
// #6673: hailuo-web must not collide with the paid API-key minimax/minimax-cn
|
|
// providers — it uses its own id as alias, per the secondary-variant convention.
|
|
test("hailuo-web resolves to its own id/alias and does not collide with minimax", () => {
|
|
assert.equal(PROVIDER_ID_TO_ALIAS["hailuo-web"], "hailuo-web");
|
|
assert.equal(resolveProviderId("hailuo-web"), "hailuo-web");
|
|
assert.equal(getProviderAlias("hailuo-web"), "hailuo-web");
|
|
assert.equal(resolveProviderId("minimax"), "minimax");
|
|
assert.equal(resolveProviderId("minimax-cn"), "minimax-cn");
|
|
});
|
|
|
|
test("freepik is the Magnific Mystic legacy alias, not a second provider id", () => {
|
|
assert.equal(resolveProviderId("freepik"), "magnific");
|
|
assert.equal(resolveProviderId("magnific"), "magnific");
|
|
assert.equal(getProviderAlias("magnific"), "freepik");
|
|
assert.ok("magnific" in APIKEY_PROVIDERS);
|
|
assert.ok(!("freepik" in APIKEY_PROVIDERS));
|
|
});
|
|
|
|
test("no provider id is registered in both the API-key and web-cookie catalogs", () => {
|
|
// A provider belongs to exactly one auth category; the same id in both catalogs
|
|
// renders the provider twice in the dashboard (once per section). huggingchat
|
|
// regressed this way (its API-key counterpart is the separate `huggingface`
|
|
// Inference API id), so it must live ONLY in WEB_COOKIE_PROVIDERS.
|
|
const apikeyIds = new Set(Object.keys(APIKEY_PROVIDERS));
|
|
const overlap = Object.keys(WEB_COOKIE_PROVIDERS).filter((id) => apikeyIds.has(id));
|
|
assert.deepEqual(overlap, [], `Providers duplicated across catalogs: ${overlap.join(", ")}`);
|
|
|
|
assert.ok("huggingchat" in WEB_COOKIE_PROVIDERS, "huggingchat must be in the web-cookie catalog");
|
|
assert.ok(
|
|
!("huggingchat" in APIKEY_PROVIDERS),
|
|
"huggingchat must NOT be in the API-key catalog (use `huggingface` for the API key path)"
|
|
);
|
|
});
|