Files
OmniRoute/tests/unit/chat-openai-compat-providers.test.ts
Álvaro Ángel Molina 81ade9e122 feat(providers): add Typhoon (Thailand) and Inception Mercury diffusion LLM (#8170)
* feat(providers): add Typhoon and Inception Mercury API-key providers

Two OpenAI-compatible API-key providers, each verified against a live
endpoint smoke test with a negative control before registration: an
unknown route answers 404 while /v1/chat/completions answers 401, which
rules out gateways that reply identically to every path.

- typhoon (SCB 10X, Thailand): first Thai-first provider in the catalog.
  /v1/models answers 200 unauthenticated and serves exactly one chat
  model, typhoon-v2.5-30b-a3b-instruct (128K ctx). The docs also list
  typhoon-v2.1-12b-instruct, but the live endpoint no longer serves it,
  so it is deliberately not registered. The typhoon-ocr* and typhoon-asr*
  entries are OCR and speech models, not chat, and are omitted.
- inception (Inception Labs): first diffusion LLM (dLLM) in the catalog.
  mercury-2 has a 128K context, 50K max output, and supports tools,
  json_mode and structured outputs. The mercury-coder models advertised
  on the vendor blog are no longer served by the live endpoint and are
  therefore not registered.

Both expose a working /v1/models catalog, so they are added to
NAMED_OPENAI_STYLE_PROVIDERS for discovery and key validation.

Free-tier metadata is claimed only where it is documented and durable:
Typhoon issues a free API key rate-limited to 5 req/s and 200 req/m, and
Inception grants 10M tokens on signup with no card, so both are
registered with hasFree: true.

Provider count moves from 280 to 282; README/AGENTS/CLAUDE counters were
stale at 278 and are resynced against docs/reference/PROVIDER_REFERENCE.md.

* fix(8170): union frontier-labs Inception+Writer, regen ref+golden

* fix(8170): close inception object + regen ref/golden

---------

Co-authored-by: Álvaro Ángel Molina <alvaretto@users.noreply.github.com>
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
2026-07-23 08:18:16 -03:00

90 lines
2.7 KiB
TypeScript

import test from "node:test";
import assert from "node:assert/strict";
import { REGISTRY } from "../../open-sse/config/providerRegistry.ts";
import { getModelsByProviderId } from "../../src/shared/constants/models.ts";
import { APIKEY_PROVIDERS } from "../../src/shared/constants/providers.ts";
const CHAT_OPENAI_COMPAT_PROVIDER_IDS = [
"deepinfra",
"vercel-ai-gateway",
"qianfan",
"lambda-ai",
"sambanova",
"nscale",
"ovhcloud",
"baseten",
"publicai",
"moonshot",
"meta-llama",
"v0-vercel",
"morph",
"featherless-ai",
"friendliai",
"llamagate",
"heroku",
"galadriel",
"databricks",
"snowflake",
"wandb",
"volcengine",
"ai21",
"gigachat",
"venice",
"codestral",
"upstage",
"maritalk",
"xiaomi-mimo",
"inference-net",
"nanogpt",
"predibase",
"bytez",
"reka",
"byteplus",
"orcarouter",
"typhoon",
"inception",
"sarvam",
"writer",
"plamo",
"clova-studio",
"internlm",
"ant-ling",
];
test("chat-openai-compat providers are registered across provider metadata, registry and local catalog", () => {
for (const providerId of CHAT_OPENAI_COMPAT_PROVIDER_IDS) {
assert.ok(APIKEY_PROVIDERS[providerId], `${providerId} missing from APIKEY_PROVIDERS`);
assert.ok(REGISTRY[providerId], `${providerId} missing from REGISTRY`);
const models = getModelsByProviderId(providerId);
assert.ok(Array.isArray(models), `${providerId} models must be an array`);
assert.ok(models.length > 0, `${providerId} models must not be empty`);
}
});
test("orcarouter models keep the orcarouter/ namespace prefix and enable passthrough", () => {
const modelIds = REGISTRY.orcarouter.models.map((model) => model.id);
// OrcaRouter's distributor matches channels by the namespaced id, so a bare
// "auto" returns 503 "No available channel" — the router id must stay prefixed.
assert.ok(modelIds.includes("orcarouter/auto"), "expected namespaced orcarouter/auto");
assert.equal(modelIds.includes("auto"), false, "bare 'auto' would 503 upstream");
// Pinned vendor models also carry their upstream namespace.
assert.ok(modelIds.includes("anthropic/claude-opus-4.8"));
// The 150+ catalog beyond the curated flagship list is reachable via passthrough.
assert.equal(APIKEY_PROVIDERS.orcarouter.passthroughModels, true);
});
test("upstage chat catalog does not include non-chat specialty models", () => {
const modelIds = REGISTRY.upstage.models.map((model) => model.id);
assert.ok(modelIds.includes("solar-pro3"));
assert.ok(modelIds.includes("solar-mini"));
assert.equal(modelIds.includes("document-parse"), false);
assert.equal(modelIds.includes("embedding-query"), false);
assert.equal(modelIds.includes("embedding-passage"), false);
});