Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Repository map and Reference Documentation sections below.

## Project at a Glance

**OmniRoute** — unified AI proxy/router. One endpoint, 290 LLM providers, auto-fallback.
**OmniRoute** — unified AI proxy/router. One endpoint, 291 LLM providers, auto-fallback.

| Layer | Location | Purpose |
| ------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

# 🚀 OmniRoute — The Free AI Gateway

<img src="./docs/diagrams/readme-hero.svg" width="100%" alt="OmniRoute — Never stop coding. Every AI tool → 290 providers — 90+ free — through one endpoint. Claude Code, Codex, Cursor, Cline, Copilot & Antigravity into FREE Claude / GPT / Gemini with auto-fallback. RTK + Caveman stacked compression saves 15–95% tokens (~89% avg) — never hit limits. 290 AI providers · 90+ free tiers · ~1.53B free tokens/mo · 19 routing strategies · $0 to start."/>
<img src="./docs/diagrams/readme-hero.svg" width="100%" alt="OmniRoute — Never stop coding. Every AI tool → 291 providers — 90+ free — through one endpoint. Claude Code, Codex, Cursor, Cline, Copilot & Antigravity into FREE Claude / GPT / Gemini with auto-fallback. RTK + Caveman stacked compression saves 15–95% tokens (~89% avg) — never hit limits. 291 AI providers · 90+ free tiers · ~1.53B free tokens/mo · 19 routing strategies · $0 to start."/>

</div>

Expand Down Expand Up @@ -81,7 +81,7 @@
<tr>
<td align="right"><b>⚙️ Features</b></td>
<td align="center"><a href="#-combos--the-flagship">🎯 Combos</a></td>
<td align="center"><a href="#-290-ai-providers--90-free">🌐 Providers</a></td>
<td align="center"><a href="#-291-ai-providers--90-free">🌐 Providers</a></td>
<td align="center"><a href="#-full-cli--a2a--mcp">🔌 CLI &amp; MCP</a></td>
</tr>
<tr>
Expand Down Expand Up @@ -188,7 +188,7 @@ curl http://localhost:20128/v1/chat/completions \

</div>

<img src="./docs/diagrams/promise-pillars.svg" width="100%" alt="The Promise — One endpoint. 290 providers. Never stop building — OmniRoute picks the cheapest one that works. Six pillars: Never hit limits (auto-fallback across 290 providers in milliseconds, zero downtime) · Save up to 95% tokens (RTK + Caveman stacked compression cuts 15–95%, ~89% avg on tool-heavy sessions) · $0 to start (90+ free tiers, 40+ free forever — no card needed) · Every tool works (33 coding agents through one config) · One endpoint (OpenAI ↔ Claude ↔ Gemini ↔ Responses API at /v1) · Production-grade (circuit breakers, TLS stealth, MCP 104 tools, A2A, memory, guardrails, evals — 25,000+ tests)."/>
<img src="./docs/diagrams/promise-pillars.svg" width="100%" alt="The Promise — One endpoint. 291 providers. Never stop building — OmniRoute picks the cheapest one that works. Six pillars: Never hit limits (auto-fallback across 291 providers in milliseconds, zero downtime) · Save up to 95% tokens (RTK + Caveman stacked compression cuts 15–95%, ~89% avg on tool-heavy sessions) · $0 to start (90+ free tiers, 40+ free forever — no card needed) · Every tool works (33 coding agents through one config) · One endpoint (OpenAI ↔ Claude ↔ Gemini ↔ Responses API at /v1) · Production-grade (circuit breakers, TLS stealth, MCP 104 tools, A2A, memory, guardrails, evals — 25,000+ tests)."/>

<br/>
<br/>
Expand Down Expand Up @@ -439,7 +439,7 @@ All **19** strategies — mix & match per combo step:

</div>

<img src="./docs/diagrams/comparison-table.svg" width="100%" alt="What sets OmniRoute apart — comparison table vs 9router, OpenRouter, CLIProxyAPI and LiteLLM across 13 capabilities. OmniRoute: 290 providers, 90+ free providers built-in, 19 routing strategies, 12-engine token compression, built-in MCP server with 104 tools, A2A agent protocol, persistent memory, guardrails, cloud agents, TLS fingerprint stealth, Desktop/Termux/PWA, 43 i18n UI locales, 100% MIT self-hosted. OmniRoute is the only one with the full set; competitors show a mix of checks, partials and crosses. Verified from each project&apos;s docs."/>
<img src="./docs/diagrams/comparison-table.svg" width="100%" alt="What sets OmniRoute apart — comparison table vs 9router, OpenRouter, CLIProxyAPI and LiteLLM across 13 capabilities. OmniRoute: 291 providers, 90+ free providers built-in, 19 routing strategies, 12-engine token compression, built-in MCP server with 104 tools, A2A agent protocol, persistent memory, guardrails, cloud agents, TLS fingerprint stealth, Desktop/Termux/PWA, 43 i18n UI locales, 100% MIT self-hosted. OmniRoute is the only one with the full set; competitors show a mix of checks, partials and crosses. Verified from each project&apos;s docs."/>

<sub>📊 Full methodology &amp; per-feature detail vs 9router, OpenRouter, CLIProxyAPI &amp; LiteLLM → [`docs/comparison/OMNIROUTE_VS_ALTERNATIVES.md`](docs/comparison/OMNIROUTE_VS_ALTERNATIVES.md)</sub>

Expand Down Expand Up @@ -574,11 +574,11 @@ Pix copia-e-cola:

<div align="center">

## 🌐 290 AI Providers — 90+ Free
## 🌐 291 AI Providers — 90+ Free

</div>

> The most complete catalog of any open-source router: **290 providers**, **90+ with a free tier**, **40+ free forever**.
> The most complete catalog of any open-source router: **291 providers**, **90+ with a free tier**, **40+ free forever**.

<div align="center">

Expand Down
1 change: 1 addition & 0 deletions changelog.d/fixes/9541-visionbridge-di.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- fix(guardrails): thread the injected credential checker into the vision-model router and keep raw images for vision-capable upstreams on total describe failure (#9541)
19 changes: 16 additions & 3 deletions src/lib/guardrails/visionBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,13 @@ export class VisionBridgeGuardrail extends BaseGuardrail {
typeof settings.visionBridgeModel === "string" && settings.visionBridgeModel.trim()
? settings.visionBridgeModel.trim()
: undefined;
const bestModel = await getBestVisionModel({ fixedModel: configuredModel });
// #9541: thread the injected credential checker into the router — without it,
// #8430's fixedModel validation runs the REAL DB check even under test DI,
// so an empty credential store (CI) silently disables the reroute path.
const bestModel = await getBestVisionModel(
{ fixedModel: configuredModel },
{ hasUsableCredentials: checkCreds }
);
if (bestModel && bestModel !== model) {
const bestUsable = await checkCreds(bestModel);
// Only block the reroute when we KNOW the target is unusable (false).
Expand Down Expand Up @@ -319,8 +325,15 @@ export class VisionBridgeGuardrail extends BaseGuardrail {
// be vision-capable (reroute path / unknown capability).
const allNull = descriptions.every((d) => d === null);
if (allNull && comboVisionBridgeDecision === "process") {
for (let i = 0; i < descriptions.length; i++) {
descriptions[i] = `[Image ${i + 1}]: (unavailable — no vision-capable provider connected)`;
// #9541: the #8430 stub is only safe when the upstream is CONFIRMED non-vision
// (it can only handle text anyway). A vision-capable upstream forced through the
// combo describe path keeps its raw images on total describe failure — that is
// the #4012 contract this stub must not override.
const upstreamVision = getResolvedModelCapabilities(model)?.supportsVision === true;
if (!upstreamVision) {
for (let i = 0; i < descriptions.length; i++) {
descriptions[i] = `[Image ${i + 1}]: (unavailable — no vision-capable provider connected)`;
}
}
}

Expand Down
8 changes: 7 additions & 1 deletion tests/unit/issue-7859-gemini-web-redirect-valid.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,15 @@ test("gemini-web validator: 302 redirect to a PUBLIC host → valid (regression
globalThis.fetch = async (url) => {
const target = String(url);
if (target.includes("gemini.google.com/app")) {
// #9407 tightened the contract AFTER this regression test was written:
// accounts.google.com/ServiceLogin now means EXPIRED session (valid:false,
// covered by issue-9407-gemini-web-validation-false-positive.test.ts).
// The #7859 contract this test guards — a PUBLIC redirect is not SSRF and
// a live Gemini session may bounce through Google — uses a non-ServiceLogin
// public target here.
return new Response(null, {
status: 302,
headers: { location: "https://accounts.google.com/ServiceLogin" },
headers: { location: "https://www.google.com/sorry/index" },
});
}
throw new Error(`unexpected fetch: ${target}`);
Expand Down
Loading