mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-27 01:22:10 +03:00
Compare commits
3 Commits
fix/11526-
...
feat/opper
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bfeb4cfe15 | ||
|
|
afae88f577 | ||
|
|
f5f6158193 |
1
changelog.d/features/opper-provider.md
Normal file
1
changelog.d/features/opper-provider.md
Normal file
@@ -0,0 +1 @@
|
||||
- **feat(providers):** Add **Opper** as an API-key gateway provider — EU-hosted AI gateway with 700+ models from 30+ providers behind one OpenAI-compatible API and one key (`OPPER_API_KEY`); model ids use `provider/model` format (e.g. `anthropic/claude-sonnet-4-6`, `openai/gpt-5`); live model catalog at `https://api.opper.ai/v3/compat/models`; entry mirrors `requesty` (same shape, `passthroughModels: true`, no static seed)
|
||||
@@ -1,16 +1,16 @@
|
||||
---
|
||||
title: "Provider Reference"
|
||||
version: 3.8.51
|
||||
lastUpdated: 2026-08-25
|
||||
lastUpdated: 2026-08-26
|
||||
---
|
||||
|
||||
# Provider Reference
|
||||
|
||||
> **Auto-generated** from `src/shared/constants/providers.ts` — do not edit by hand.
|
||||
> Regenerate with: `npm run gen:provider-reference`
|
||||
> **Last generated:** 2026-08-25
|
||||
> **Last generated:** 2026-08-26
|
||||
|
||||
Total providers: **353**. See category breakdown below.
|
||||
Total providers: **354**. See category breakdown below.
|
||||
|
||||
## Categories
|
||||
|
||||
@@ -98,7 +98,7 @@ Use the dashboard at `/dashboard/providers` to enable, configure, and test each
|
||||
| `deepseek-web` | `ds-web` | DeepSeek Web | Web cookie | [link](https://chat.deepseek.com) | Paste your userToken from chat.deepseek.com — DevTools → Application → Local Storage → userToken | emulated |
|
||||
| `doubao-web` | `db` | Dola Web (ByteDance) | Web cookie | [link](https://www.dola.com) | Paste the full Cookie header from www.dola.com. It should include sessionid, ttwid, and s_v_web_id. If s_v_web_id is unavailable, fp=verify_... from a chat/completion request URL can be used as a fallback. | — |
|
||||
| `gemini-business` | `gembiz` | Gemini Business (Enterprise) | Web cookie | [link](https://business.gemini.google) | From your enterprise account: open business.gemini.google/home/cid/{your-cid}, then copy __Secure-1PSID and __Secure-1PSIDTS cookies from DevTools → Application → Cookies. Paste as a cookie header below. | — |
|
||||
| `gemini-web` | `gweb` | Gemini Web (Free) | Web cookie | [link](https://gemini.google.com) | Paste your __Secure-1PSID cookie value from gemini.google.com. Optionally add __Secure-1PSIDTS separated by semicolon. | emulated |
|
||||
| `gemini-web` | `gweb` | Gemini Web (Free) | Web cookie | [link](https://gemini.google.com) | Paste the full cookie header, the __Secure-1PSID value, or the JSON export containing cookies from gemini.google.com. Include __Secure-1PSIDTS and __Secure-1PSIDCC when available. | emulated |
|
||||
| `grok-web` | `gw` | Grok Web (Subscription) | Web cookie | [link](https://grok.com) | Paste the full grok.com cookie line from DevTools → Application → Cookies. Include both `sso` and `sso-rw` (e.g. `sso=...; sso-rw=...`) — Grok's anti-bot rejects `sso` on its own. | — |
|
||||
| `hailuo-web` | `hailuo-web` | Hailuo Web (MiniMax) | Web cookie | [link](https://chat.minimax.io) | Open hailuo.ai, log in, then open DevTools → Application → Local Storage → copy the "_token" value. device_id/uuid fingerprint fields are derived automatically; if requests fail, re-capture _token (sessions can expire). | — |
|
||||
| `huggingchat` | `huggingchat` | HuggingChat (Free) | Web cookie | [link](https://huggingface.co/chat) | Paste the full Cookie header from huggingface.co/chat (DevTools → Network → /chat/conversation → Request Headers → Cookie). It should include hf-chat and may also include token / aws-waf-token. | — |
|
||||
@@ -122,7 +122,7 @@ Use the dashboard at `/dashboard/providers` to enable, configure, and test each
|
||||
| `zai-web` | `zw` | Z.ai Web | Web cookie | [link](https://chat.z.ai) | Copy the "token" value from chat.z.ai → DevTools → Application → Local Storage. Do not copy cookies; OmniRoute handles the per-request CAPTCHA through its browser transport. | — |
|
||||
| `zenmux-free` | `zmf` | ZenMux Free (Web) | Web cookie | [link](https://zenmux.ai) | Login at zenmux.ai, then export all cookies using EditThisCookie or Cookie-Editor and paste the full Cookie header string here. Refresh every ~30 days. | — |
|
||||
|
||||
## API Key Providers (paid / paid-with-free-credits) (233)
|
||||
## API Key Providers (paid / paid-with-free-credits) (234)
|
||||
|
||||
| ID | Alias | Name | Tags | Website | Notes |
|
||||
|----|-------|------|------|---------|-------|
|
||||
@@ -284,6 +284,7 @@ Use the dashboard at `/dashboard/providers` to enable, configure, and test each
|
||||
| `openference-api` | `ofa` | Openference API | API key | [link](https://openference.com) | Free plan: 3-day trial with open-source models — no credit card required |
|
||||
| `openrouter` | `openrouter` | OpenRouter | API key, aggregator | [link](https://openrouter.ai) | Free models at $0/token with :free suffix - 20 RPM / 200 RPD |
|
||||
| `openvecta` | `openvecta` | OpenVecta | API key | [link](https://openvecta.com) | Free credits on signup for OpenAI-compatible inference across LLMs, embeddings, and reasoning models |
|
||||
| `opper` | `opper` | Opper | API key, aggregator | [link](https://opper.ai) | — |
|
||||
| `orcarouter` | `orcarouter` | OrcaRouter | API key | [link](https://www.orcarouter.ai) | — |
|
||||
| `ovhcloud` | `ovh` | OVHcloud AI | API key | [link](https://www.ovhcloud.com) | — |
|
||||
| `perplexity` | `pplx` | Perplexity | API key | [link](https://www.perplexity.ai) | — |
|
||||
|
||||
@@ -229,6 +229,7 @@ import { x5labProvider } from "./registry/x5lab/index.ts";
|
||||
import { kenariProvider } from "./registry/kenari/index.ts";
|
||||
import { navyProvider } from "./registry/navy/index.ts";
|
||||
import { naraProvider } from "./registry/nara/index.ts";
|
||||
import { opperProvider } from "./registry/opper/index.ts";
|
||||
import { requestyProvider } from "./registry/requesty/index.ts";
|
||||
import { sealionProvider } from "./registry/sealion/index.ts";
|
||||
import { routewayProvider } from "./registry/routeway/index.ts";
|
||||
@@ -500,6 +501,7 @@ export const REGISTRY: Record<string, RegistryEntry> = {
|
||||
kenari: kenariProvider,
|
||||
navy: navyProvider,
|
||||
nara: naraProvider,
|
||||
opper: opperProvider,
|
||||
requesty: requestyProvider,
|
||||
sealion: sealionProvider,
|
||||
routeway: routewayProvider,
|
||||
|
||||
11
open-sse/config/providers/registry/opper/index.ts
Normal file
11
open-sse/config/providers/registry/opper/index.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import type { RegistryEntry } from "../../shared.ts";
|
||||
import { buildOpenAiCompatibleRegistryEntry } from "../../shared.ts";
|
||||
|
||||
export const opperProvider: RegistryEntry = buildOpenAiCompatibleRegistryEntry({
|
||||
id: "opper",
|
||||
alias: "opper",
|
||||
baseUrl: "https://api.opper.ai/v3/compat/chat/completions",
|
||||
modelsUrl: "https://api.opper.ai/v3/compat/models",
|
||||
models: [],
|
||||
passthroughModels: true,
|
||||
});
|
||||
1
public/providers/opper.svg
Normal file
1
public/providers/opper.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 315 315"><title>Opper</title><circle cx="157.5" cy="157.5" r="157.5" fill="#1B2E40"/><g transform="translate(63 63) scale(0.6)" fill="#FFFFFF"><path fill-rule="evenodd" clip-rule="evenodd" d="M159.78 315C71.53 315 0 244.49 0 157.5C0 -18.9499 159.78 0.650075 159.78 0.650075C159.78 87.2201 88.36 157.4 0.2 157.5C149.8 157.64 159.78 315 159.78 315ZM160.52 217.98C160.52 217.98 156.94 161.65 105.04 157.52C120.6 157.34 160.52 151.54 160.52 96.5601C160.52 151.54 200.44 157.34 216 157.52C164.1 161.65 160.52 217.98 160.52 217.98Z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 592 B |
@@ -97,6 +97,7 @@ export const AGGREGATOR_PROVIDER_IDS = new Set([
|
||||
"kilo-gateway",
|
||||
"aimlapi",
|
||||
"novita",
|
||||
"opper",
|
||||
"piapi",
|
||||
"getgoapi",
|
||||
"laozhang",
|
||||
|
||||
@@ -99,6 +99,20 @@ export const APIKEY_PROVIDERS_GATEWAYS = {
|
||||
freeNote: "Free models at $0/token with :free suffix - 20 RPM / 200 RPD",
|
||||
serviceKinds: ["llm", "imageToText"],
|
||||
},
|
||||
opper: {
|
||||
id: "opper",
|
||||
alias: "opper",
|
||||
name: "Opper",
|
||||
icon: "router",
|
||||
color: "#6366F1",
|
||||
textIcon: "OP",
|
||||
passthroughModels: true,
|
||||
website: "https://opper.ai",
|
||||
apiHint:
|
||||
"Create an API key at https://platform.opper.ai, then paste it here as a Bearer token. " +
|
||||
"OpenAI-compatible endpoint at https://api.opper.ai/v3/compat, with a live /v3/compat/models catalog. " +
|
||||
"Model ids use provider/model format, e.g. anthropic/claude-sonnet-4-6 or openai/gpt-5.",
|
||||
},
|
||||
requesty: {
|
||||
id: "requesty",
|
||||
alias: "requesty",
|
||||
|
||||
@@ -4609,6 +4609,29 @@
|
||||
"stream": "https://api.openvecta.com/v1/chat/completions"
|
||||
}
|
||||
},
|
||||
"opper": {
|
||||
"format": "openai",
|
||||
"headers": {
|
||||
"apiKey": {
|
||||
"Accept": "text/event-stream",
|
||||
"Authorization": "Bearer <TOK>",
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
"nonStream": {
|
||||
"Authorization": "Bearer <TOK>",
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
"oauth": {
|
||||
"Accept": "text/event-stream",
|
||||
"Authorization": "Bearer <TOK>",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
},
|
||||
"url": {
|
||||
"nonStream": "https://api.opper.ai/v3/compat/chat/completions",
|
||||
"stream": "https://api.opper.ai/v3/compat/chat/completions"
|
||||
}
|
||||
},
|
||||
"orcarouter": {
|
||||
"format": "openai",
|
||||
"headers": {
|
||||
|
||||
44
tests/unit/opper-provider.test.ts
Normal file
44
tests/unit/opper-provider.test.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
const { APIKEY_PROVIDERS } = await import("../../src/shared/constants/providers.ts");
|
||||
const { REGISTRY: providerRegistry } = await import("../../open-sse/config/providerRegistry.ts");
|
||||
const { isValidModel } = await import("../../src/shared/constants/models.ts");
|
||||
|
||||
const OPPER_CHAT_URL = "https://api.opper.ai/v3/compat/chat/completions";
|
||||
const OPPER_MODELS_URL = "https://api.opper.ai/v3/compat/models";
|
||||
|
||||
test("opper is registered as an API-key gateway provider", () => {
|
||||
const entry = APIKEY_PROVIDERS.opper;
|
||||
assert.ok(entry, "APIKEY_PROVIDERS.opper must be defined");
|
||||
assert.equal(entry.id, "opper");
|
||||
assert.equal(entry.alias, "opper");
|
||||
assert.equal(entry.name, "Opper");
|
||||
assert.equal(entry.website, "https://opper.ai");
|
||||
assert.equal(entry.passthroughModels, true);
|
||||
});
|
||||
|
||||
test("opper registry entry uses OpenAI format with bearer API-key auth", () => {
|
||||
const entry = providerRegistry.opper;
|
||||
assert.ok(entry, "providerRegistry.opper must be defined");
|
||||
assert.equal(entry.id, "opper");
|
||||
assert.equal(entry.alias, "opper");
|
||||
assert.equal(entry.format, "openai");
|
||||
assert.equal(entry.executor, "default");
|
||||
assert.equal(entry.authType, "apikey");
|
||||
assert.equal(entry.authHeader, "bearer");
|
||||
assert.equal(entry.baseUrl, OPPER_CHAT_URL);
|
||||
assert.equal(entry.modelsUrl, OPPER_MODELS_URL);
|
||||
assert.equal(entry.passthroughModels, true);
|
||||
});
|
||||
|
||||
test("opper ships no static model seed — relies fully on passthrough + live catalog", () => {
|
||||
assert.deepEqual(providerRegistry.opper.models, []);
|
||||
});
|
||||
|
||||
test("opper accepts provider/model ids via passthrough (OpenAI, Anthropic, DeepSeek, Mistral behind one key)", () => {
|
||||
assert.equal(isValidModel("opper", "anthropic/claude-sonnet-4-6"), true);
|
||||
assert.equal(isValidModel("opper", "openai/gpt-5"), true);
|
||||
assert.equal(isValidModel("opper", "deepseek/deepseek-v4-pro"), true);
|
||||
assert.equal(isValidModel("opper", "mistral/mistral-large-latest"), true);
|
||||
});
|
||||
Reference in New Issue
Block a user