Compare commits

..

5 Commits

Author SHA1 Message Date
backryun
90ced7290a sync #9669 onto release
# Conflicts:
#	tests/unit/chatcore-plugin-onresponse.test.ts
2026-08-12 02:15:43 -03:00
diegosouzapw
4a2a9978bc Merge remote-tracking branch 'origin/release/v3.8.50' into feat/9571-plugin-streaming-usage-timing 2026-08-07 11:52:33 -03:00
diegosouzapw
867fbc8bad fix(changelog): remove YAML frontmatter from 9571 fragment
The changelog fragment format requires the first non-empty line to be
a markdown bullet ("- "). YAML frontmatter was the first non-empty
line, causing the integrity check to fail.
2026-08-07 01:11:58 -03:00
diegosouzapw
d557ea2222 Merge remote-tracking branch 'origin/release/v3.8.50' into babysit/9571-plugin-streaming-usage-timing 2026-08-06 23:58:33 -03:00
diegosouzapw
1bdd1be8c6 feat(plugins): add onStreamComplete built-in event exposing streaming usage and timing (#9571) 2026-08-06 21:40:40 -03:00
43 changed files with 54 additions and 1079 deletions

View File

@@ -233,32 +233,6 @@ import { hyperagentProvider } from "./registry/hyperagent/index.ts";
import { muse_codeProvider } from "./registry/muse-code/index.ts";
import { naga_acProvider } from "./registry/naga-ac/index.ts";
import { chatanywhereProvider } from "./registry/chatanywhere/index.ts";
import { zyloApiProvider } from "./registry/zylo-api/index.ts";
import { poolsideProvider } from "./registry/poolside/index.ts";
import { fastrouterProvider } from "./registry/fastrouter/index.ts";
import { anyapiProvider } from "./registry/anyapi/index.ts";
import { electronhubProvider } from "./registry/electronhub/index.ts";
import { llmgatewayProvider } from "./registry/llmgateway/index.ts";
import { llmKiwiProvider } from "./registry/llm-kiwi/index.ts";
import { literouterProvider } from "./registry/literouter/index.ts";
import { mnnAiProvider } from "./registry/mnn-ai/index.ts";
import { meganovaAiProvider } from "./registry/meganova-ai/index.ts";
import { mixlayerProvider } from "./registry/mixlayer/index.ts";
import { spekaProvider } from "./registry/speka/index.ts";
import { tokenreplyProvider } from "./registry/tokenreply/index.ts";
import { yoloAutoProvider } from "./registry/yolo-auto/index.ts";
import { dxntProvider } from "./registry/dxnt/index.ts";
import { cloudcodeOneProvider } from "./registry/cloudcode-one/index.ts";
import { ofoxaiProvider } from "./registry/ofoxai/index.ts";
import { zerolimitaiProvider } from "./registry/zerolimitai/index.ts";
import { helyxaiProvider } from "./registry/helyxai/index.ts";
import { aurikoProvider } from "./registry/auriko/index.ts";
import { poixeAiProvider } from "./registry/poixe-ai/index.ts";
import { nagaAiProvider } from "./registry/naga-ai/index.ts";
import { chatOripeProvider } from "./registry/chat-oripe/index.ts";
import { freeinferenceProvider } from "./registry/freeinference/index.ts";
import { freeAiProvider } from "./registry/free-ai/index.ts";
export const REGISTRY: Record<string, RegistryEntry> = {
aimlapi: aimlapiProvider,
@@ -491,33 +465,7 @@ export const REGISTRY: Record<string, RegistryEntry> = {
promptql: promptqlProvider,
hyperagent: hyperagentProvider,
"muse-code": muse_codeProvider,
"zylo-api": zyloApiProvider,
unorouter: unorouterProvider,
"naga-ac": naga_acProvider,
chatanywhere: chatanywhereProvider,
poolside: poolsideProvider,
fastrouter: fastrouterProvider,
anyapi: anyapiProvider,
electronhub: electronhubProvider,
llmgateway: llmgatewayProvider,
"llm-kiwi": llmKiwiProvider,
literouter: literouterProvider,
"mnn-ai": mnnAiProvider,
"meganova-ai": meganovaAiProvider,
mixlayer: mixlayerProvider,
speka: spekaProvider,
tokenreply: tokenreplyProvider,
"yolo-auto": yoloAutoProvider,
dxnt: dxntProvider,
"cloudcode-one": cloudcodeOneProvider,
ofoxai: ofoxaiProvider,
zerolimitai: zerolimitaiProvider,
helyxai: helyxaiProvider,
auriko: aurikoProvider,
"poixe-ai": poixeAiProvider,
"naga-ai": nagaAiProvider,
"chat-oripe": chatOripeProvider,
freeinference: freeinferenceProvider,
"free-ai": freeAiProvider,
};

View File

@@ -1,11 +0,0 @@
import type { RegistryEntry } from "../../shared.ts";
import { buildOpenAiCompatibleRegistryEntry } from "../../shared.ts";
export const aurikoProvider: RegistryEntry = buildOpenAiCompatibleRegistryEntry({
id: "auriko",
alias: "auriko",
baseUrl: "https://api.auriko.ai/v1/chat/completions",
modelsUrl: "https://api.auriko.ai/v1/models",
models: [],
passthroughModels: true,
});

View File

@@ -1,12 +0,0 @@
import type { RegistryEntry } from "../../shared.ts";
import { buildOpenAiCompatibleRegistryEntry } from "../../shared.ts";
// The upstream brand and hostname are ambiguous, so avoid unverified quota claims.
export const chatOripeProvider: RegistryEntry = buildOpenAiCompatibleRegistryEntry({
id: "chat-oripe",
alias: "chat-oripe",
baseUrl: "https://api.oriper.com/v1/chat/completions",
modelsUrl: "https://api.oriper.com/v1/models",
models: [],
passthroughModels: true,
});

View File

@@ -1,12 +1,17 @@
import type { RegistryEntry } from "../../shared.ts";
import { buildOpenAiCompatibleRegistryEntry } from "../../shared.ts";
// International endpoint; audited free access is limited to non-commercial use.
export const chatanywhereProvider: RegistryEntry = buildOpenAiCompatibleRegistryEntry({
// ChatAnywhere (api.chatanywhere.tech) — OpenAI-compatible gateway from the
// chatanywhere/GPT_API_free project (~38.7k GitHub stars). Requires GitHub-account-
// gated API key. Free tier is for personal non-commercial use only.
export const chatanywhereProvider: RegistryEntry = {
id: "chatanywhere",
alias: "chatanywhere",
baseUrl: "https://api.chatanywhere.org/v1/chat/completions",
modelsUrl: "https://api.chatanywhere.org/v1/models",
models: [],
alias: "chtany",
format: "openai",
executor: "default",
baseUrl: "https://api.chatanywhere.tech/v1/chat/completions",
modelsUrl: "https://api.chatanywhere.tech/v1/models",
authType: "apikey",
authHeader: "bearer",
passthroughModels: true,
});
models: [],
};

View File

@@ -1,20 +0,0 @@
import type { RegistryEntry } from "../../shared.ts";
import { buildOpenAiCompatibleRegistryEntry } from "../../shared.ts";
/**
* CloudCode.ONE - OpenAI-compatible API with published free model aliases.
*
* The Anthropic-compatible endpoint is documented separately; this registry
* covers the OpenAI-compatible API surface audited for this migration.
*/
export const cloudcodeOneProvider: RegistryEntry = buildOpenAiCompatibleRegistryEntry({
id: "cloudcode-one",
alias: "cloudcode-one",
baseUrl: "https://api.cloudcode.one/v1/chat/completions",
modelsUrl: "https://api.cloudcode.one/v1/models",
models: [
{ id: "glm-4.7-flash", name: "GLM 4.7 Flash" },
{ id: "glm-4.6v-flash", name: "GLM 4.6V Flash" },
],
passthroughModels: true,
});

View File

@@ -1,5 +1,5 @@
import type { RegistryEntry } from "../../shared.ts";
import { CONOL_FALLBACK_MODELS } from "../../../../services/conolModels.ts";
import { CONOL_FALLBACK_MODELS } from "../../../services/conolModels.ts";
export const conol_webProvider: RegistryEntry = {
id: "conol-web",

View File

@@ -1,17 +0,0 @@
import type { RegistryEntry } from "../../shared.ts";
import { buildOpenAiCompatibleRegistryEntry } from "../../shared.ts";
/**
* DXNT - OpenAI-compatible API with a free account quota.
*
* Models are discovered from the provider's authenticated catalog rather than
* copied into a static list, so account-specific availability remains intact.
*/
export const dxntProvider: RegistryEntry = buildOpenAiCompatibleRegistryEntry({
id: "dxnt",
alias: "dxnt",
baseUrl: "https://www.dxnt.com/v1/chat/completions",
modelsUrl: "https://www.dxnt.com/v1/models",
models: [],
passthroughModels: true,
});

View File

@@ -1,11 +0,0 @@
import type { RegistryEntry } from "../../shared.ts";
import { buildOpenAiCompatibleRegistryEntry } from "../../shared.ts";
export const freeAiProvider: RegistryEntry = buildOpenAiCompatibleRegistryEntry({
id: "free-ai",
alias: "free-ai",
baseUrl: "https://api.free.ai/v1/chat/",
modelsUrl: "https://api.free.ai/v1/models",
models: [],
passthroughModels: true,
});

View File

@@ -1,11 +0,0 @@
import type { RegistryEntry } from "../../shared.ts";
import { buildOpenAiCompatibleRegistryEntry } from "../../shared.ts";
export const freeinferenceProvider: RegistryEntry = buildOpenAiCompatibleRegistryEntry({
id: "freeinference",
alias: "freeinference",
baseUrl: "https://freeinference.org/v1/chat/completions",
modelsUrl: "https://freeinference.org/v1/models",
models: [],
passthroughModels: true,
});

View File

@@ -1,11 +0,0 @@
import type { RegistryEntry } from "../../shared.ts";
import { buildOpenAiCompatibleRegistryEntry } from "../../shared.ts";
export const helyxaiProvider: RegistryEntry = buildOpenAiCompatibleRegistryEntry({
id: "helyxai",
alias: "helyxai",
baseUrl: "https://helyxai.space/v1/chat/completions",
modelsUrl: "https://helyxai.space/v1/models",
models: [],
passthroughModels: true,
});

View File

@@ -1,11 +0,0 @@
import type { RegistryEntry } from "../../shared.ts";
import { buildOpenAiCompatibleRegistryEntry } from "../../shared.ts";
export const literouterProvider: RegistryEntry = buildOpenAiCompatibleRegistryEntry({
id: "literouter",
alias: "literouter",
baseUrl: "https://api.literouter.com/v1/chat/completions",
modelsUrl: "https://api.literouter.com/v1/models",
models: [],
passthroughModels: true,
});

View File

@@ -1,11 +0,0 @@
import type { RegistryEntry } from "../../shared.ts";
import { buildOpenAiCompatibleRegistryEntry } from "../../shared.ts";
export const meganovaAiProvider: RegistryEntry = buildOpenAiCompatibleRegistryEntry({
id: "meganova-ai",
alias: "meganova-ai",
baseUrl: "https://api.meganova.ai/v1/chat/completions",
modelsUrl: "https://api.meganova.ai/v1/models",
models: [],
passthroughModels: true,
});

View File

@@ -1,11 +0,0 @@
import type { RegistryEntry } from "../../shared.ts";
import { buildOpenAiCompatibleRegistryEntry } from "../../shared.ts";
export const mixlayerProvider: RegistryEntry = buildOpenAiCompatibleRegistryEntry({
id: "mixlayer",
alias: "mixlayer",
baseUrl: "https://models.mixlayer.ai/v1/chat/completions",
modelsUrl: "https://models.mixlayer.ai/v1/models",
models: [{ id: "qwen/qwen3.5-4b-free", name: "Qwen 3.5 4B (free)" }],
passthroughModels: true,
});

View File

@@ -1,11 +0,0 @@
import type { RegistryEntry } from "../../shared.ts";
import { buildOpenAiCompatibleRegistryEntry } from "../../shared.ts";
export const mnnAiProvider: RegistryEntry = buildOpenAiCompatibleRegistryEntry({
id: "mnn-ai",
alias: "mnn-ai",
baseUrl: "https://api.mnnai.ru/v1/chat/completions",
modelsUrl: "https://api.mnnai.ru/v1/models",
models: [],
passthroughModels: true,
});

View File

@@ -1,12 +0,0 @@
import type { RegistryEntry } from "../../shared.ts";
import { buildOpenAiCompatibleRegistryEntry } from "../../shared.ts";
// Free access terms may permit data collection or training use; discover models dynamically.
export const nagaAiProvider: RegistryEntry = buildOpenAiCompatibleRegistryEntry({
id: "naga-ai",
alias: "naga-ai",
baseUrl: "https://api.naga.ac/v1/chat/completions",
modelsUrl: "https://api.naga.ac/v1/models",
models: [],
passthroughModels: true,
});

View File

@@ -1,11 +0,0 @@
import type { RegistryEntry } from "../../shared.ts";
import { buildOpenAiCompatibleRegistryEntry } from "../../shared.ts";
export const ofoxaiProvider: RegistryEntry = buildOpenAiCompatibleRegistryEntry({
id: "ofoxai",
alias: "ofoxai",
baseUrl: "https://api.ofox.ai/v1/chat/completions",
modelsUrl: "https://api.ofox.ai/v1/models",
models: [],
passthroughModels: true,
});

View File

@@ -1,11 +0,0 @@
import type { RegistryEntry } from "../../shared.ts";
import { buildOpenAiCompatibleRegistryEntry } from "../../shared.ts";
export const poixeAiProvider: RegistryEntry = buildOpenAiCompatibleRegistryEntry({
id: "poixe-ai",
alias: "poixe-ai",
baseUrl: "https://api.poixe.com/v1/chat/completions",
modelsUrl: "https://api.poixe.com/v1/models",
models: [],
passthroughModels: true,
});

View File

@@ -1,11 +0,0 @@
import type { RegistryEntry } from "../../shared.ts";
import { buildOpenAiCompatibleRegistryEntry } from "../../shared.ts";
export const spekaProvider: RegistryEntry = buildOpenAiCompatibleRegistryEntry({
id: "speka",
alias: "speka",
baseUrl: "https://speka.me/v1/chat/completions",
modelsUrl: "https://speka.me/v1/models",
models: [],
passthroughModels: true,
});

View File

@@ -1,11 +0,0 @@
import type { RegistryEntry } from "../../shared.ts";
import { buildOpenAiCompatibleRegistryEntry } from "../../shared.ts";
export const tokenreplyProvider: RegistryEntry = buildOpenAiCompatibleRegistryEntry({
id: "tokenreply",
alias: "tokenreply",
baseUrl: "https://api.tokenreply.com/v1/chat/completions",
modelsUrl: "https://api.tokenreply.com/v1/models",
models: [],
passthroughModels: true,
});

View File

@@ -1,11 +1,14 @@
import type { RegistryEntry } from "../../shared.ts";
import { buildOpenAiCompatibleRegistryEntry } from "../../shared.ts";
export const unorouterProvider: RegistryEntry = buildOpenAiCompatibleRegistryEntry({
export const unorouterProvider: RegistryEntry = {
id: "unorouter",
alias: "unorouter",
baseUrl: "https://api.unorouter.com/v1/chat/completions",
modelsUrl: "https://api.unorouter.com/v1/models",
models: [],
format: "openai",
executor: "default",
baseUrl: "https://api.unorouter.ai/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
defaultContextLength: 128000,
models: [{ id: "auto", name: "Auto (Best Available)" }],
passthroughModels: true,
});
};

View File

@@ -1,17 +0,0 @@
import type { RegistryEntry } from "../../shared.ts";
import { buildOpenAiCompatibleRegistryEntry } from "../../shared.ts";
/**
* Yolo-Auto - OpenAI-compatible API with a request-limited free tier.
*
* The catalog is kept intentionally small: the documented free-tier model is
* seeded while passthrough discovery allows the service to publish updates.
*/
export const yoloAutoProvider: RegistryEntry = buildOpenAiCompatibleRegistryEntry({
id: "yolo-auto",
alias: "yolo-auto",
baseUrl: "https://yolo-auto.com/v1/chat/completions",
modelsUrl: "https://yolo-auto.com/v1/models",
models: [{ id: "qwen3.6-35b-a3b", name: "Qwen 3.6 35B A3B" }],
passthroughModels: true,
});

View File

@@ -1,11 +0,0 @@
import type { RegistryEntry } from "../../shared.ts";
import { buildOpenAiCompatibleRegistryEntry } from "../../shared.ts";
export const zerolimitaiProvider: RegistryEntry = buildOpenAiCompatibleRegistryEntry({
id: "zerolimitai",
alias: "zerolimitai",
baseUrl: "https://www.zerolimitai.com/api/v1/chat/completions",
modelsUrl: "https://www.zerolimitai.com/api/v1/models",
models: [],
passthroughModels: true,
});

View File

@@ -1,5 +1,3 @@
import { randomUUID } from "node:crypto";
import { BaseExecutor, type ExecuteInput } from "./base.ts";
import { makeExecutorErrorResult as makeErrorResult } from "../utils/error.ts";
import { initTinyCmsWasm, generateSecurePayload } from "./tinycmsSigner.ts";
@@ -30,9 +28,9 @@ async function fetchChallenge(uuid: string): Promise<any> {
const res = await fetch(CHALLENGE_URL, {
method: "GET",
headers: {
uuid: uuid,
"uuid": uuid,
"x-origin": "https://gov.freegpt.win",
Accept: "application/json",
"Accept": "application/json",
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36",
},
});
@@ -69,10 +67,10 @@ export class TinyCmsExecutor extends BaseExecutor {
const challengeObj = await fetchChallenge(uuid);
const timestamp = Date.now().toString();
// The nonce is signed into the anti-replay payload below, so it must come from a CSPRNG.
// `randomUUID` from node:crypto is always available on the supported runtimes — the old
// non-cryptographic fallback produced a predictable nonce with no way to notice.
const nonceJs = randomUUID();
const nonceJs =
typeof crypto !== "undefined" && crypto.randomUUID
? crypto.randomUUID()
: `${Date.now()}-${Math.random().toString(16).slice(2)}`;
const securePayload = generateSecurePayload(
uuid,
@@ -123,7 +121,12 @@ export class TinyCmsExecutor extends BaseExecutor {
body: response.body,
};
} catch (err: any) {
return makeErrorResult(500, `TinyCMS Error: ${err.message}`, body, CHAT_URL);
return makeErrorResult(
500,
`TinyCMS Error: ${err.message}`,
body,
CHAT_URL
);
}
}
}

View File

@@ -237,16 +237,12 @@ function trustedEnvironmentText(parsed: CodexParsedRequest): string {
}
function decodeXmlText(value: string): string {
// `&amp;` MUST be decoded last: decoding it first turns `&amp;quot;` (the encoding of the
// literal text `&quot;`) into `&quot;`, which the following pass then decodes again into `"`.
// These values feed the workspace-root trust comparison below, so a double-unescape lets an
// encoded path decode into a different path than the one the client actually declared.
return value
.replaceAll("&lt;", "<")
.replaceAll("&gt;", ">")
.replaceAll("&amp;", "&")
.replaceAll("&quot;", '"')
.replaceAll("&#39;", "'")
.replaceAll("&amp;", "&");
.replaceAll("&#39;", "'");
}
function uniqueAbsolutePaths(values: string[], field: string): string[] {

View File

@@ -7,33 +7,6 @@ export const PROVIDER_ENDPOINTS = {
dgrid: "https://api.dgrid.ai/v1/chat/completions",
bai: "https://api.b.ai/v1/chat/completions",
qiniu: "https://api.qnaigc.com/v1/chat/completions",
"zylo-api": "https://api.zyloai.net/v1/chat/completions",
unorouter: "https://api.unorouter.com/v1/chat/completions",
poolside: "https://inference.poolside.ai/v1/chat/completions",
fastrouter: "https://api.fastrouter.ai/api/v1/chat/completions",
anyapi: "https://api.anyapi.ai/v1/chat/completions",
electronhub: "https://api.electronhub.ai/v1/chat/completions",
llmgateway: "https://api.llmgateway.io/v1/chat/completions",
"llm-kiwi": "https://api.llm.kiwi/v1/chat/completions",
literouter: "https://api.literouter.com/v1/chat/completions",
"mnn-ai": "https://api.mnnai.ru/v1/chat/completions",
"meganova-ai": "https://api.meganova.ai/v1/chat/completions",
mixlayer: "https://models.mixlayer.ai/v1/chat/completions",
speka: "https://speka.me/v1/chat/completions",
tokenreply: "https://api.tokenreply.com/v1/chat/completions",
"yolo-auto": "https://yolo-auto.com/v1/chat/completions",
dxnt: "https://www.dxnt.com/v1/chat/completions",
"cloudcode-one": "https://api.cloudcode.one/v1/chat/completions",
ofoxai: "https://api.ofox.ai/v1/chat/completions",
zerolimitai: "https://www.zerolimitai.com/api/v1/chat/completions",
chatanywhere: "https://api.chatanywhere.org/v1/chat/completions",
helyxai: "https://helyxai.space/v1/chat/completions",
auriko: "https://api.auriko.ai/v1/chat/completions",
"poixe-ai": "https://api.poixe.com/v1/chat/completions",
"naga-ai": "https://api.naga.ac/v1/chat/completions",
"chat-oripe": "https://api.oriper.com/v1/chat/completions",
freeinference: "https://freeinference.org/v1/chat/completions",
"free-ai": "https://api.free.ai/v1/chat/",
glm: "https://api.z.ai/api/anthropic/v1/messages",
glmt: "https://api.z.ai/api/anthropic/v1/messages",
"bailian-coding-plan": "https://coding-intl.dashscope.aliyuncs.com/apps/anthropic/v1/messages",

View File

@@ -21,10 +21,7 @@ import { PROVIDER_MODELS as MODELS } from "@omniroute/open-sse/config/providerMo
const PASSTHROUGH_PROVIDERS = new Set(
Object.entries(AI_PROVIDERS)
.filter(([, p]) => (p as any).passthroughModels)
.flatMap(([key, provider]) => {
const alias = (provider as { alias?: unknown }).alias;
return typeof alias === "string" && alias.length > 0 ? [key, alias] : [key];
})
.map(([key]) => key)
);
// Wrap isValidModel with passthrough providers

View File

@@ -96,32 +96,7 @@ export const AGGREGATOR_PROVIDER_IDS = new Set([
"g4f-nvidia",
"naga-ac",
"chatanywhere",
"zylo-api",
"fastrouter",
"anyapi",
"electronhub",
"llmgateway",
"llm-kiwi",
"literouter",
"mnn-ai",
"meganova-ai",
"mixlayer",
"speka",
"tokenreply",
"yolo-auto",
"dxnt",
"cloudcode-one",
"ofoxai",
"zerolimitai",
"helyxai",
"auriko",
"poixe-ai",
"naga-ai",
"chat-oripe",
"freeinference",
"free-ai",
]);;
]);
export const ENTERPRISE_CLOUD_PROVIDER_IDS = new Set([
"azure-openai",

View File

@@ -53,9 +53,6 @@ export const APIKEY_PROVIDERS_GATEWAYS = {
color: "#8B5CF6",
textIcon: "UR",
passthroughModels: true,
hasFree: true,
freeNote:
"Models with the :free suffix do not debit balance; limit is 1 request/minute per free model per user.",
website: "https://unorouter.ai",
apiHint: "Create an API key at https://unorouter.ai, then paste it here as a Bearer token.",
},
@@ -442,37 +439,6 @@ export const APIKEY_PROVIDERS_GATEWAYS = {
apiHint:
"Use https://api.oriper.com/v1 only after confirming the provider's current documentation, terms and key issuance. No quota is guaranteed by this catalog.",
},
freeinference: {
id: "freeinference",
alias: "freeinference",
name: "FreeInference",
icon: "science",
color: "#8B5CF6",
textIcon: "FI",
passthroughModels: true,
website: "https://freeinference.org",
hasFree: true,
freeNote:
"Free research access without a card; non-Harvard applicants require manual approval and no numeric quota is publicly guaranteed.",
apiHint:
"Apply for a FreeInference key, then use https://freeinference.org/v1 as the OpenAI-compatible base URL. Terms allow prompt/response logging and possible publication of anonymized research data; never send sensitive or production data.",
},
"free-ai": {
id: "free-ai",
alias: "free-ai",
name: "Free.ai",
icon: "hub",
color: "#16A34A",
textIcon: "FA",
passthroughModels: true,
website: "https://free.ai",
hasFree: true,
freeNote:
"30,000 tokens/day cover self-hosted models after email verification. Usage beyond the pool can bill at raw cost, and premium external models are paid.",
apiHint:
"Create an sk-free- key, then use the nonstandard but OpenAI-shaped https://api.free.ai/v1/chat/ endpoint. Select a self-hosted zero-price model to stay within the free pool.",
},
dgrid: {
id: "dgrid",
alias: "dgrid",
@@ -1213,7 +1179,6 @@ export const APIKEY_PROVIDERS_GATEWAYS = {
authHint: "Get your Regolo API key from regolo.ai, then paste it here as a Bearer token.",
apiHint:
"OpenAI-compatible endpoint at https://api.regolo.ai/v1 with dynamic model discovery (19 models).",
},
"naga-ac": {
id: "naga-ac",
alias: "naga",
@@ -1230,4 +1195,19 @@ export const APIKEY_PROVIDERS_GATEWAYS = {
authHint:
"Get API key at naga.ac — Google/GitHub/Discord signup available.",
},
chatanywhere: {
id: "chatanywhere",
alias: "chtany",
name: "ChatAnywhere",
icon: "chat",
color: "#10B981",
textIcon: "CA",
website: "https://api.chatanywhere.tech",
hasFree: true,
freeNote:
"Free tier: 5 req/day for GPT-5/4o/4.1, 30/day DeepSeek, 200/day gpt-4o-mini. Personal non-commercial use only — see chatanywhere/GPT_API_free. Requires GitHub-account-gated API key.",
passthroughModels: true,
authHint:
"Get free API key at api.chatanywhere.tech — requires GitHub account signup.",
},
};

View File

@@ -45,21 +45,6 @@ export const APIKEY_PROVIDERS_INFERENCE = {
hasFree: true,
freeNote: "Free plan: 3-day trial with open-source models — no credit card required",
},
poolside: {
id: "poolside",
alias: "poolside",
name: "Poolside",
icon: "memory",
color: "#111827",
textIcon: "PS",
passthroughModels: true,
website: "https://poolside.ai",
hasFree: true,
freeNote:
"Laguna S 2.1 and XS 2.1 are free during Preview; no public numeric quota is published.",
apiHint:
"Create a free developer API key, then use https://inference.poolside.ai/v1 as the OpenAI-compatible base URL.",
},
fireworks: {
id: "fireworks",
alias: "fireworks",

View File

@@ -1,55 +0,0 @@
import assert from "node:assert/strict";
import test from "node:test";
const { REGISTRY } = await import("../../open-sse/config/providerRegistry.ts");
const { DefaultExecutor, getExecutor } = await import("../../open-sse/executors/index.ts");
const { PROVIDER_ENDPOINTS } = await import("../../src/shared/constants/config.ts");
const { isValidModel } = await import("../../src/shared/constants/models.ts");
const { AGGREGATOR_PROVIDER_IDS } = await import("../../src/shared/constants/providers.ts");
const { APIKEY_PROVIDERS } = await import("../../src/shared/constants/providers/apikey/index.ts");
const providers = [
["zylo-api", "zylo", "https://api.zyloai.net/v1/chat/completions"],
["unorouter", "unorouter", "https://api.unorouter.com/v1/chat/completions"],
["poolside", "poolside", "https://inference.poolside.ai/v1/chat/completions"],
["fastrouter", "fastrouter", "https://api.fastrouter.ai/api/v1/chat/completions"],
["anyapi", "anyapi", "https://api.anyapi.ai/v1/chat/completions"],
["electronhub", "electronhub", "https://api.electronhub.ai/v1/chat/completions"],
["llmgateway", "llmgateway", "https://api.llmgateway.io/v1/chat/completions"],
["llm-kiwi", "llmkiwi", "https://api.llm.kiwi/v1/chat/completions"],
] as const;
for (const [id, alias, endpoint] of providers) {
test(`${id} is wired through registry, metadata, endpoint and default executor`, () => {
const registry = REGISTRY[id];
const metadata = APIKEY_PROVIDERS[id];
assert.ok(registry);
assert.ok(metadata);
assert.equal(registry.id, id);
assert.equal(registry.alias, alias);
assert.equal(registry.baseUrl, endpoint);
assert.equal(PROVIDER_ENDPOINTS[id], endpoint);
assert.equal(metadata.id, id);
assert.equal(metadata.alias, alias);
assert.equal(metadata.hasFree, true);
assert.equal(metadata.passthroughModels, true);
assert.ok(typeof metadata.freeNote === "string" && metadata.freeNote.length > 0);
assert.ok(getExecutor(id) instanceof DefaultExecutor);
assert.equal(isValidModel(id, "future/live-catalog-model"), true);
assert.equal(isValidModel(alias, "future/live-catalog-model"), true);
});
}
test("gateway providers are classified as aggregators while direct Poolside is not", () => {
const gatewayIds = providers.map(([id]) => id).filter((id) => id !== "poolside");
for (const id of gatewayIds) assert.equal(AGGREGATOR_PROVIDER_IDS.has(id), true);
assert.equal(AGGREGATOR_PROVIDER_IDS.has("poolside"), false);
});
test("LLM.Kiwi statically exposes only the confirmed Free plan models", () => {
assert.deepEqual(REGISTRY["llm-kiwi"].models, [
{ id: "auto", name: "Auto" },
{ id: "hrLLM", name: "hrLLM" },
]);
});

View File

@@ -1,51 +0,0 @@
import assert from "node:assert/strict";
import test from "node:test";
import { literouterProvider } from "../../open-sse/config/providers/registry/literouter/index.ts";
import { meganovaAiProvider } from "../../open-sse/config/providers/registry/meganova-ai/index.ts";
import { mnnAiProvider } from "../../open-sse/config/providers/registry/mnn-ai/index.ts";
import type { RegistryEntry } from "../../open-sse/config/providers/shared.ts";
const providers: Array<{
entry: RegistryEntry;
id: string;
chatUrl: string;
modelsUrl: string;
}> = [
{
entry: literouterProvider,
id: "literouter",
chatUrl: "https://api.literouter.com/v1/chat/completions",
modelsUrl: "https://api.literouter.com/v1/models",
},
{
entry: mnnAiProvider,
id: "mnn-ai",
chatUrl: "https://api.mnnai.ru/v1/chat/completions",
modelsUrl: "https://api.mnnai.ru/v1/models",
},
{
entry: meganovaAiProvider,
id: "meganova-ai",
chatUrl: "https://api.meganova.ai/v1/chat/completions",
modelsUrl: "https://api.meganova.ai/v1/models",
},
];
for (const { entry, id, chatUrl, modelsUrl } of providers) {
test(`${id} uses an OpenAI-compatible Bearer registry entry`, () => {
assert.equal(entry.id, id);
assert.equal(entry.alias, id);
assert.equal(entry.format, "openai");
assert.equal(entry.executor, "default");
assert.equal(entry.authType, "apikey");
assert.equal(entry.authHeader, "bearer");
assert.equal(entry.baseUrl, chatUrl);
assert.equal(entry.modelsUrl, modelsUrl);
assert.equal(entry.passthroughModels, true);
});
test(`${id} leaves model discovery to the live upstream catalog`, () => {
assert.deepEqual(entry.models, []);
});
}

View File

@@ -1,60 +0,0 @@
import assert from "node:assert/strict";
import test from "node:test";
import { mixlayerProvider } from "../../open-sse/config/providers/registry/mixlayer/index.ts";
import { spekaProvider } from "../../open-sse/config/providers/registry/speka/index.ts";
import { tokenreplyProvider } from "../../open-sse/config/providers/registry/tokenreply/index.ts";
import type { RegistryEntry } from "../../open-sse/config/providers/shared.ts";
const providers: Array<{
entry: RegistryEntry;
id: string;
chatUrl: string;
modelsUrl: string;
}> = [
{
entry: mixlayerProvider,
id: "mixlayer",
chatUrl: "https://models.mixlayer.ai/v1/chat/completions",
modelsUrl: "https://models.mixlayer.ai/v1/models",
},
{
entry: spekaProvider,
id: "speka",
chatUrl: "https://speka.me/v1/chat/completions",
modelsUrl: "https://speka.me/v1/models",
},
{
entry: tokenreplyProvider,
id: "tokenreply",
chatUrl: "https://api.tokenreply.com/v1/chat/completions",
modelsUrl: "https://api.tokenreply.com/v1/models",
},
];
test("Wave 2-B providers expose OpenAI-compatible Bearer registries", () => {
for (const { entry, id, chatUrl, modelsUrl } of providers) {
assert.equal(entry.id, id);
assert.equal(entry.alias, id);
assert.equal(entry.format, "openai");
assert.equal(entry.executor, "default");
assert.equal(entry.authType, "apikey");
assert.equal(entry.authHeader, "bearer");
assert.equal(entry.baseUrl, chatUrl);
assert.equal(entry.modelsUrl, modelsUrl);
assert.equal(entry.passthroughModels, true);
assert.ok(Array.isArray(entry.models));
}
});
test("Mixlayer seeds only its documented free model", () => {
assert.deepEqual(
mixlayerProvider.models.map((model) => model.id),
["qwen/qwen3.5-4b-free"]
);
});
test("Speka and TokenReply rely on live model catalogs without invented models", () => {
assert.deepEqual(spekaProvider.models, []);
assert.deepEqual(tokenreplyProvider.models, []);
});

View File

@@ -1,58 +0,0 @@
import assert from "node:assert/strict";
import test from "node:test";
import { cloudcodeOneProvider } from "../../open-sse/config/providers/registry/cloudcode-one/index.ts";
import { dxntProvider } from "../../open-sse/config/providers/registry/dxnt/index.ts";
import { yoloAutoProvider } from "../../open-sse/config/providers/registry/yolo-auto/index.ts";
import type { RegistryEntry } from "../../open-sse/config/providers/shared.ts";
const providers: Array<{
entry: RegistryEntry;
id: string;
chatUrl: string;
modelsUrl: string;
modelIds: string[];
}> = [
{
entry: yoloAutoProvider,
id: "yolo-auto",
chatUrl: "https://yolo-auto.com/v1/chat/completions",
modelsUrl: "https://yolo-auto.com/v1/models",
modelIds: ["qwen3.6-35b-a3b"],
},
{
entry: dxntProvider,
id: "dxnt",
chatUrl: "https://www.dxnt.com/v1/chat/completions",
modelsUrl: "https://www.dxnt.com/v1/models",
modelIds: [],
},
{
entry: cloudcodeOneProvider,
id: "cloudcode-one",
chatUrl: "https://api.cloudcode.one/v1/chat/completions",
modelsUrl: "https://api.cloudcode.one/v1/models",
modelIds: ["glm-4.7-flash", "glm-4.6v-flash"],
},
];
for (const { entry, id, chatUrl, modelsUrl, modelIds } of providers) {
test(`${id} uses the standard OpenAI-compatible API-key registry shape`, () => {
assert.equal(entry.id, id);
assert.equal(entry.alias, id);
assert.equal(entry.format, "openai");
assert.equal(entry.executor, "default");
assert.equal(entry.authType, "apikey");
assert.equal(entry.authHeader, "bearer");
assert.equal(entry.baseUrl, chatUrl);
assert.equal(entry.modelsUrl, modelsUrl);
assert.equal(entry.passthroughModels, true);
});
test(`${id} seeds only the audited model identifiers`, () => {
assert.deepEqual(
(entry.models ?? []).map((model) => model.id),
modelIds
);
});
}

View File

@@ -1,60 +0,0 @@
import assert from "node:assert/strict";
import test from "node:test";
const { REGISTRY } = await import("../../open-sse/config/providerRegistry.ts");
const { DefaultExecutor, getExecutor } = await import("../../open-sse/executors/index.ts");
const { PROVIDER_ENDPOINTS } = await import("../../src/shared/constants/config.ts");
const { isValidModel } = await import("../../src/shared/constants/models.ts");
const { AGGREGATOR_PROVIDER_IDS } = await import("../../src/shared/constants/providers.ts");
const { APIKEY_PROVIDERS } = await import("../../src/shared/constants/providers/apikey/index.ts");
const providers = [
["literouter", "https://api.literouter.com/v1/chat/completions", []],
["mnn-ai", "https://api.mnnai.ru/v1/chat/completions", []],
["meganova-ai", "https://api.meganova.ai/v1/chat/completions", []],
["mixlayer", "https://models.mixlayer.ai/v1/chat/completions", ["qwen/qwen3.5-4b-free"]],
["speka", "https://speka.me/v1/chat/completions", []],
["tokenreply", "https://api.tokenreply.com/v1/chat/completions", []],
["yolo-auto", "https://yolo-auto.com/v1/chat/completions", ["qwen3.6-35b-a3b"]],
["dxnt", "https://www.dxnt.com/v1/chat/completions", []],
[
"cloudcode-one",
"https://api.cloudcode.one/v1/chat/completions",
["glm-4.7-flash", "glm-4.6v-flash"],
],
] as const;
for (const [id, endpoint, modelIds] of providers) {
test(`${id} is wired through registry, metadata, endpoint and default executor`, () => {
const registry = REGISTRY[id];
const metadata = APIKEY_PROVIDERS[id];
assert.ok(registry);
assert.ok(metadata);
assert.equal(registry.id, id);
assert.equal(registry.alias, id);
assert.equal(registry.baseUrl, endpoint);
assert.equal(PROVIDER_ENDPOINTS[id], endpoint);
assert.equal(metadata.id, id);
assert.equal(metadata.alias, id);
assert.equal(metadata.hasFree, true);
assert.equal(metadata.passthroughModels, true);
assert.ok(typeof metadata.freeNote === "string" && metadata.freeNote.length > 0);
assert.equal(AGGREGATOR_PROVIDER_IDS.has(id), true);
assert.ok(getExecutor(id) instanceof DefaultExecutor);
assert.equal(isValidModel(id, "future/live-catalog-model"), true);
assert.deepEqual(
registry.models.map((model) => model.id),
modelIds
);
});
}
test("risk-sensitive metadata preserves the audited quota qualifications", () => {
assert.match(APIKEY_PROVIDERS["mnn-ai"].apiHint ?? "", /jurisdiction.*privacy/i);
assert.match(APIKEY_PROVIDERS["meganova-ai"].freeNote ?? "", /per-model quotas/i);
assert.match(APIKEY_PROVIDERS["meganova-ai"].freeNote ?? "", /paid overage/i);
assert.match(APIKEY_PROVIDERS.tokenreply.freeNote ?? "", /no fixed global free quota/i);
assert.match(APIKEY_PROVIDERS["yolo-auto"].freeNote ?? "", /no numeric daily quota/i);
assert.match(APIKEY_PROVIDERS["cloudcode-one"].freeNote ?? "", /credit or a coupon/i);
});

View File

@@ -1,48 +0,0 @@
import assert from "node:assert/strict";
import test from "node:test";
import { chatanywhereProvider } from "../../open-sse/config/providers/registry/chatanywhere/index.ts";
import { ofoxaiProvider } from "../../open-sse/config/providers/registry/ofoxai/index.ts";
import { zerolimitaiProvider } from "../../open-sse/config/providers/registry/zerolimitai/index.ts";
import type { RegistryEntry } from "../../open-sse/config/providers/shared.ts";
const providers: Array<{
entry: RegistryEntry;
id: string;
chatUrl: string;
modelsUrl: string;
}> = [
{
entry: ofoxaiProvider,
id: "ofoxai",
chatUrl: "https://api.ofox.ai/v1/chat/completions",
modelsUrl: "https://api.ofox.ai/v1/models",
},
{
entry: zerolimitaiProvider,
id: "zerolimitai",
chatUrl: "https://www.zerolimitai.com/api/v1/chat/completions",
modelsUrl: "https://www.zerolimitai.com/api/v1/models",
},
{
entry: chatanywhereProvider,
id: "chatanywhere",
chatUrl: "https://api.chatanywhere.org/v1/chat/completions",
modelsUrl: "https://api.chatanywhere.org/v1/models",
},
];
test("Wave 3-A providers expose OpenAI-compatible Bearer registries", () => {
for (const { entry, id, chatUrl, modelsUrl } of providers) {
assert.equal(entry.id, id);
assert.equal(entry.alias, id);
assert.equal(entry.format, "openai");
assert.equal(entry.executor, "default");
assert.equal(entry.authType, "apikey");
assert.equal(entry.authHeader, "bearer");
assert.equal(entry.baseUrl, chatUrl);
assert.equal(entry.modelsUrl, modelsUrl);
assert.equal(entry.passthroughModels, true);
assert.deepEqual(entry.models, []);
}
});

View File

@@ -1,53 +0,0 @@
import assert from "node:assert/strict";
import test from "node:test";
import { aurikoProvider } from "../../open-sse/config/providers/registry/auriko/index.ts";
import { helyxaiProvider } from "../../open-sse/config/providers/registry/helyxai/index.ts";
import { poixeAiProvider } from "../../open-sse/config/providers/registry/poixe-ai/index.ts";
import type { RegistryEntry } from "../../open-sse/config/providers/shared.ts";
const providers: Array<{
entry: RegistryEntry;
id: string;
chatUrl: string;
modelsUrl: string;
}> = [
{
entry: helyxaiProvider,
id: "helyxai",
chatUrl: "https://helyxai.space/v1/chat/completions",
modelsUrl: "https://helyxai.space/v1/models",
},
{
entry: aurikoProvider,
id: "auriko",
chatUrl: "https://api.auriko.ai/v1/chat/completions",
modelsUrl: "https://api.auriko.ai/v1/models",
},
{
entry: poixeAiProvider,
id: "poixe-ai",
chatUrl: "https://api.poixe.com/v1/chat/completions",
modelsUrl: "https://api.poixe.com/v1/models",
},
];
test("Wave 3-B providers expose OpenAI-compatible Bearer registries", () => {
for (const { entry, id, chatUrl, modelsUrl } of providers) {
assert.equal(entry.id, id);
assert.equal(entry.alias, id);
assert.equal(entry.format, "openai");
assert.equal(entry.executor, "default");
assert.equal(entry.authType, "apikey");
assert.equal(entry.authHeader, "bearer");
assert.equal(entry.baseUrl, chatUrl);
assert.equal(entry.modelsUrl, modelsUrl);
assert.equal(entry.passthroughModels, true);
}
});
test("Wave 3-B providers rely on live catalogs without invented models", () => {
for (const { entry } of providers) {
assert.deepEqual(entry.models, []);
}
});

View File

@@ -1,41 +0,0 @@
import assert from "node:assert/strict";
import test from "node:test";
import { chatOripeProvider } from "../../open-sse/config/providers/registry/chat-oripe/index.ts";
import { nagaAiProvider } from "../../open-sse/config/providers/registry/naga-ai/index.ts";
import type { RegistryEntry } from "../../open-sse/config/providers/shared.ts";
const providers: Array<{
entry: RegistryEntry;
id: string;
chatUrl: string;
modelsUrl: string;
}> = [
{
entry: nagaAiProvider,
id: "naga-ai",
chatUrl: "https://api.naga.ac/v1/chat/completions",
modelsUrl: "https://api.naga.ac/v1/models",
},
{
entry: chatOripeProvider,
id: "chat-oripe",
chatUrl: "https://api.oriper.com/v1/chat/completions",
modelsUrl: "https://api.oriper.com/v1/models",
},
];
test("Wave 3-C providers expose OpenAI-compatible Bearer registries", () => {
for (const { entry, id, chatUrl, modelsUrl } of providers) {
assert.equal(entry.id, id);
assert.equal(entry.alias, id);
assert.equal(entry.format, "openai");
assert.equal(entry.executor, "default");
assert.equal(entry.authType, "apikey");
assert.equal(entry.authHeader, "bearer");
assert.equal(entry.baseUrl, chatUrl);
assert.equal(entry.modelsUrl, modelsUrl);
assert.equal(entry.passthroughModels, true);
assert.deepEqual(entry.models, []);
}
});

View File

@@ -1,53 +0,0 @@
import assert from "node:assert/strict";
import test from "node:test";
const { REGISTRY } = await import("../../open-sse/config/providerRegistry.ts");
const { DefaultExecutor, getExecutor } = await import("../../open-sse/executors/index.ts");
const { PROVIDER_ENDPOINTS } = await import("../../src/shared/constants/config.ts");
const { isValidModel } = await import("../../src/shared/constants/models.ts");
const { AGGREGATOR_PROVIDER_IDS } = await import("../../src/shared/constants/providers.ts");
const { APIKEY_PROVIDERS } = await import("../../src/shared/constants/providers/apikey/index.ts");
const providers = [
["ofoxai", "https://api.ofox.ai/v1/chat/completions"],
["zerolimitai", "https://www.zerolimitai.com/api/v1/chat/completions"],
["chatanywhere", "https://api.chatanywhere.org/v1/chat/completions"],
["helyxai", "https://helyxai.space/v1/chat/completions"],
["auriko", "https://api.auriko.ai/v1/chat/completions"],
["poixe-ai", "https://api.poixe.com/v1/chat/completions"],
["naga-ai", "https://api.naga.ac/v1/chat/completions"],
["chat-oripe", "https://api.oriper.com/v1/chat/completions"],
] as const;
for (const [id, endpoint] of providers) {
test(`${id} is wired through registry, metadata, endpoint and default executor`, () => {
const registry = REGISTRY[id];
const metadata = APIKEY_PROVIDERS[id];
assert.ok(registry);
assert.ok(metadata);
assert.equal(registry.id, id);
assert.equal(registry.alias, id);
assert.equal(registry.baseUrl, endpoint);
assert.equal(PROVIDER_ENDPOINTS[id], endpoint);
assert.equal(metadata.id, id);
assert.equal(metadata.alias, id);
assert.equal(metadata.hasFree, true);
assert.equal(metadata.passthroughModels, true);
assert.ok(typeof metadata.freeNote === "string" && metadata.freeNote.length > 0);
assert.equal(AGGREGATOR_PROVIDER_IDS.has(id), true);
assert.ok(getExecutor(id) instanceof DefaultExecutor);
assert.equal(isValidModel(id, "future/live-catalog-model"), true);
assert.deepEqual(registry.models, []);
});
}
test("Wave 3 metadata preserves the audited legal, quota and privacy warnings", () => {
assert.match(APIKEY_PROVIDERS.chatanywhere.freeNote ?? "", /commercial traffic/i);
assert.match(APIKEY_PROVIDERS.zerolimitai.freeNote ?? "", /3 and 7 days/i);
assert.match(APIKEY_PROVIDERS.helyxai.freeNote ?? "", /100,000 tokens\/day/i);
assert.match(APIKEY_PROVIDERS.auriko.freeNote ?? "", /not a free-token pool/i);
assert.match(APIKEY_PROVIDERS["poixe-ai"].freeNote ?? "", /2 RPM\/5 RPD/i);
assert.match(APIKEY_PROVIDERS["naga-ai"].freeNote ?? "", /training/i);
assert.match(APIKEY_PROVIDERS["chat-oripe"].freeNote ?? "", /unconfirmed/i);
});

View File

@@ -1,27 +0,0 @@
import assert from "node:assert/strict";
import test from "node:test";
import { freeinferenceProvider } from "../../open-sse/config/providers/registry/freeinference/index.ts";
import {
DefaultExecutor,
getExecutor,
hasSpecializedExecutor,
} from "../../open-sse/executors/index.ts";
test("FreeInference exposes an OpenAI-compatible Bearer registry", () => {
assert.equal(freeinferenceProvider.id, "freeinference");
assert.equal(freeinferenceProvider.alias, "freeinference");
assert.equal(freeinferenceProvider.format, "openai");
assert.equal(freeinferenceProvider.executor, "default");
assert.equal(freeinferenceProvider.authType, "apikey");
assert.equal(freeinferenceProvider.authHeader, "bearer");
assert.equal(freeinferenceProvider.baseUrl, "https://freeinference.org/v1/chat/completions");
assert.equal(freeinferenceProvider.modelsUrl, "https://freeinference.org/v1/models");
assert.deepEqual(freeinferenceProvider.models, []);
assert.equal(freeinferenceProvider.passthroughModels, true);
});
test("FreeInference uses DefaultExecutor without specialized behavior", () => {
assert.equal(hasSpecializedExecutor("freeinference"), false);
assert.ok(getExecutor("freeinference") instanceof DefaultExecutor);
});

View File

@@ -1,27 +0,0 @@
import assert from "node:assert/strict";
import test from "node:test";
import { freeAiProvider } from "../../open-sse/config/providers/registry/free-ai/index.ts";
import {
DefaultExecutor,
getExecutor,
hasSpecializedExecutor,
} from "../../open-sse/executors/index.ts";
test("Free.ai exposes its exact OpenAI-compatible endpoint and live catalog", () => {
assert.equal(freeAiProvider.id, "free-ai");
assert.equal(freeAiProvider.alias, "free-ai");
assert.equal(freeAiProvider.format, "openai");
assert.equal(freeAiProvider.executor, "default");
assert.equal(freeAiProvider.authType, "apikey");
assert.equal(freeAiProvider.authHeader, "bearer");
assert.equal(freeAiProvider.baseUrl, "https://api.free.ai/v1/chat/");
assert.equal(freeAiProvider.modelsUrl, "https://api.free.ai/v1/models");
assert.deepEqual(freeAiProvider.models, []);
assert.equal(freeAiProvider.passthroughModels, true);
});
test("Free.ai uses DefaultExecutor without a specialized executor", () => {
assert.ok(getExecutor("free-ai") instanceof DefaultExecutor);
assert.equal(hasSpecializedExecutor("free-ai"), false);
});

View File

@@ -1,64 +0,0 @@
import assert from "node:assert/strict";
import test from "node:test";
import { deriveConfigFromRegistryModelsUrl } from "../../src/app/api/providers/[id]/models/discoveryConfig.ts";
const { REGISTRY } = await import("../../open-sse/config/providerRegistry.ts");
const { DefaultExecutor, getExecutor, hasSpecializedExecutor } =
await import("../../open-sse/executors/index.ts");
const { PROVIDER_ENDPOINTS } = await import("../../src/shared/constants/config.ts");
const { isValidModel } = await import("../../src/shared/constants/models.ts");
const { AGGREGATOR_PROVIDER_IDS } = await import("../../src/shared/constants/providers.ts");
const { APIKEY_PROVIDERS } = await import("../../src/shared/constants/providers/apikey/index.ts");
const providers = [
["freeinference", "https://freeinference.org/v1/chat/completions"],
["free-ai", "https://api.free.ai/v1/chat/"],
] as const;
for (const [id, endpoint] of providers) {
test(`${id} is fully wired without a specialized executor`, () => {
const registry = REGISTRY[id];
const metadata = APIKEY_PROVIDERS[id];
assert.ok(registry);
assert.ok(metadata);
assert.equal(registry.id, id);
assert.equal(registry.alias, id);
assert.equal(registry.baseUrl, endpoint);
assert.equal(PROVIDER_ENDPOINTS[id], endpoint);
assert.equal(metadata.id, id);
assert.equal(metadata.alias, id);
assert.equal(metadata.hasFree, true);
assert.equal(metadata.passthroughModels, true);
assert.equal(AGGREGATOR_PROVIDER_IDS.has(id), true);
assert.equal(hasSpecializedExecutor(id), false);
const executor = getExecutor(id);
assert.ok(executor instanceof DefaultExecutor);
assert.equal(executor.buildUrl("live-model", false), endpoint);
assert.equal(isValidModel(id, "future/live-catalog-model"), true);
assert.deepEqual(registry.models, []);
});
}
test("Wave 4 model discovery accepts both public catalog response envelopes", () => {
const freeInferenceDiscovery = deriveConfigFromRegistryModelsUrl("freeinference");
const freeAiDiscovery = deriveConfigFromRegistryModelsUrl("free-ai");
assert.ok(freeInferenceDiscovery);
assert.ok(freeAiDiscovery);
assert.deepEqual(freeInferenceDiscovery.parseResponse({ data: [{ id: "glm-5.1" }] }), [
{ id: "glm-5.1" },
]);
assert.deepEqual(freeAiDiscovery.parseResponse({ models: [{ id: "qwen7b" }] }), [
{ id: "qwen7b" },
]);
});
test("Wave 4 metadata preserves approval, logging and overage warnings", () => {
assert.match(APIKEY_PROVIDERS.freeinference.freeNote ?? "", /manual approval/i);
assert.match(APIKEY_PROVIDERS.freeinference.apiHint ?? "", /logging/i);
assert.match(APIKEY_PROVIDERS["free-ai"].freeNote ?? "", /30,000 tokens\/day/i);
assert.match(APIKEY_PROVIDERS["free-ai"].freeNote ?? "", /premium external models are paid/i);
assert.match(APIKEY_PROVIDERS["free-ai"].apiHint ?? "", /\/v1\/chat\//i);
});

View File

@@ -1,15 +0,0 @@
import assert from "node:assert/strict";
import test from "node:test";
const { isValidModel } = await import("../../src/shared/constants/models.ts");
test("passthrough providers accept live model ids through both provider id and alias", () => {
for (const [id, alias] of [
["zylo-api", "zylo"],
["llm-kiwi", "llmkiwi"],
["freetheai", "fta"],
] as const) {
assert.equal(isValidModel(id, "future/live-catalog-model"), true);
assert.equal(isValidModel(alias, "future/live-catalog-model"), true);
}
});

View File

@@ -1,57 +0,0 @@
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { join } from "node:path";
import test from "node:test";
const REPO_ROOT = join(import.meta.dirname, "..", "..");
/**
* Regression guards for the CodeQL alerts triaged on 2026-08-12.
*
* Both are source-level invariants rather than behavioral round-trips: the functions they
* protect are module-private (`decodeXmlText`) or only reachable through a live upstream
* handshake (`tinycms` nonce), so the guard asserts the property on the source itself.
*/
test("decodeXmlText decodes &amp; last so encoded entities do not double-unescape", () => {
const source = readFileSync(
join(REPO_ROOT, "open-sse/vendor/codex-chatgpt-web/adapters/chatgpt-web/environment.ts"),
"utf8"
);
const body = /function decodeXmlText\(value: string\): string \{([\s\S]*?)\n\}/.exec(source)?.[1];
assert.ok(body, "decodeXmlText not found — update this guard if the helper was renamed");
const order = [...body.matchAll(/replaceAll\("(&[^"]+;)"/g)].map((match) => match[1]);
assert.ok(order.length >= 2, `expected several entity replacements, got ${order.length}`);
assert.equal(
order.at(-1),
"&amp;",
`"&amp;" must be the LAST entity decoded, otherwise "&amp;quot;" decodes to '"' instead ` +
`of the literal "&quot;". Current order: ${order.join(" -> ")}`
);
// Mirror the implementation to document the property the ordering buys us.
const decode = (value: string) =>
order.reduce((acc, entity) => {
const plain = { "&lt;": "<", "&gt;": ">", "&quot;": '"', "&#39;": "'", "&amp;": "&" }[entity];
return plain === undefined ? acc : acc.replaceAll(entity, plain);
}, value);
assert.equal(decode("&amp;quot;"), "&quot;");
assert.equal(decode("&amp;#39;"), "&#39;");
assert.equal(decode("&amp;lt;"), "&lt;");
});
test("tinycms signs its anti-replay nonce with a CSPRNG, never Math.random", () => {
const source = readFileSync(join(REPO_ROOT, "open-sse/executors/tinycms.ts"), "utf8");
assert.match(
source,
/const nonceJs = randomUUID\(\)/,
"the tinycms nonce must come from node:crypto randomUUID"
);
assert.doesNotMatch(
source,
/Math\.random\(\)/,
"Math.random() is not a CSPRNG — the nonce is signed into the anti-replay payload"
);
});