diff --git a/docs/reference/PROVIDER_REFERENCE.md b/docs/reference/PROVIDER_REFERENCE.md index 13869aa651..b3ea495df4 100644 --- a/docs/reference/PROVIDER_REFERENCE.md +++ b/docs/reference/PROVIDER_REFERENCE.md @@ -323,7 +323,8 @@ Use the dashboard at `/dashboard/providers` to enable, configure, and test each | `tinyfish` | `tf` | TinyFish Fetch | API key | [link](https://docs.tinyfish.ai/fetch-api) | X-API-Key from agent.tinyfish.ai/api-keys | | `together` | `together` | Together AI | API key, video | [link](https://www.together.ai) | — | | `tokenreply` | `tokenreply` | TokenReply | API key, aggregator | [link](https://www.tokenreply.com) | Free-tagged models have model- and campaign-specific daily limits; no fixed global free quota is published. | -| `tokenrouter` | `trk` | TokenRouter | API key | [link](https://tokenrouter.com) | Use your TokenRouter API key in Authorization: Bearer . Fully OpenAI-compatible. API base URL: https://api.tokenrouter.com/v1. | +| `tokenrouter` | `trk` | TokenRouter | API key | [link](https://tokenrouter.com) | Use your TokenRouter API key in Authorization: Bearer *** Fully OpenAI-compatible. API base URL: https://api.tokenrouter.com/v1. | +| `token-kiosk` | `tk` | Token Kiosk | API key | [link](https://agent-router.gaib.ai) | Use your Token Kiosk API key in Authorization: Bearer *** Fully OpenAI-compatible. API base URL: https://agent-router.gaib.ai/v1. | | `topaz` | `topaz` | Topaz | API key, image | [link](https://topazlabs.com) | — | | `typhoon` | `typhoon` | Typhoon | API key | [link](https://docs.opentyphoon.ai) | Free API key with a 5 req/s and 200 req/m rate limit. | | `udio` | `udio` | Udio | API key | [link](https://udio.com) | Paste session cookie from udio.com (Supabase auth) | diff --git a/open-sse/config/providers/index.ts b/open-sse/config/providers/index.ts index 01395e7dd8..75c69f1a39 100644 --- a/open-sse/config/providers/index.ts +++ b/open-sse/config/providers/index.ts @@ -213,6 +213,7 @@ import { kiroProvider } from "./registry/kiro/index.ts"; import { openadapterProvider } from "./registry/openadapter/index.ts"; import { ditProvider } from "./registry/dit/index.ts"; import { tokenrouterProvider } from "./registry/tokenrouter/index.ts"; +import { token_kioskProvider } from "./registry/token-kiosk/index.ts"; import { grok_cliProvider } from "./registry/grok-cli/index.ts"; import { codebuddy_cnProvider } from "./registry/codebuddy-cn/index.ts"; import { pioneerProvider } from "./registry/pioneer/index.ts"; @@ -475,6 +476,7 @@ export const REGISTRY: Record = { openadapter: openadapterProvider, dit: ditProvider, tokenrouter: tokenrouterProvider, + "token-kiosk": token_kioskProvider, "grok-cli": grok_cliProvider, "codebuddy-cn": codebuddy_cnProvider, pioneer: pioneerProvider, diff --git a/open-sse/config/providers/registry/token-kiosk/index.ts b/open-sse/config/providers/registry/token-kiosk/index.ts new file mode 100644 index 0000000000..319747828c --- /dev/null +++ b/open-sse/config/providers/registry/token-kiosk/index.ts @@ -0,0 +1,20 @@ +import type { RegistryEntry } from "../../shared.ts"; + +export const token_kioskProvider: RegistryEntry = { + id: "token-kiosk", + alias: "tk", + format: "openai", + executor: "default", + baseUrl: "https://agent-router.gaib.ai/v1/chat/completions", + modelsUrl: "https://agent-router.gaib.ai/v1/models", + authType: "apikey", + authHeader: "bearer", + defaultContextLength: 128000, + models: [ + { id: "claude-3-5-sonnet", name: "Claude 3.5 Sonnet (Token Kiosk)", contextLength: 200000, toolCalling: true, supportsVision: true }, + { id: "deepseek-v3", name: "DeepSeek V3 (Token Kiosk)", contextLength: 64000, toolCalling: true }, + { id: "deepseek-r1", name: "DeepSeek R1 (Token Kiosk)", contextLength: 64000, toolCalling: true, supportsReasoning: true }, + { id: "kimi-k1.5", name: "Kimi K1.5 (Token Kiosk)", contextLength: 128000, toolCalling: true }, + { id: "minimax-m6", name: "MiniMax M6 (Token Kiosk)", contextLength: 128000, toolCalling: true }, + ], +}; diff --git a/src/app/api/providers/[id]/models/discovery/providerSets.ts b/src/app/api/providers/[id]/models/discovery/providerSets.ts index d443cfabc7..8238681479 100644 --- a/src/app/api/providers/[id]/models/discovery/providerSets.ts +++ b/src/app/api/providers/[id]/models/discovery/providerSets.ts @@ -23,6 +23,7 @@ export const NAMED_OPENAI_STYLE_PROVIDERS = new Set([ "openadapter", "dit", "tokenrouter", + "token-kiosk", // provider-model-sweep (2026-06-19): same class as #3976/#4202/#4249 — keyed // openai-style providers with a real live `/models` catalog, served // their small hardcoded seed because unclassified. Seed stays as offline fallback. diff --git a/src/shared/constants/config.ts b/src/shared/constants/config.ts index eacf73db7e..9b1bbcb132 100644 --- a/src/shared/constants/config.ts +++ b/src/shared/constants/config.ts @@ -53,6 +53,7 @@ export const PROVIDER_ENDPOINTS = { openadapter: "https://api.openadapter.in/v1/chat/completions", dit: "https://api.dit.ai/v1/chat/completions", tokenrouter: "https://api.tokenrouter.com/v1/chat/completions", + "token-kiosk": "https://agent-router.gaib.ai/v1/chat/completions", sumopod: "https://ai.sumopod.com/v1/chat/completions", x5lab: "https://api.x5lab.dev/v1/chat/completions", kenari: "https://kenari.id/v1/chat/completions", diff --git a/src/shared/constants/providers/apikey/gateways.ts b/src/shared/constants/providers/apikey/gateways.ts index cbfd651529..2b9c077e15 100644 --- a/src/shared/constants/providers/apikey/gateways.ts +++ b/src/shared/constants/providers/apikey/gateways.ts @@ -1055,6 +1055,19 @@ export const APIKEY_PROVIDERS_GATEWAYS = { apiHint: "TokenRouter exposes an OpenAI-compatible chat completions endpoint at https://api.tokenrouter.com/v1/chat/completions, plus a working /v1/models catalog. OmniRoute uses the OpenAI protocol.", }, + "token-kiosk": { + id: "token-kiosk", + alias: "tk", + name: "Token Kiosk", + icon: "hub", + color: "#6366F1", + textIcon: "TKI", + website: "https://agent-router.gaib.ai", + authHint: + "Use your Token Kiosk API key in Authorization: Bearer . Fully OpenAI-compatible gateway. API base URL: https://agent-router.gaib.ai/v1.", + apiHint: + "Token Kiosk is a multi-provider agent LLM routing infrastructure exposing an OpenAI-compatible endpoint at https://agent-router.gaib.ai/v1/chat/completions with auto-fallback and latency routing.", + }, sumopod: { id: "sumopod", alias: "sumopod", diff --git a/tests/unit/token-kiosk-provider.test.ts b/tests/unit/token-kiosk-provider.test.ts new file mode 100644 index 0000000000..a887271160 --- /dev/null +++ b/tests/unit/token-kiosk-provider.test.ts @@ -0,0 +1,37 @@ +import test from "node:test"; +import assert from "node:assert/strict"; + +const { APIKEY_PROVIDERS } = await import("../../src/shared/constants/providers.ts"); +const { PROVIDER_ENDPOINTS } = await import("../../src/shared/constants/config.ts"); +const { REGISTRY: providerRegistry } = await import("../../open-sse/config/providerRegistry.ts"); +const { isNamedOpenAIStyleProvider } = await import("../../src/app/api/providers/[id]/models/discovery/providerSets.ts"); + +test("Token Kiosk is registered as an API-key gateway provider", () => { + const entry = APIKEY_PROVIDERS["token-kiosk"]; + assert.ok(entry, "APIKEY_PROVIDERS['token-kiosk'] must be defined"); + assert.equal(entry.id, "token-kiosk"); + assert.equal(entry.alias, "tk"); + assert.equal(entry.name, "Token Kiosk"); + assert.equal(entry.website, "https://agent-router.gaib.ai"); +}); + +test("Token Kiosk exposes the OpenAI-compatible chat completions URL", () => { + assert.equal(PROVIDER_ENDPOINTS["token-kiosk"], "https://agent-router.gaib.ai/v1/chat/completions"); +}); + +test("Token Kiosk registry entry uses OpenAI format with bearer apikey auth", () => { + const entry = providerRegistry["token-kiosk"]; + assert.ok(entry, "providerRegistry['token-kiosk'] must be defined"); + assert.equal(entry.id, "token-kiosk"); + assert.equal(entry.alias, "tk"); + assert.equal(entry.format, "openai"); + assert.equal(entry.executor, "default"); + assert.equal(entry.authType, "apikey"); + assert.equal(entry.authHeader, "bearer"); + assert.equal(entry.baseUrl, "https://agent-router.gaib.ai/v1/chat/completions"); + assert.equal(entry.modelsUrl, "https://agent-router.gaib.ai/v1/models"); +}); + +test("Token Kiosk is registered as a named OpenAI-style provider for live model discovery", () => { + assert.ok(isNamedOpenAIStyleProvider("token-kiosk")); +});