From 4904998ca3eae2e60690a9e417c3bd9e0be3046d Mon Sep 17 00:00:00 2001 From: diegosouzapw Date: Sun, 2 Aug 2026 01:29:38 -0300 Subject: [PATCH] feat(providers): add Mixlayer Speka and TokenReply registries --- .../providers/registry/mixlayer/index.ts | 11 ++++ .../config/providers/registry/speka/index.ts | 11 ++++ .../providers/registry/tokenreply/index.ts | 11 ++++ .../unit/free-tier-providers-wave2-b.test.ts | 60 +++++++++++++++++++ 4 files changed, 93 insertions(+) create mode 100644 open-sse/config/providers/registry/mixlayer/index.ts create mode 100644 open-sse/config/providers/registry/speka/index.ts create mode 100644 open-sse/config/providers/registry/tokenreply/index.ts create mode 100644 tests/unit/free-tier-providers-wave2-b.test.ts diff --git a/open-sse/config/providers/registry/mixlayer/index.ts b/open-sse/config/providers/registry/mixlayer/index.ts new file mode 100644 index 0000000000..63f4ab7715 --- /dev/null +++ b/open-sse/config/providers/registry/mixlayer/index.ts @@ -0,0 +1,11 @@ +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, +}); diff --git a/open-sse/config/providers/registry/speka/index.ts b/open-sse/config/providers/registry/speka/index.ts new file mode 100644 index 0000000000..04f1f17c7e --- /dev/null +++ b/open-sse/config/providers/registry/speka/index.ts @@ -0,0 +1,11 @@ +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, +}); diff --git a/open-sse/config/providers/registry/tokenreply/index.ts b/open-sse/config/providers/registry/tokenreply/index.ts new file mode 100644 index 0000000000..835225c471 --- /dev/null +++ b/open-sse/config/providers/registry/tokenreply/index.ts @@ -0,0 +1,11 @@ +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, +}); diff --git a/tests/unit/free-tier-providers-wave2-b.test.ts b/tests/unit/free-tier-providers-wave2-b.test.ts new file mode 100644 index 0000000000..3fec49f943 --- /dev/null +++ b/tests/unit/free-tier-providers-wave2-b.test.ts @@ -0,0 +1,60 @@ +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, []); +});