diff --git a/AGENTS.md b/AGENTS.md index b1bcfebafd..4472c2fa5e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -46,7 +46,7 @@ Repository map and Reference Documentation sections below. ## Project at a Glance -**OmniRoute** โ€” unified AI proxy/router. One endpoint, 341 LLM providers, auto-fallback. +**OmniRoute** โ€” unified AI proxy/router. One endpoint, 342 LLM providers, auto-fallback. | Layer | Location | Purpose | | ------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/README.md b/README.md index d04278cab3..fd13437fc9 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ # ๐Ÿš€ OmniRoute โ€” The Free AI Gateway -OmniRoute โ€” Never stop coding. Every AI tool โ†’ 341 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. 341 AI providers ยท 90+ free tiers ยท ~1.51B free tokens/mo ยท 19 routing strategies ยท $0 to start. +OmniRoute โ€” Never stop coding. Every AI tool โ†’ 342 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. 342 AI providers ยท 90+ free tiers ยท ~1.51B free tokens/mo ยท 19 routing strategies ยท $0 to start. @@ -63,7 +63,7 @@ | | v3.8.49 | **v3.8.50** | `v3.8.51+` | | ------------------------- | :-----: | :---------: | :---------: | -| ๐ŸŒ Providers | 290 | **341** | more queued | +| ๐ŸŒ Providers | 290 | **342** | more queued | | ๐Ÿง  Documented models | 1185 | **1202** | โ€” | | ๐Ÿ–ผ๏ธ Modality Bridge | โ€” | ๐Ÿ†• vision | video | | ๐Ÿ“ก Radar free catalog | โ€” | ๐Ÿ†• opt-in | โ€” | @@ -101,7 +101,7 @@ โš™๏ธ Features ๐ŸŽฏ Combos - ๐ŸŒ Providers + ๐ŸŒ Providers ๐Ÿ”Œ CLI & MCP @@ -210,7 +210,7 @@ curl http://localhost:20128/v1/chat/completions \ -The Promise โ€” One endpoint. 341 providers. Never stop building โ€” OmniRoute picks the cheapest one that works. Six pillars: Never hit limits (auto-fallback across 341 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, 56 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 109 tools, A2A, memory, guardrails, evals โ€” 25,000+ tests). +The Promise โ€” One endpoint. 342 providers. Never stop building โ€” OmniRoute picks the cheapest one that works. Six pillars: Never hit limits (auto-fallback across 342 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, 56 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 109 tools, A2A, memory, guardrails, evals โ€” 25,000+ tests).

@@ -461,7 +461,7 @@ All **19** strategies โ€” mix & match per combo step: -What sets OmniRoute apart โ€” comparison table vs 9router, OpenRouter, CLIProxyAPI and LiteLLM across 13 capabilities. OmniRoute: 341 providers, 90+ free providers built-in, 19 routing strategies, 12-engine token compression, built-in MCP server with 109 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's docs. +What sets OmniRoute apart โ€” comparison table vs 9router, OpenRouter, CLIProxyAPI and LiteLLM across 13 capabilities. OmniRoute: 342 providers, 90+ free providers built-in, 19 routing strategies, 12-engine token compression, built-in MCP server with 109 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's docs. ๐Ÿ“Š Full methodology & per-feature detail vs 9router, OpenRouter, CLIProxyAPI & LiteLLM โ†’ [`docs/comparison/OMNIROUTE_VS_ALTERNATIVES.md`](docs/comparison/OMNIROUTE_VS_ALTERNATIVES.md) @@ -559,7 +559,7 @@ the current catalog at **[radar.omniroute.online/planos](https://radar.omniroute - **๐Ÿ–ผ๏ธ New endpoints** โ€” `/v1/ocr` (Mistral OCR) and `/v1/audio/translations` (Whisper-style) round out the media surface. โ†’ [API Reference](docs/reference/API_REFERENCE.md) - **๐ŸŽจ Image / video / audio generation** โ€” one API for media: xAI Grok Imagine & Novita AI video, ComfyUI, Freepik, Adobe Firefly, Microsoft Designer, Segmind, EdgeTTS. โ†’ [API Reference](docs/reference/API_REFERENCE.md) - **๐ŸŒ Deployment & ops** โ€” reverse-proxy `basePath`, browser-language auto-detect, per-key device tracking, root-less MITM trust, zh-TW localization. โ†’ [Environment](docs/reference/ENVIRONMENT.md) -- **๐Ÿค More providers & agents** โ€” Cursor Cloud Agent, Grok Build (xAI) with browser + OAuth login, Ollama first-class card, Claude Opus 5 & Sonnet 5, Kimi official partnership (Code/Web/Moonshot), Zed, Requesty, SenseNova, Yuanbao, Agnes AIโ€ฆ and a refreshed **341-provider catalog**. โ†’ [Providers](docs/reference/PROVIDER_REFERENCE.md) +- **๐Ÿค More providers & agents** โ€” Cursor Cloud Agent, Grok Build (xAI) with browser + OAuth login, Ollama first-class card, Claude Opus 5 & Sonnet 5, Kimi official partnership (Code/Web/Moonshot), Zed, Requesty, SenseNova, Yuanbao, Agnes AIโ€ฆ and a refreshed **342-provider catalog**. โ†’ [Providers](docs/reference/PROVIDER_REFERENCE.md) - **๐Ÿ“ก Routing transparency** โ€” every response carries an `X-OmniRoute-Decision` header naming the strategy/provider/latency that served it, a new `cache-optimized` combo strategy + Auto-Combo `cacheAffinity` factor route repeat requests back to the connection holding the cached prefix, and a read-only `/v1/auto-combo/{channel}/candidates` endpoint exposes an `auto/*` channel's live candidate pool. โ†’ [Auto-Combo](docs/routing/AUTO-COMBO.md) - **โšก Local performance & infra** โ€” one-click local Redis, Cloudflare Workers / Deno Deploy relay deployers, Bifrost & Mux as supervised embedded services. โ†’ [Embedded Services](docs/frameworks/EMBEDDED-SERVICES.md) @@ -642,11 +642,11 @@ of your shell history. โ†’ [CLI Integrations](docs/guides/CLI-INTEGRATIONS.md)
-## ๐ŸŒ 341 AI Providers โ€” 90+ Free +## ๐ŸŒ 342 AI Providers โ€” 90+ Free
-> The most complete catalog of any open-source router: **341 providers**, **90+ with a free tier**, **56 free forever**. +> The most complete catalog of any open-source router: **342 providers**, **90+ with a free tier**, **56 free forever**.
diff --git a/changelog.d/features/10729-cursor-api-key-and-cli-passthrough.md b/changelog.d/features/10729-cursor-api-key-and-cli-passthrough.md new file mode 100644 index 0000000000..96094ffff1 --- /dev/null +++ b/changelog.d/features/10729-cursor-api-key-and-cli-passthrough.md @@ -0,0 +1 @@ +- **feat(providers):** new `cursor-api` provider (card "Cursor API", alias `cua`): connect a Cursor user API key (`crsr_โ€ฆ`) and route `cursor-api/` through the existing Cursor agent executor (the key is exchanged for a 1h session token and cached), plus a `/api/cursor-cli/*` passthrough so the Cursor CLI itself runs through OmniRoute (`CURSOR_API_ENDPOINT=http:///api/cursor-cli`, `CURSOR_API_KEY=`) with every RPC attributed and logged. The IDE `cursor` provider is unchanged. (#10729) diff --git a/docs/diagrams/cli-terminal.svg b/docs/diagrams/cli-terminal.svg index 99bc29b327..a18765a9c7 100644 --- a/docs/diagrams/cli-terminal.svg +++ b/docs/diagrams/cli-terminal.svg @@ -1,4 +1,4 @@ - + Compact animated terminal cycling three real OmniRoute CLI commands with a typewriter effect and a scrolling subcommand ticker; the first frame shows the completed providers-list screen. diff --git a/docs/diagrams/comparison-table.svg b/docs/diagrams/comparison-table.svg index 80b3cbcdb2..744dbb7d00 100644 --- a/docs/diagrams/comparison-table.svg +++ b/docs/diagrams/comparison-table.svg @@ -1,4 +1,4 @@ - + Static-header comparison table where each capability row fades in top to bottom; the OmniRoute column is highlighted and shows a check or a leading value in every row, while competitors show a mix of checks, partials and crosses. diff --git a/docs/diagrams/promise-pillars.svg b/docs/diagrams/promise-pillars.svg index a25437f78c..5b692896e9 100644 --- a/docs/diagrams/promise-pillars.svg +++ b/docs/diagrams/promise-pillars.svg @@ -1,4 +1,4 @@ - + Animated promise card: six pillar tiles fade in in reading order, then a soft colored border highlight sweeps from tile to tile in a continuous cycle. @@ -21,7 +21,7 @@ - One endpoint. 341 providers. Never stop building โ€” OmniRoute picks the cheapest one that works. + One endpoint. 342 providers. Never stop building โ€” OmniRoute picks the cheapest one that works. @@ -38,7 +38,7 @@ Never hit limits - Auto-fallback across 341 providers in + Auto-fallback across 342 providers in milliseconds. Quota out? The next provider takes over โ€” zero downtime. diff --git a/docs/diagrams/readme-hero.svg b/docs/diagrams/readme-hero.svg index 0182df44a2..6e13fac6b4 100644 --- a/docs/diagrams/readme-hero.svg +++ b/docs/diagrams/readme-hero.svg @@ -1,4 +1,4 @@ - + Animated hero card: a pulse travels the divider line and a compression bar demo repeatedly shrinks a prompt by up to 95 percent; all headline content is static and readable on the first frame. @@ -28,7 +28,7 @@ Never stop coding. - Every AI tool โ†’ 341 providers โ€” 90+ free โ€” through one endpoint. + Every AI tool โ†’ 342 providers โ€” 90+ free โ€” through one endpoint. Claude Code ยท Codex ยท Cursor ยท Cline ยท Copilot ยท Antigravity  โ†’  FREE Claude / GPT / Gemini ยท auto-fallback diff --git a/docs/i18n/ar/llm.txt b/docs/i18n/ar/llm.txt index d5a97ec33a..732d79189c 100644 --- a/docs/i18n/ar/llm.txt +++ b/docs/i18n/ar/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/az/llm.txt b/docs/i18n/az/llm.txt index 6116eb395e..e930a1f05a 100644 --- a/docs/i18n/az/llm.txt +++ b/docs/i18n/az/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/bg/llm.txt b/docs/i18n/bg/llm.txt index 6116eb395e..e930a1f05a 100644 --- a/docs/i18n/bg/llm.txt +++ b/docs/i18n/bg/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/bn/llm.txt b/docs/i18n/bn/llm.txt index 18ab0fc537..baa6656839 100644 --- a/docs/i18n/bn/llm.txt +++ b/docs/i18n/bn/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/cs/llm.txt b/docs/i18n/cs/llm.txt index 08f8297c10..dfb5f9b2b8 100644 --- a/docs/i18n/cs/llm.txt +++ b/docs/i18n/cs/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/da/llm.txt b/docs/i18n/da/llm.txt index 531f324c3a..10ce4811ac 100644 --- a/docs/i18n/da/llm.txt +++ b/docs/i18n/da/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/de/llm.txt b/docs/i18n/de/llm.txt index dfefdf04bf..b5ebeb9c86 100644 --- a/docs/i18n/de/llm.txt +++ b/docs/i18n/de/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/es/llm.txt b/docs/i18n/es/llm.txt index cd36f88e07..72d4fa4a05 100644 --- a/docs/i18n/es/llm.txt +++ b/docs/i18n/es/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/fa/llm.txt b/docs/i18n/fa/llm.txt index 1d98061631..4b324a992d 100644 --- a/docs/i18n/fa/llm.txt +++ b/docs/i18n/fa/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/fi/llm.txt b/docs/i18n/fi/llm.txt index 01fb1ec72b..92d30e036c 100644 --- a/docs/i18n/fi/llm.txt +++ b/docs/i18n/fi/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/fr/llm.txt b/docs/i18n/fr/llm.txt index b20f38d804..2b5cdefa71 100644 --- a/docs/i18n/fr/llm.txt +++ b/docs/i18n/fr/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/gu/llm.txt b/docs/i18n/gu/llm.txt index 3cabcd235f..d0f0f42f59 100644 --- a/docs/i18n/gu/llm.txt +++ b/docs/i18n/gu/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/he/llm.txt b/docs/i18n/he/llm.txt index d1dca10cc1..f8f0b3f644 100644 --- a/docs/i18n/he/llm.txt +++ b/docs/i18n/he/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/hi/llm.txt b/docs/i18n/hi/llm.txt index e88a70b26a..d79717b61e 100644 --- a/docs/i18n/hi/llm.txt +++ b/docs/i18n/hi/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/hu/llm.txt b/docs/i18n/hu/llm.txt index fdd9526279..1b941f1e5a 100644 --- a/docs/i18n/hu/llm.txt +++ b/docs/i18n/hu/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/id/llm.txt b/docs/i18n/id/llm.txt index 776304488c..e1b23c5e3d 100644 --- a/docs/i18n/id/llm.txt +++ b/docs/i18n/id/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/in/llm.txt b/docs/i18n/in/llm.txt index 2e0784f344..7713dacb68 100644 --- a/docs/i18n/in/llm.txt +++ b/docs/i18n/in/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/it/llm.txt b/docs/i18n/it/llm.txt index 160add875c..e0823ba499 100644 --- a/docs/i18n/it/llm.txt +++ b/docs/i18n/it/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/ja/llm.txt b/docs/i18n/ja/llm.txt index 7e3f75466f..5c1963195f 100644 --- a/docs/i18n/ja/llm.txt +++ b/docs/i18n/ja/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/ko/llm.txt b/docs/i18n/ko/llm.txt index 6cd010d0a4..2ae8fe4ec4 100644 --- a/docs/i18n/ko/llm.txt +++ b/docs/i18n/ko/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/mr/llm.txt b/docs/i18n/mr/llm.txt index 12129f663d..157eec643a 100644 --- a/docs/i18n/mr/llm.txt +++ b/docs/i18n/mr/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/ms/llm.txt b/docs/i18n/ms/llm.txt index 8c01bf3654..e26b195208 100644 --- a/docs/i18n/ms/llm.txt +++ b/docs/i18n/ms/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/nl/llm.txt b/docs/i18n/nl/llm.txt index 7fe980153e..67f935d590 100644 --- a/docs/i18n/nl/llm.txt +++ b/docs/i18n/nl/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/no/llm.txt b/docs/i18n/no/llm.txt index 32364510ee..e28dda1508 100644 --- a/docs/i18n/no/llm.txt +++ b/docs/i18n/no/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/phi/llm.txt b/docs/i18n/phi/llm.txt index 54595155ef..ed539c84be 100644 --- a/docs/i18n/phi/llm.txt +++ b/docs/i18n/phi/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/pl/llm.txt b/docs/i18n/pl/llm.txt index 18c1d5aeaf..f8665fa410 100644 --- a/docs/i18n/pl/llm.txt +++ b/docs/i18n/pl/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/pt-BR/llm.txt b/docs/i18n/pt-BR/llm.txt index 8dc803bdbe..c56d966794 100644 --- a/docs/i18n/pt-BR/llm.txt +++ b/docs/i18n/pt-BR/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/pt/llm.txt b/docs/i18n/pt/llm.txt index 0a841f4d7f..6e2aa2bb20 100644 --- a/docs/i18n/pt/llm.txt +++ b/docs/i18n/pt/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/ro/llm.txt b/docs/i18n/ro/llm.txt index 4461a57b48..4fac614baf 100644 --- a/docs/i18n/ro/llm.txt +++ b/docs/i18n/ro/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/ru/llm.txt b/docs/i18n/ru/llm.txt index e4b51b687b..9d522135b2 100644 --- a/docs/i18n/ru/llm.txt +++ b/docs/i18n/ru/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/sk/llm.txt b/docs/i18n/sk/llm.txt index 3783940896..df0dbd95a7 100644 --- a/docs/i18n/sk/llm.txt +++ b/docs/i18n/sk/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/sv/llm.txt b/docs/i18n/sv/llm.txt index 3e4eb1f5f4..59246e38bf 100644 --- a/docs/i18n/sv/llm.txt +++ b/docs/i18n/sv/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/sw/llm.txt b/docs/i18n/sw/llm.txt index ec134c100a..dbbf236c5d 100644 --- a/docs/i18n/sw/llm.txt +++ b/docs/i18n/sw/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/ta/llm.txt b/docs/i18n/ta/llm.txt index 64848422b9..842ca8c7ee 100644 --- a/docs/i18n/ta/llm.txt +++ b/docs/i18n/ta/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/te/llm.txt b/docs/i18n/te/llm.txt index ebb7d28a0c..5098dbc0ae 100644 --- a/docs/i18n/te/llm.txt +++ b/docs/i18n/te/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/th/llm.txt b/docs/i18n/th/llm.txt index dc01025526..f1251db7be 100644 --- a/docs/i18n/th/llm.txt +++ b/docs/i18n/th/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/tr/llm.txt b/docs/i18n/tr/llm.txt index 182af11a3b..ba729555c2 100644 --- a/docs/i18n/tr/llm.txt +++ b/docs/i18n/tr/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/uk-UA/llm.txt b/docs/i18n/uk-UA/llm.txt index bd5997d66a..33b12b870b 100644 --- a/docs/i18n/uk-UA/llm.txt +++ b/docs/i18n/uk-UA/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/ur/llm.txt b/docs/i18n/ur/llm.txt index 6d04724edb..bd5d5fdc83 100644 --- a/docs/i18n/ur/llm.txt +++ b/docs/i18n/ur/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/vi/llm.txt b/docs/i18n/vi/llm.txt index ff99a1050e..4b59fd5d3d 100644 --- a/docs/i18n/vi/llm.txt +++ b/docs/i18n/vi/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/zh-CN/llm.txt b/docs/i18n/zh-CN/llm.txt index 925f9e6184..122734bec7 100644 --- a/docs/i18n/zh-CN/llm.txt +++ b/docs/i18n/zh-CN/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/i18n/zh-TW/llm.txt b/docs/i18n/zh-TW/llm.txt index 1c95e25755..b1f841f8e9 100644 --- a/docs/i18n/zh-TW/llm.txt +++ b/docs/i18n/zh-TW/llm.txt @@ -4,7 +4,7 @@ --- -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -169,7 +169,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/docs/providers/CURSOR-API-KEY-AND-CLI.md b/docs/providers/CURSOR-API-KEY-AND-CLI.md new file mode 100644 index 0000000000..53c0a85dfd --- /dev/null +++ b/docs/providers/CURSOR-API-KEY-AND-CLI.md @@ -0,0 +1,123 @@ +--- +title: "Cursor API provider and the Cursor CLI passthrough" +version: 3.8.50 +lastUpdated: 2026-08-19 +--- + +# Cursor API provider and the Cursor CLI passthrough + +Two ways to put Cursor behind OmniRoute without an IDE session: + +1. **`cursor-api` provider** (card "Cursor API", alias `cua`): an API-key + provider that holds a Cursor user API key (`crsr_โ€ฆ`, generated at + `https://cursor.com/dashboard/api`). Any OmniRoute client then reaches + Cursor models through `/v1/chat/completions` as `cursor-api/` or + `cua/`, with the usual quota, fallback and logging layers. The IDE + provider (`cursor`, OAuth/IDE session) is unchanged. +2. **Cursor CLI passthrough**: point the Cursor CLI (`agent`) at OmniRoute so + every RPC the CLI makes is authenticated with an OmniRoute API key, forwarded + to Cursor with a `cursor-api` connection's credential, and recorded in the + Logs page. + +## Why the key is exchanged + +`api2.cursor.sh` rejects a raw `crsr_โ€ฆ` key as a Bearer token (401). The Cursor +CLI first POSTs the key to `/auth/exchange_user_api_key` and receives a session +JWT that expires after one hour; the returned `refreshToken` carries the same +`exp`, so refreshing means re-exchanging the key. +`open-sse/services/cursorApiKeyAuth.ts` does that exchange, caches one session +token per key, re-exchanges five minutes before expiry and drops the cached +token when Cursor answers 401. `CursorExecutor` calls it right before opening +the upstream stream for `cursor-api` connections. + +## The `cursor-api` provider + +Registry: `open-sse/config/providers/registry/cursor/index.ts` +(`cursor_apiProvider`, `authType: "apikey"`, same `format`, `baseUrl` and +`models` as `cursor`). Catalog card: +`src/shared/constants/providers/apikey/specialty-media.ts`. Executor map: +`open-sse/executors/index.ts` (`"cursor-api"` / `cua` โ†’ +`new CursorExecutor("cursor-api")`). + +Dashboard: Providers โ†’ Cursor API โ†’ Add API key. + +REST: + +```bash +curl -sS -X POST http://localhost:20128/api/providers \ + -H "Content-Type: application/json" \ + -d '{"provider":"cursor-api","name":"cursor-api-key","apiKey":"crsr_โ€ฆ","priority":1}' +``` + +Then: + +```bash +curl -sS http://localhost:20128/v1/chat/completions \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d '{"model":"cursor-api/auto","messages":[{"role":"user","content":"say PONG"}]}' +``` + +Notes: + +- Model listing for `cursor-api` comes from the static Cursor registry (the + same list the IDE provider falls back to); no `cursor-agent` install is + needed on the OmniRoute host. +- `POST /api/providers/{id}/refresh-cursor` is for the `cursor` IDE provider + only; `cursor-api` connections have no IDE session to renew. + +## Cursor CLI passthrough + +Route: `src/app/api/cursor-cli/[...path]/route.ts` โ†’ +`open-sse/handlers/cursorCliProxy.ts`. The prefix `/api/cursor-cli/` is +registered in `src/shared/constants/publicApiRoutes.ts` because the handler +enforces its own authentication: + +| Path | Auth expected from the CLI | What OmniRoute does | +| ---------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `POST /auth/exchange_user_api_key` | `Bearer ` | Validates the key, mints a 1h HS256 JWT (signed with `JWT_SECRET`) and returns it | +| every other path (`/aiserver.v1.*`, `/agent.v1.AgentService/RunSSE`, `/aiserver.v1.BidiService/BidiAppend`, `/v1/traces`, โ€ฆ) | `Bearer ` | Verifies issuer/audience/expiry, picks an active `cursor-api` connection, swaps the Authorization header for the exchanged Cursor token and streams the reply back | + +The CLI decodes `exp` from whatever token it receives, so handing it an opaque +token makes it re-exchange before almost every request; the minted JWT avoids +that. A 401 from OmniRoute makes the CLI exchange again. + +### Setup + +1. Create an OmniRoute API key (Dashboard โ†’ API keys) and a `cursor-api` + connection. +2. Tell the CLI to use HTTP/1.1 for the agent stream. In + `~/.cursor/cli-config.json`: + + ```json + { "network": { "useHttp1ForAgent": true } } + ``` + + Without this the CLI opens the agent turn over HTTP/2 to a separately + configured agent host and only the control-plane RPCs go through the + endpoint. + +3. Run the CLI against OmniRoute: + + ```bash + export CURSOR_API_ENDPOINT=http://localhost:20128/api/cursor-cli + export CURSOR_API_KEY= + agent -p --trust "Reply with exactly OK" + ``` + +Every hop lands in Logs as provider `cursor-api`, request type `cursor-cli`, +path `/api/cursor-cli/`, attributed to the OmniRoute API key and the +connection that served it. + +### Failure modes + +| Situation | Response to the CLI | +| ------------------------------------------------ | --------------------------------------------- | +| Unknown OmniRoute key and `REQUIRE_API_KEY=true` | 401 `unauthenticated` on exchange | +| `REQUIRE_API_KEY=false` | anonymous session (mirrors `/v1/*` behaviour) | +| Expired / foreign / tampered session JWT | 401, the CLI re-exchanges | +| OmniRoute API key revoked after exchange | 401 on the next RPC | +| No active `cursor-api` connection | 503 `unavailable` | +| Cursor rejects the connection's key | 401 `unauthenticated`, cached session dropped | +| Upstream unreachable | 502 `unavailable` (sanitized message) | +| `JWT_SECRET` unset | 503 on exchange | diff --git a/docs/providers/meta.json b/docs/providers/meta.json index 82eec7eca7..fa6485dd57 100644 --- a/docs/providers/meta.json +++ b/docs/providers/meta.json @@ -7,6 +7,7 @@ "CHATGPT_WEB", "AGENTROUTER", "ZED-DOCKER", - "CURSOR-DOCKER" + "CURSOR-DOCKER", + "CURSOR-API-KEY-AND-CLI" ] } diff --git a/docs/reference/PROVIDER_REFERENCE.md b/docs/reference/PROVIDER_REFERENCE.md index b3ea495df4..d6dcf8abb2 100644 --- a/docs/reference/PROVIDER_REFERENCE.md +++ b/docs/reference/PROVIDER_REFERENCE.md @@ -1,16 +1,16 @@ --- title: "Provider Reference" version: 3.8.50 -lastUpdated: 2026-08-18 +lastUpdated: 2026-08-19 --- # 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-18 +> **Last generated:** 2026-08-19 -Total providers: **341**. See category breakdown below. +Total providers: **342**. See category breakdown below. ## Categories @@ -120,7 +120,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) (228) +## API Key Providers (paid / paid-with-free-credits) (229) | ID | Alias | Name | Tags | Website | Notes | |----|-------|------|------|---------|-------| @@ -169,6 +169,7 @@ Use the dashboard at `/dashboard/providers` to enable, configure, and test each | `command-code` | `cmd` | Command Code | API key | [link](https://commandcode.ai/) | Use a Command Code API key. Requests are sent to Command Code's /alpha/generate endpoint. | | `coze` | `coze` | Coze | API key | [link](https://coze.com) | Get API key at coze.com/open/api | | `crof` | `crof` | CrofAI | API key | [link](https://crof.ai) | โ€” | +| `cursor-api` | `cua` | Cursor API | API key | [link](https://cursor.com/dashboard/api) | Paste a Cursor user API key (crsr_...) from cursor.com/dashboard/api. OmniRoute exchanges it for a session token on demand; no IDE or cursor-agent install is needed. Usage bills to the Cursor plan that owns the key. | | `dahl` | `dahl` | Dahl | API key | [link](https://inference.dahl.global) | Click 'Add Account' to auto-generate a token, or add a manual API key. | | `databricks` | `databricks` | Databricks | API key, enterprise | [link](https://www.databricks.com) | โ€” | | `datarobot` | `datarobot` | DataRobot | API key, enterprise | [link](https://docs.datarobot.com) | Use your DataRobot API token. Optional Base URL can be the account root (for LLM Gateway) or a deployment URL under /api/v2/deployments/. | diff --git a/llm.txt b/llm.txt index 92016efd1c..cc2d9d5aba 100644 --- a/llm.txt +++ b/llm.txt @@ -1,6 +1,6 @@ # OmniRoute -> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 341 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. +> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 342 AI providers โ€” all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app. ## Overview @@ -165,7 +165,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo โ”‚ โ”‚ โ””โ”€โ”€ manager.ts # MITM proxy manager โ”‚ โ”œโ”€โ”€ shared/ # Shared utilities, components, and constants โ”‚ โ”‚ โ”œโ”€โ”€ components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.) -โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (341), model lists, pricing, routing strategies, MCP scopes +โ”‚ โ”‚ โ”œโ”€โ”€ constants/ # Provider definitions (342), model lists, pricing, routing strategies, MCP scopes โ”‚ โ”‚ โ”œโ”€โ”€ contracts/ # Shared API contracts โ”‚ โ”‚ โ”œโ”€โ”€ hooks/ # React hooks โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ # Shared middleware utilities @@ -277,7 +277,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo ## Key Features (v3.8.50) ### Core Proxy -- **341 AI providers** with automatic format translation +- **342 AI providers** with automatic format translation - **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible) - **18 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, context-relay, fusion, pipeline - **4-tier fallback**: Subscription โ†’ API Key โ†’ Cheap โ†’ Free @@ -475,7 +475,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool ## v3.8.x Highlights -- **341-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add +- **342-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **19 routing strategies** โ€” including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay` - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) diff --git a/open-sse/config/providers/index.ts b/open-sse/config/providers/index.ts index 75c69f1a39..34189e0d00 100644 --- a/open-sse/config/providers/index.ts +++ b/open-sse/config/providers/index.ts @@ -65,7 +65,7 @@ import { api_airforceProvider } from "./registry/api-airforce/index.ts"; import { mistralProvider } from "./registry/mistral/index.ts"; import { togetherProvider } from "./registry/together/index.ts"; import { cohereProvider } from "./registry/cohere/index.ts"; -import { cursorProvider } from "./registry/cursor/index.ts"; +import { cursorProvider, cursor_apiProvider } from "./registry/cursor/index.ts"; import { volcengineProvider } from "./registry/volcengine/index.ts"; import { hackclubProvider } from "./registry/hackclub/index.ts"; import { freetheaiProvider } from "./registry/freetheai/index.ts"; @@ -327,6 +327,7 @@ export const REGISTRY: Record = { together: togetherProvider, cohere: cohereProvider, cursor: cursorProvider, + "cursor-api": cursor_apiProvider, volcengine: volcengineProvider, hackclub: hackclubProvider, freetheai: freetheaiProvider, diff --git a/open-sse/config/providers/registry/cursor/index.ts b/open-sse/config/providers/registry/cursor/index.ts index 0e167d39bb..1bb6d02b21 100644 --- a/open-sse/config/providers/registry/cursor/index.ts +++ b/open-sse/config/providers/registry/cursor/index.ts @@ -156,3 +156,29 @@ export const cursorProvider: RegistryEntry = { { id: "kimi-k2.7-code", name: "Kimi K2.7 Code" }, ], }; + +/** + * API-key variant of the Cursor provider. + * + * Same wire protocol, executor and catalog as `cursor`, but the connection + * holds a Cursor user API key (`crsr_โ€ฆ`, cursor.com/dashboard/api) instead of + * an IDE/OAuth session. The executor exchanges that key for a session token + * on demand (open-sse/services/cursorApiKeyAuth.ts), so no cursor-agent or + * IDE install is needed on the OmniRoute host. Kept as a distinct backend ID + * so API-key and IDE-session connections never share renewal, quota or + * dashboard semantics. + */ +export const cursor_apiProvider: RegistryEntry = { + id: "cursor-api", + alias: "cua", + format: cursorProvider.format, + executor: "cursor-api", + baseUrl: cursorProvider.baseUrl, + chatPath: cursorProvider.chatPath, + authType: "apikey", + authHeader: "bearer", + defaultContextLength: cursorProvider.defaultContextLength, + headers: getCursorRegistryHeaders(), + clientVersion: CURSOR_REGISTRY_VERSION, + models: cursorProvider.models, +}; diff --git a/open-sse/executors/cursor.ts b/open-sse/executors/cursor.ts index 89f7799b03..bc9ade9d27 100644 --- a/open-sse/executors/cursor.ts +++ b/open-sse/executors/cursor.ts @@ -57,6 +57,13 @@ import { type StreamingState as ComposerStreamingState, } from "../utils/composerToolCalls.ts"; import { cursorSessionManager, type CursorSession } from "../services/cursorSessionManager.ts"; +import { + CursorApiKeyExchangeError, + invalidateCursorSessionToken, + isCursorApiKey, + resolveCursorBearerToken, + stripCursorOAuthTokenPrefix, +} from "../services/cursorApiKeyAuth.ts"; import crypto from "crypto"; import * as fs from "node:fs"; import * as zlib from "node:zlib"; @@ -706,18 +713,44 @@ export function processFrame( } export class CursorExecutor extends BaseExecutor { - constructor() { - super("cursor", PROVIDERS.cursor); + constructor(provider: "cursor" | "cursor-api" = "cursor") { + super(provider, PROVIDERS[provider]); } buildUrl() { return CURSOR_AGENT_URL; } + /** + * API-key connections carry a `crsr_โ€ฆ` key that api2.cursor.sh does not + * accept as a Bearer; swap it for the exchanged session token before the + * h2 stream is opened. OAuth/IDE-session connections pass through untouched. + */ + async resolveExecutionCredentials(credentials) { + if (!isCursorApiKey(credentials?.apiKey)) return credentials; + try { + const accessToken = await resolveCursorBearerToken(credentials); + return { ...credentials, accessToken }; + } catch (err) { + const status = + err instanceof CursorApiKeyExchangeError ? err.status : HTTP_STATUS.SERVER_ERROR; + const message = err instanceof Error ? err.message : String(err); + return new Response( + JSON.stringify({ + error: { + message: sanitizeErrorMessage(message), + type: status === HTTP_STATUS.UNAUTHORIZED ? "authentication_error" : "connection_error", + code: "", + }, + }), + { status, headers: { "Content-Type": "application/json" } } + ); + } + } + buildHeaders(credentials) { - const accessToken = credentials.accessToken; const ghostMode = credentials.providerSpecificData?.ghostMode !== false; - const cleanToken = accessToken.includes("::") ? accessToken.split("::")[1] : accessToken; + const cleanToken = stripCursorOAuthTokenPrefix(credentials.accessToken ?? ""); const requestId = crypto.randomUUID(); const traceParent = `00-${crypto.randomBytes(16).toString("hex")}-${crypto.randomBytes(8).toString("hex")}-01`; @@ -825,7 +858,7 @@ export class CursorExecutor extends BaseExecutor { */ private async loadLiveCatalogIds(): Promise | undefined> { try { - const catalog = await getActiveSyncedCatalog("cursor"); + const catalog = await getActiveSyncedCatalog(this.provider); if (!catalog.models.length) return undefined; return new Set(catalog.models.map((model) => model.id)); } catch { @@ -1179,7 +1212,11 @@ export class CursorExecutor extends BaseExecutor { async execute({ model, body, stream, credentials, signal, log, upstreamExtraHeaders }) { const url = this.buildUrl(); - const headers = this.buildHeaders(credentials); + const executionCredentials = await this.resolveExecutionCredentials(credentials); + if (executionCredentials instanceof Response) { + return { response: executionCredentials, url, headers: {}, transformedBody: body }; + } + const headers = this.buildHeaders(executionCredentials); mergeUpstreamExtraHeaders(headers, upstreamExtraHeaders); const messages: ChatMessage[] = body.messages || []; @@ -1252,8 +1289,10 @@ export class CursorExecutor extends BaseExecutor { if (isToolFollowUp) { session = cursorSessionManager.acquire(conversationId); // #9029: content-based session match when client lacks conversation_id. - if (!session && !body.conversation_id) session = cursorSessionManager.findByToolCallIds( - messages.filter(m => m.role === "tool" && m.tool_call_id).map(m => m.tool_call_id!)); + if (!session && !body.conversation_id) + session = cursorSessionManager.findByToolCallIds( + messages.filter((m) => m.role === "tool" && m.tool_call_id).map((m) => m.tool_call_id!) + ); } if (session) { @@ -1334,6 +1373,9 @@ export class CursorExecutor extends BaseExecutor { if (opened.status !== 200) { const errBuf = await opened.consumeError(); const errText = errBuf.toString("utf8") || "Unknown error"; + if (opened.status === HTTP_STATUS.UNAUTHORIZED && isCursorApiKey(credentials.apiKey)) { + invalidateCursorSessionToken(credentials.apiKey); + } return { response: buildErrorResponse(opened.status, `[${opened.status}]: ${errText}`), url, diff --git a/open-sse/executors/index.ts b/open-sse/executors/index.ts index 3fc2bdf9b3..d82452bb7e 100644 --- a/open-sse/executors/index.ts +++ b/open-sse/executors/index.ts @@ -1,9 +1,5 @@ import { SEARCH_PROVIDERS } from "../config/searchRegistry.ts"; -import { - registerExecutor, - getRegisteredExecutor, - hasRegisteredExecutor, -} from "./registry.ts"; +import { registerExecutor, getRegisteredExecutor, hasRegisteredExecutor } from "./registry.ts"; import { AntigravityExecutor } from "./antigravity.ts"; import { GithubExecutor } from "./github.ts"; import { GheCopilotExecutor } from "./ghe-copilot.ts"; @@ -107,6 +103,8 @@ const executors = { "glm-cn": new GlmExecutor("glm-cn"), glmt: new GlmExecutor("glmt"), cu: new CursorExecutor(), // Alias for cursor + "cursor-api": new CursorExecutor("cursor-api"), + cua: new CursorExecutor("cursor-api"), "azure-openai": new AzureOpenAIExecutor(), "azure-ai": new AzureAiExecutor(), "command-code": new CommandCodeExecutor(), diff --git a/open-sse/handlers/cursorCliProxy.ts b/open-sse/handlers/cursorCliProxy.ts new file mode 100644 index 0000000000..dbf742f8f6 --- /dev/null +++ b/open-sse/handlers/cursorCliProxy.ts @@ -0,0 +1,524 @@ +/** + * Cursor CLI passthrough. + * + * cursor-agent honours `--endpoint` / CURSOR_API_ENDPOINT and, with + * `network.useHttp1ForAgent: true`, talks to that endpoint exclusively over + * HTTP/1.1: unary Connect-RPC POSTs (`/aiserver.v1.*`, `/agent.v1.*`, + * `/aiserver.v1.BidiService/BidiAppend`), the agent turn as + * `/agent.v1.AgentService/RunSSE` (text/event-stream), OTLP traces on + * `/v1/traces`, and the API-key bootstrap `POST /auth/exchange_user_api_key`. + * + * Pointing the CLI at OmniRoute therefore only needs a thin forwarder: + * 1. `/auth/exchange_user_api_key` authenticates the CLI with an OmniRoute + * API key and hands back an OmniRoute-minted session JWT. The CLI reads + * `exp` from whatever JWT it receives and re-exchanges when the token is + * opaque or expired, so the minted token must be a real JWT with `exp`. + * 2. Every other path verifies that JWT, resolves an active `cursor-api` + * connection (the crsr_ key is exchanged for a session token), swaps the + * Authorization header and streams the upstream reply back unchanged. + * Each hop is recorded in call_logs. + */ + +import { SignJWT, jwtVerify, type JWTPayload } from "jose"; +import { z } from "zod"; +import { getApiKeyById, getApiKeyMetadata, validateApiKey } from "@/lib/db/apiKeys"; +import { getProviderConnections } from "@/lib/db/providers"; +import { saveCallLog } from "@/lib/usage/callLogs"; +import { isRequireApiKeyEnabled } from "@/shared/utils/featureFlags"; +import { HTTP_STATUS } from "../config/constants.ts"; +import { + CURSOR_API_BASE_URL, + CURSOR_API_KEY_EXCHANGE_PATH, + CursorApiKeyExchangeError, + invalidateCursorSessionToken, + isCursorApiKey, + resolveCursorBearerToken, +} from "../services/cursorApiKeyAuth.ts"; +import { sanitizeErrorMessage } from "../utils/error.ts"; + +export const CURSOR_CLI_PROXY_PREFIX = "/api/cursor-cli"; +export const CURSOR_CLI_SESSION_ISSUER = "omniroute"; +export const CURSOR_CLI_SESSION_AUDIENCE = "cursor-cli"; +export const CURSOR_CLI_SESSION_TTL_SECONDS = 60 * 60; +export const CURSOR_CLI_REQUEST_TYPE = "cursor-cli"; +const ANONYMOUS_SUBJECT = "anonymous"; +const PROVIDER_ID = "cursor-api"; + +const REQUEST_HEADER_DENYLIST = new Set([ + "authorization", + "host", + "connection", + "content-length", + "accept-encoding", + "keep-alive", + "proxy-authorization", + "proxy-connection", + "te", + "trailer", + "transfer-encoding", + "upgrade", + "x-forwarded-for", + "x-forwarded-host", + "x-forwarded-proto", + "x-real-ip", + "cookie", +]); + +const RESPONSE_HEADER_DENYLIST = new Set([ + "connection", + "content-encoding", + "content-length", + "keep-alive", + "transfer-encoding", + "set-cookie", +]); + +const exchangeBodySchema = z.object({}).passthrough(); + +const sessionClaimsSchema = z.object({ + sub: z.string().min(1), + iss: z.literal(CURSOR_CLI_SESSION_ISSUER), + aud: z.union([ + z.literal(CURSOR_CLI_SESSION_AUDIENCE), + z.array(z.string()).refine((list) => list.includes(CURSOR_CLI_SESSION_AUDIENCE)), + ]), + exp: z.number(), + name: z.string().nullable().optional(), +}); + +export type CursorCliPrincipal = { + apiKeyId: string | null; + apiKeyName: string | null; +}; + +export type CursorCliConnectionLike = { + id?: unknown; + apiKey?: unknown; + accessToken?: unknown; + priority?: unknown; + rateLimitedUntil?: unknown; +}; + +export type CursorCliProxyDeps = { + fetchImpl: typeof fetch; + now: () => number; + getSecret: () => string | undefined; + validateApiKey: (key: string) => Promise; + getApiKeyMetadata: (key: string) => Promise<{ id: string; name: string } | null>; + getApiKeyById: (id: string) => Promise<{ isActive?: unknown; revokedAt?: unknown } | null>; + requireApiKey: () => boolean; + listCursorConnections: () => Promise; + resolveBearer: (credentials: { + apiKey?: string | null; + accessToken?: string | null; + }) => Promise; + invalidateBearer: (apiKey: string) => void; + saveCallLog: (entry: Record) => Promise; + upstreamBaseUrl: string; +}; + +const defaultDeps: CursorCliProxyDeps = { + fetchImpl: (input, init) => fetch(input, init), + now: () => Date.now(), + getSecret: () => process.env.JWT_SECRET, + validateApiKey: (key) => validateApiKey(key), + getApiKeyMetadata: async (key) => { + const meta = await getApiKeyMetadata(key); + return meta ? { id: meta.id, name: meta.name } : null; + }, + getApiKeyById: (id) => getApiKeyById(id), + requireApiKey: () => isRequireApiKeyEnabled(), + listCursorConnections: async () => + (await getProviderConnections({ + provider: PROVIDER_ID, + isActive: true, + })) as CursorCliConnectionLike[], + resolveBearer: (credentials) => resolveCursorBearerToken(credentials), + invalidateBearer: (apiKey) => invalidateCursorSessionToken(apiKey), + saveCallLog: (entry) => saveCallLog(entry), + upstreamBaseUrl: CURSOR_API_BASE_URL, +}; + +function jsonResponse(status: number, body: Record): Response { + return new Response(JSON.stringify(body), { + status, + headers: { "content-type": "application/json" }, + }); +} + +function connectError(status: number, code: string, message: string): Response { + return jsonResponse(status, { code, message: sanitizeErrorMessage(message) }); +} + +function extractBearer(request: Request): string | null { + const header = request.headers.get("authorization") ?? ""; + const match = /^Bearer\s+(.+)$/i.exec(header.trim()); + return match ? match[1].trim() : null; +} + +function secretKey(secret: string): Uint8Array { + return new TextEncoder().encode(secret); +} + +export function normalizeCursorCliPath(segments: readonly string[]): string { + return "/" + segments.map((segment) => encodeURIComponent(decodeURIComponent(segment))).join("/"); +} + +async function authenticateExchange( + request: Request, + deps: CursorCliProxyDeps +): Promise { + const bearer = extractBearer(request); + if (bearer && (await deps.validateApiKey(bearer))) { + const meta = await deps.getApiKeyMetadata(bearer); + return { apiKeyId: meta?.id ?? null, apiKeyName: meta?.name ?? null }; + } + if (!deps.requireApiKey()) { + return { apiKeyId: null, apiKeyName: null }; + } + return connectError( + HTTP_STATUS.UNAUTHORIZED, + "unauthenticated", + "CURSOR_API_KEY must be an OmniRoute API key when OmniRoute requires API keys" + ); +} + +export async function mintCursorCliSessionToken( + principal: CursorCliPrincipal, + secret: string, + nowMs: number +): Promise { + const nowSeconds = Math.floor(nowMs / 1000); + return new SignJWT({ name: principal.apiKeyName }) + .setProtectedHeader({ alg: "HS256", typ: "JWT" }) + .setIssuer(CURSOR_CLI_SESSION_ISSUER) + .setAudience(CURSOR_CLI_SESSION_AUDIENCE) + .setSubject(principal.apiKeyId ?? ANONYMOUS_SUBJECT) + .setIssuedAt(nowSeconds) + .setExpirationTime(nowSeconds + CURSOR_CLI_SESSION_TTL_SECONDS) + .sign(secretKey(secret)); +} + +async function verifyCursorCliSessionToken( + token: string, + secret: string, + nowMs: number +): Promise { + let payload: JWTPayload; + try { + ({ payload } = await jwtVerify(token, secretKey(secret), { + issuer: CURSOR_CLI_SESSION_ISSUER, + audience: CURSOR_CLI_SESSION_AUDIENCE, + currentDate: new Date(nowMs), + })); + } catch { + return null; + } + const claims = sessionClaimsSchema.safeParse(payload); + if (!claims.success) return null; + return { + apiKeyId: claims.data.sub === ANONYMOUS_SUBJECT ? null : claims.data.sub, + apiKeyName: claims.data.name ?? null, + }; +} + +async function isPrincipalStillValid( + principal: CursorCliPrincipal, + deps: CursorCliProxyDeps +): Promise { + if (!principal.apiKeyId) return !deps.requireApiKey(); + const row = await deps.getApiKeyById(principal.apiKeyId); + if (!row) return false; + if (row.isActive === false) return false; + return !(typeof row.revokedAt === "string" && row.revokedAt.trim() !== ""); +} + +type ResolvedConnection = { + connectionId: string | null; + bearer: string; + apiKey: string | null; +}; + +function connectionPriority(connection: CursorCliConnectionLike): number { + return typeof connection.priority === "number" ? connection.priority : Number.MAX_SAFE_INTEGER; +} + +function isCoolingDown(connection: CursorCliConnectionLike, nowMs: number): boolean { + if (typeof connection.rateLimitedUntil !== "string") return false; + const until = Date.parse(connection.rateLimitedUntil); + return Number.isFinite(until) && until > nowMs; +} + +async function resolveUpstreamConnection( + deps: CursorCliProxyDeps +): Promise { + const connections = (await deps.listCursorConnections()) + .filter((connection) => !isCoolingDown(connection, deps.now())) + .sort((a, b) => connectionPriority(a) - connectionPriority(b)); + if (connections.length === 0) { + return connectError( + HTTP_STATUS.SERVICE_UNAVAILABLE, + "unavailable", + "No active Cursor API connection configured in OmniRoute" + ); + } + let lastError: unknown = null; + for (const connection of connections) { + const apiKey = isCursorApiKey(connection.apiKey) ? connection.apiKey : null; + const accessToken = typeof connection.accessToken === "string" ? connection.accessToken : null; + try { + const bearer = await deps.resolveBearer({ apiKey, accessToken }); + return { + connectionId: typeof connection.id === "string" ? connection.id : null, + bearer, + apiKey, + }; + } catch (err) { + lastError = err; + } + } + const status = + lastError instanceof CursorApiKeyExchangeError ? lastError.status : HTTP_STATUS.BAD_GATEWAY; + const message = lastError instanceof Error ? lastError.message : "Cursor credential unavailable"; + return connectError( + status, + status === HTTP_STATUS.UNAUTHORIZED ? "unauthenticated" : "unavailable", + message + ); +} + +function buildUpstreamHeaders(request: Request, bearer: string): Headers { + const headers = new Headers(); + request.headers.forEach((value, name) => { + if (!REQUEST_HEADER_DENYLIST.has(name.toLowerCase())) headers.set(name, value); + }); + headers.set("authorization", `Bearer ${bearer}`); + return headers; +} + +function buildDownstreamHeaders(upstream: Response): Headers { + const headers = new Headers(); + upstream.headers.forEach((value, name) => { + if (!RESPONSE_HEADER_DENYLIST.has(name.toLowerCase())) headers.set(name, value); + }); + return headers; +} + +type CallLogInput = { + method: string; + path: string; + status: number; + startedAt: number; + principal: CursorCliPrincipal | null; + connectionId: string | null; + error?: string | null; +}; + +function recordCall(deps: CursorCliProxyDeps, input: CallLogInput): void { + void deps + .saveCallLog({ + method: input.method, + path: `${CURSOR_CLI_PROXY_PREFIX}${input.path}`, + status: input.status, + model: "-", + provider: PROVIDER_ID, + connectionId: input.connectionId, + duration: Math.max(0, deps.now() - input.startedAt), + apiKeyId: input.principal?.apiKeyId ?? null, + apiKeyName: input.principal?.apiKeyName ?? null, + requestType: CURSOR_CLI_REQUEST_TYPE, + sourceFormat: CURSOR_CLI_REQUEST_TYPE, + targetFormat: CURSOR_CLI_REQUEST_TYPE, + error: input.error ? { message: sanitizeErrorMessage(input.error) } : null, + }) + .catch(() => undefined); +} + +function streamWithCompletionLog( + body: ReadableStream, + onDone: (error?: string) => void +): ReadableStream { + const reader = body.getReader(); + let settled = false; + const settle = (error?: string) => { + if (settled) return; + settled = true; + onDone(error); + }; + return new ReadableStream({ + async pull(controller) { + try { + const { done, value } = await reader.read(); + if (done) { + settle(); + controller.close(); + return; + } + controller.enqueue(value); + } catch (err) { + settle(err instanceof Error ? err.message : "upstream stream failed"); + controller.error(err); + } + }, + cancel(reason) { + settle(reason instanceof Error ? reason.message : "stream cancelled"); + return reader.cancel(reason); + }, + }); +} + +async function handleExchange( + request: Request, + startedAt: number, + deps: CursorCliProxyDeps +): Promise { + if (request.method !== "POST") { + return connectError(405, "unimplemented", "Use POST"); + } + const rawBody = await request.text(); + if (rawBody.trim().length > 0) { + let parsed: unknown; + try { + parsed = JSON.parse(rawBody); + } catch { + return connectError(HTTP_STATUS.BAD_REQUEST, "invalid_argument", "Body must be JSON"); + } + if (!exchangeBodySchema.safeParse(parsed).success) { + return connectError( + HTTP_STATUS.BAD_REQUEST, + "invalid_argument", + "Body must be a JSON object" + ); + } + } + + const principal = await authenticateExchange(request, deps); + if (principal instanceof Response) { + recordCall(deps, { + method: request.method, + path: CURSOR_API_KEY_EXCHANGE_PATH, + status: principal.status, + startedAt, + principal: null, + connectionId: null, + error: "OmniRoute API key rejected", + }); + return principal; + } + + const secret = deps.getSecret(); + if (!secret || secret.trim().length === 0) { + return connectError( + HTTP_STATUS.SERVICE_UNAVAILABLE, + "unavailable", + "JWT_SECRET is not configured; the Cursor CLI passthrough cannot mint session tokens" + ); + } + + const token = await mintCursorCliSessionToken(principal, secret, deps.now()); + recordCall(deps, { + method: request.method, + path: CURSOR_API_KEY_EXCHANGE_PATH, + status: 200, + startedAt, + principal, + connectionId: null, + }); + return jsonResponse(200, { accessToken: token, refreshToken: token }); +} + +async function handleForward( + request: Request, + path: string, + startedAt: number, + deps: CursorCliProxyDeps +): Promise { + const secret = deps.getSecret(); + const bearer = extractBearer(request); + const principal = + bearer && secret ? await verifyCursorCliSessionToken(bearer, secret, deps.now()) : null; + if (!principal || !(await isPrincipalStillValid(principal, deps))) { + return connectError( + HTTP_STATUS.UNAUTHORIZED, + "unauthenticated", + "Missing or expired OmniRoute Cursor CLI session token" + ); + } + + const resolved = await resolveUpstreamConnection(deps); + if (resolved instanceof Response) { + recordCall(deps, { + method: request.method, + path, + status: resolved.status, + startedAt, + principal, + connectionId: null, + error: "No usable Cursor connection", + }); + return resolved; + } + + const search = new URL(request.url).search; + const upstreamUrl = `${deps.upstreamBaseUrl}${path}${search}`; + const hasBody = request.method !== "GET" && request.method !== "HEAD"; + let upstream: Response; + try { + upstream = await deps.fetchImpl(upstreamUrl, { + method: request.method, + headers: buildUpstreamHeaders(request, resolved.bearer), + body: hasBody ? request.body : undefined, + signal: request.signal, + redirect: "manual", + ...(hasBody ? { duplex: "half" } : {}), + } as RequestInit); + } catch (err) { + const message = err instanceof Error ? err.message : "upstream request failed"; + recordCall(deps, { + method: request.method, + path, + status: HTTP_STATUS.BAD_GATEWAY, + startedAt, + principal, + connectionId: resolved.connectionId, + error: message, + }); + return connectError(HTTP_STATUS.BAD_GATEWAY, "unavailable", message); + } + + if (upstream.status === HTTP_STATUS.UNAUTHORIZED && resolved.apiKey) { + deps.invalidateBearer(resolved.apiKey); + } + + const logInput: CallLogInput = { + method: request.method, + path, + status: upstream.status, + startedAt, + principal, + connectionId: resolved.connectionId, + }; + const headers = buildDownstreamHeaders(upstream); + if (!upstream.body) { + recordCall(deps, logInput); + return new Response(null, { status: upstream.status, headers }); + } + const body = streamWithCompletionLog(upstream.body, (error) => + recordCall(deps, { ...logInput, error: error ?? null }) + ); + return new Response(body, { status: upstream.status, headers }); +} + +export async function handleCursorCliProxy( + request: Request, + segments: readonly string[], + overrides: Partial = {} +): Promise { + const deps: CursorCliProxyDeps = { ...defaultDeps, ...overrides }; + const startedAt = deps.now(); + const path = normalizeCursorCliPath(segments); + if (path === CURSOR_API_KEY_EXCHANGE_PATH) { + return handleExchange(request, startedAt, deps); + } + return handleForward(request, path, startedAt, deps); +} diff --git a/open-sse/services/cursorApiKeyAuth.ts b/open-sse/services/cursorApiKeyAuth.ts new file mode 100644 index 0000000000..60c3385783 --- /dev/null +++ b/open-sse/services/cursorApiKeyAuth.ts @@ -0,0 +1,198 @@ +/** + * Cursor user API keys (`crsr_โ€ฆ`, minted at cursor.com/dashboard/api) are not + * accepted as a Bearer credential by api2.cursor.sh (401). cursor-agent first + * POSTs the key to `/auth/exchange_user_api_key` and receives a 1-hour session + * JWT (`type: "api_key_token"`); the accompanying refreshToken carries the same + * `exp`, so "refresh" simply means re-exchanging the key. This module owns that + * exchange plus a per-key cache so the executor and the Cursor CLI passthrough + * share one live session token per key. + */ + +import crypto from "node:crypto"; + +export const CURSOR_API_BASE_URL = "https://api2.cursor.sh"; +export const CURSOR_API_KEY_PREFIX = "crsr_"; +export const CURSOR_API_KEY_EXCHANGE_PATH = "/auth/exchange_user_api_key"; +export const CURSOR_API_KEY_EXCHANGE_URL = `${CURSOR_API_BASE_URL}${CURSOR_API_KEY_EXCHANGE_PATH}`; + +const REFRESH_SKEW_MS = 5 * 60 * 1000; +const FALLBACK_TTL_MS = 55 * 60 * 1000; +const EXCHANGE_TIMEOUT_MS = 15_000; + +export type CursorSessionToken = { + accessToken: string; + refreshToken: string | null; + expiresAt: number; +}; + +export class CursorApiKeyExchangeError extends Error { + readonly status: number; + + constructor(message: string, status: number) { + super(message); + this.name = "CursorApiKeyExchangeError"; + this.status = status; + } +} + +type FetchLike = (input: string, init?: RequestInit) => Promise; + +export type CursorApiKeyAuthOptions = { + fetchImpl?: FetchLike; + signal?: AbortSignal; + now?: () => number; +}; + +const sessionCache = new Map(); +const inflightExchanges = new Map>(); + +export function isCursorApiKey(value: unknown): value is string { + return typeof value === "string" && value.startsWith(CURSOR_API_KEY_PREFIX); +} + +function cacheKeyFor(apiKey: string): string { + return crypto.createHash("sha256").update(apiKey).digest("hex"); +} + +export function readJwtExpiryMs(token: string): number | null { + const parts = token.split("."); + if (parts.length !== 3) return null; + try { + const payload = JSON.parse(Buffer.from(parts[1], "base64url").toString("utf8")) as { + exp?: unknown; + }; + return typeof payload.exp === "number" && Number.isFinite(payload.exp) + ? payload.exp * 1000 + : null; + } catch { + return null; + } +} + +function parseExchangeBody(raw: string): { accessToken: string; refreshToken: string | null } { + let parsed: unknown; + try { + parsed = JSON.parse(raw); + } catch { + throw new CursorApiKeyExchangeError("Cursor API key exchange returned a non-JSON body", 502); + } + if (!parsed || typeof parsed !== "object") { + throw new CursorApiKeyExchangeError("Cursor API key exchange returned an empty body", 502); + } + const { accessToken, refreshToken } = parsed as { accessToken?: unknown; refreshToken?: unknown }; + if (typeof accessToken !== "string" || accessToken.length === 0) { + throw new CursorApiKeyExchangeError("Cursor API key exchange returned no accessToken", 502); + } + return { + accessToken, + refreshToken: typeof refreshToken === "string" && refreshToken.length > 0 ? refreshToken : null, + }; +} + +export async function exchangeCursorApiKey( + apiKey: string, + options: CursorApiKeyAuthOptions = {} +): Promise { + if (!isCursorApiKey(apiKey)) { + throw new CursorApiKeyExchangeError( + `Cursor API keys start with "${CURSOR_API_KEY_PREFIX}"`, + 400 + ); + } + const fetchImpl = options.fetchImpl ?? fetch; + const now = options.now ?? Date.now; + const signal = options.signal ?? AbortSignal.timeout(EXCHANGE_TIMEOUT_MS); + + let response: Response; + try { + response = await fetchImpl(CURSOR_API_KEY_EXCHANGE_URL, { + method: "POST", + headers: { + authorization: `Bearer ${apiKey}`, + "content-type": "application/json", + accept: "application/json", + }, + body: "{}", + signal, + }); + } catch { + throw new CursorApiKeyExchangeError("Cursor API key exchange request failed", 502); + } + + if (response.status === 401 || response.status === 403) { + throw new CursorApiKeyExchangeError("Cursor rejected the API key", 401); + } + if (!response.ok) { + throw new CursorApiKeyExchangeError( + `Cursor API key exchange failed with HTTP ${response.status}`, + response.status >= 500 ? 502 : response.status + ); + } + + const { accessToken, refreshToken } = parseExchangeBody(await response.text()); + const expiresAt = readJwtExpiryMs(accessToken) ?? now() + FALLBACK_TTL_MS; + return { accessToken, refreshToken, expiresAt }; +} + +function isFresh(token: CursorSessionToken, nowMs: number): boolean { + return token.expiresAt - REFRESH_SKEW_MS > nowMs; +} + +export async function resolveCursorSessionToken( + apiKey: string, + options: CursorApiKeyAuthOptions = {} +): Promise { + const now = options.now ?? Date.now; + const key = cacheKeyFor(apiKey); + const cached = sessionCache.get(key); + if (cached && isFresh(cached, now())) return cached; + + const pending = inflightExchanges.get(key); + if (pending) return pending; + + const exchange = exchangeCursorApiKey(apiKey, options) + .then((token) => { + sessionCache.set(key, token); + return token; + }) + .finally(() => { + inflightExchanges.delete(key); + }); + inflightExchanges.set(key, exchange); + return exchange; +} + +export function invalidateCursorSessionToken(apiKey: string): void { + sessionCache.delete(cacheKeyFor(apiKey)); +} + +export function stripCursorOAuthTokenPrefix(accessToken: string): string { + return accessToken.includes("::") ? accessToken.split("::")[1] : accessToken; +} + +export type CursorBearerCredentials = { + apiKey?: string | null; + accessToken?: string | null; +}; + +export async function resolveCursorBearerToken( + credentials: CursorBearerCredentials, + options: CursorApiKeyAuthOptions = {} +): Promise { + if (isCursorApiKey(credentials.apiKey)) { + const session = await resolveCursorSessionToken(credentials.apiKey, options); + return session.accessToken; + } + if (typeof credentials.accessToken === "string" && credentials.accessToken.length > 0) { + return stripCursorOAuthTokenPrefix(credentials.accessToken); + } + throw new CursorApiKeyExchangeError( + "Cursor connection has neither an API key nor a session token", + 401 + ); +} + +export function __resetCursorApiKeyAuthForTest(): void { + sessionCache.clear(); + inflightExchanges.clear(); +} diff --git a/package.json b/package.json index 64d600aa04..5a235fec3b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "omniroute", "version": "3.8.50", - "description": "Unified AI router with 341 providers, RTK+Caveman compression, auto fallback, MCP/A2A, desktop, PWA, and OpenAI-compatible APIs.", + "description": "Unified AI router with 342 providers, RTK+Caveman compression, auto fallback, MCP/A2A, desktop, PWA, and OpenAI-compatible APIs.", "type": "module", "bin": { "omniroute": "bin/omniroute.mjs", diff --git a/src/app/api/cursor-cli/[...path]/route.ts b/src/app/api/cursor-cli/[...path]/route.ts new file mode 100644 index 0000000000..04d53d194f --- /dev/null +++ b/src/app/api/cursor-cli/[...path]/route.ts @@ -0,0 +1,14 @@ +import { handleCursorCliProxy } from "@omniroute/open-sse/handlers/cursorCliProxy.ts"; + +export const runtime = "nodejs"; +export const dynamic = "force-dynamic"; + +type RouteContext = { params: Promise<{ path: string[] }> }; + +async function proxy(request: Request, context: RouteContext): Promise { + const { path } = await context.params; + return handleCursorCliProxy(request, path ?? []); +} + +export const GET = proxy; +export const POST = proxy; diff --git a/src/i18n/messages/en.json b/src/i18n/messages/en.json index 4a67320eab..c0ac56dc49 100644 --- a/src/i18n/messages/en.json +++ b/src/i18n/messages/en.json @@ -6220,6 +6220,7 @@ "claude": "Connect Claude Code with the existing OAuth flow.", "cline": "Connect Cline with the existing OAuth flow.", "cursor": "Connect Cursor IDE with the existing OAuth flow.", + "cursor-api": "Connect Cursor with a user API key (crsr_...) from cursor.com/dashboard/api; no IDE session needed.", "github": "Connect GitHub Copilot with the existing OAuth flow.", "gitlab-duo": "OAuth application with ai_features + read_user scopes. Configure GITLAB_DUO_OAUTH_CLIENT_ID and optionally GITLAB_DUO_OAUTH_CLIENT_SECRET on this OmniRoute instance.", "kilocode": "Connect Kilo Code with the existing OAuth flow.", diff --git a/src/lib/providers/validation.ts b/src/lib/providers/validation.ts index d5986d2419..df29569f8b 100644 --- a/src/lib/providers/validation.ts +++ b/src/lib/providers/validation.ts @@ -112,6 +112,7 @@ import { validateAdobeFireflyProvider } from "./validation/adobeFirefly"; import { validateV0VercelProvider, validateAuggieProvider, + validateCursorApiProvider, validateQoderProvider, validateKiroProvider, validateGitlabProvider, @@ -185,6 +186,7 @@ export async function validateProviderApiKey({ provider, apiKey, providerSpecifi // for parity with the "jules" cloud-agent entry above โ€” see #6142. devin: validateDevinCloudAgentProvider, auggie: validateAuggieProvider, + "cursor-api": validateCursorApiProvider, aihorde: validateAiHordeProvider, // #10522: registered under both the canonical id and the short alias โ€” Firefly // connections are commonly stored as "firefly" (same prefix as firefly/ diff --git a/src/lib/providers/validation/specialtyInline.ts b/src/lib/providers/validation/specialtyInline.ts index 191902d290..7729fa4554 100644 --- a/src/lib/providers/validation/specialtyInline.ts +++ b/src/lib/providers/validation/specialtyInline.ts @@ -61,6 +61,28 @@ export async function validateAuggieProvider() { return { valid: true, error: null, unsupported: false, method: result.version }; } +export async function validateCursorApiProvider({ apiKey }: { apiKey?: string }) { + const { exchangeCursorApiKey, CursorApiKeyExchangeError, isCursorApiKey } = + await import("@omniroute/open-sse/services/cursorApiKeyAuth.ts"); + const key = (apiKey || "").trim(); + if (!isCursorApiKey(key)) { + return { + valid: false, + error: "Cursor user API keys start with crsr_ (cursor.com/dashboard/api)", + unsupported: false, + statusCode: 400, + }; + } + try { + await exchangeCursorApiKey(key); + return { valid: true, error: null, unsupported: false, method: "exchange_user_api_key" }; + } catch (error) { + const statusCode = error instanceof CursorApiKeyExchangeError ? error.status : 502; + const message = error instanceof Error ? error.message : "Cursor API key exchange failed"; + return { valid: false, error: message, unsupported: false, statusCode }; + } +} + export async function validateQoderProvider({ apiKey, providerSpecificData }: any) { // Bifurcate validation: PAT tokens use Cosy auth against api1.qoder.sh; // regular API keys validate against dashscope (OpenAI-compatible endpoint). diff --git a/src/shared/components/ProviderIcon.tsx b/src/shared/components/ProviderIcon.tsx index bdd50292a1..9e3524561a 100644 --- a/src/shared/components/ProviderIcon.tsx +++ b/src/shared/components/ProviderIcon.tsx @@ -240,6 +240,7 @@ const KNOWN_SVGS = new Set([ ]); const LOCAL_SVG_ALIASES: Record = { + "cursor-api": "cursor", "qwen-cloud": "qwencloud", "qwen-cloud-token-plan": "qwencloud", }; diff --git a/src/shared/constants/providers.ts b/src/shared/constants/providers.ts index d50c63e32a..0ae41d9532 100644 --- a/src/shared/constants/providers.ts +++ b/src/shared/constants/providers.ts @@ -146,8 +146,7 @@ export const AGGREGATOR_PROVIDER_IDS = new Set([ "free-ai", "void-ai", "helixmind", - -]);; +]); export const ENTERPRISE_CLOUD_PROVIDER_IDS = new Set([ "azure-openai", diff --git a/src/shared/constants/providers/apikey/specialty-media.ts b/src/shared/constants/providers/apikey/specialty-media.ts index 88a5049b2b..e66e97bc2b 100644 --- a/src/shared/constants/providers/apikey/specialty-media.ts +++ b/src/shared/constants/providers/apikey/specialty-media.ts @@ -305,4 +305,19 @@ export const APIKEY_PROVIDERS_SPECIALTY = { apiHint: "DeepAI uses per-endpoint REST calls (e.g. /api/text2img) instead of OpenAI chat/completions. OmniRoute adapts OpenAI image generation requests to DeepAI's /api/{slug} endpoints.", }, + "cursor-api": { + id: "cursor-api", + alias: "cua", + name: "Cursor API", + icon: "edit_note", + color: "#00D4AA", + textIcon: "CA", + website: "https://cursor.com/dashboard/api", + subscriptionRisk: true, + riskNoticeVariant: "oauth", + authHint: + "Paste a Cursor user API key (crsr_...) from cursor.com/dashboard/api. OmniRoute exchanges it for a session token on demand; no IDE or cursor-agent install is needed. Usage bills to the Cursor plan that owns the key.", + apiHint: + "Same agent protocol and model catalog as the Cursor IDE provider. The Cursor CLI can also be pointed at /api/cursor-cli on this instance and authenticated with an OmniRoute API key.", + }, }; diff --git a/src/shared/constants/publicApiRoutes.ts b/src/shared/constants/publicApiRoutes.ts index 07d8610adf..3de4c9a5be 100644 --- a/src/shared/constants/publicApiRoutes.ts +++ b/src/shared/constants/publicApiRoutes.ts @@ -30,6 +30,12 @@ const PUBLIC_API_ROUTE_PREFIXES = [ // auth (503 when TELEGRAM_BOT_TOKEN is unset; 401 on invalid initData // HMAC). See src/app/api/telegram/update/route.ts. Do not widen. "/api/telegram/", + // Cursor CLI passthrough (CURSOR_API_ENDPOINT -> OmniRoute -> api2.cursor.sh). + // The handler enforces its own auth: /auth/exchange_user_api_key requires an + // OmniRoute API key (validateApiKey); every other path requires the + // OmniRoute-minted session JWT that exchange returns. See + // open-sse/handlers/cursorCliProxy.ts. Do not widen. + "/api/cursor-cli/", ]; const PUBLIC_READONLY_API_ROUTE_PREFIXES = [ diff --git a/tests/snapshots/executors/executor-map.json b/tests/snapshots/executors/executor-map.json index d0ce4024b5..ffe64f9429 100644 --- a/tests/snapshots/executors/executor-map.json +++ b/tests/snapshots/executors/executor-map.json @@ -190,11 +190,21 @@ "configSource": "cursor", "provider": "cursor" }, + "cua": { + "className": "CursorExecutor", + "configSource": "cursor-api", + "provider": "cursor-api" + }, "cursor": { "className": "CursorExecutor", "configSource": "cursor", "provider": "cursor" }, + "cursor-api": { + "className": "CursorExecutor", + "configSource": "cursor-api", + "provider": "cursor-api" + }, "cw-web": { "className": "ClaudeWebExecutor", "configSource": "", @@ -686,6 +696,6 @@ "provider": "zai-web" } }, - "keyCount": 137, + "keyCount": 139, "sharedInstances": [] } diff --git a/tests/unit/cursor-api-key-auth.test.ts b/tests/unit/cursor-api-key-auth.test.ts new file mode 100644 index 0000000000..d5517c1e5b --- /dev/null +++ b/tests/unit/cursor-api-key-auth.test.ts @@ -0,0 +1,227 @@ +/** + * Cursor API-key exchange (open-sse/services/cursorApiKeyAuth.ts). + * + * api2.cursor.sh rejects a raw `crsr_โ€ฆ` key as Bearer; cursor-agent exchanges + * it at /auth/exchange_user_api_key for a 1h session JWT. These tests pin the + * exchange request shape, the 401/5xx/malformed-body mapping, the per-key + * cache (refresh 5 min before exp, in-flight dedupe, invalidation) and the + * shared bearer resolver used by the executor and the CLI passthrough. + */ +import { describe, it, beforeEach } from "node:test"; +import assert from "node:assert/strict"; + +import { + CURSOR_API_KEY_EXCHANGE_URL, + CursorApiKeyExchangeError, + __resetCursorApiKeyAuthForTest, + exchangeCursorApiKey, + invalidateCursorSessionToken, + isCursorApiKey, + readJwtExpiryMs, + resolveCursorBearerToken, + resolveCursorSessionToken, + stripCursorOAuthTokenPrefix, +} from "@omniroute/open-sse/services/cursorApiKeyAuth.ts"; + +const API_KEY = "crsr_test_key_0123456789"; + +function jwtWithExp(expSeconds: number): string { + const b64 = (value: object) => Buffer.from(JSON.stringify(value)).toString("base64url"); + return `${b64({ alg: "HS256", typ: "JWT" })}.${b64({ exp: expSeconds, type: "api_key_token" })}.sig`; +} + +type RecordedCall = { url: string; init: RequestInit | undefined }; + +function fakeFetch( + responder: (call: RecordedCall) => Response, + calls: RecordedCall[] = [] +): { fetchImpl: (url: string, init?: RequestInit) => Promise; calls: RecordedCall[] } { + return { + calls, + fetchImpl: async (url, init) => { + const call = { url, init }; + calls.push(call); + return responder(call); + }, + }; +} + +function okExchange(expSeconds: number): Response { + return new Response( + JSON.stringify({ accessToken: jwtWithExp(expSeconds), refreshToken: jwtWithExp(expSeconds) }), + { status: 200, headers: { "content-type": "application/json" } } + ); +} + +describe("cursorApiKeyAuth", () => { + beforeEach(() => { + __resetCursorApiKeyAuthForTest(); + }); + + it("recognises crsr_ keys only", () => { + assert.equal(isCursorApiKey(API_KEY), true); + assert.equal(isCursorApiKey("sk-other"), false); + assert.equal(isCursorApiKey(undefined), false); + }); + + it("reads exp from a JWT and returns null for opaque tokens", () => { + assert.equal(readJwtExpiryMs(jwtWithExp(1_800_000_000)), 1_800_000_000_000); + assert.equal(readJwtExpiryMs("opaque"), null); + }); + + it("strips the WorkOS composite prefix from OAuth session tokens only", () => { + assert.equal(stripCursorOAuthTokenPrefix("user_123::jwt.part.sig"), "jwt.part.sig"); + assert.equal(stripCursorOAuthTokenPrefix("jwt.part.sig"), "jwt.part.sig"); + }); + + it("POSTs the key as Bearer to the exchange endpoint and parses the session", async () => { + const exp = Math.floor(Date.now() / 1000) + 3600; + const { fetchImpl, calls } = fakeFetch(() => okExchange(exp)); + + const session = await exchangeCursorApiKey(API_KEY, { fetchImpl }); + + assert.equal(calls.length, 1); + assert.equal(calls[0].url, CURSOR_API_KEY_EXCHANGE_URL); + assert.equal(calls[0].init?.method, "POST"); + const headers = calls[0].init?.headers as Record; + assert.equal(headers.authorization, `Bearer ${API_KEY}`); + assert.equal(headers["content-type"], "application/json"); + assert.equal(calls[0].init?.body, "{}"); + assert.equal(session.accessToken, jwtWithExp(exp)); + assert.equal(session.expiresAt, exp * 1000); + }); + + it("rejects non-crsr keys without calling upstream", async () => { + const { fetchImpl, calls } = fakeFetch(() => okExchange(1)); + await assert.rejects( + exchangeCursorApiKey("sk-not-cursor", { fetchImpl }), + (err: unknown) => err instanceof CursorApiKeyExchangeError && err.status === 400 + ); + assert.equal(calls.length, 0); + }); + + it("maps upstream 401/403 to a 401 exchange error", async () => { + for (const status of [401, 403]) { + const { fetchImpl } = fakeFetch(() => new Response("nope", { status })); + await assert.rejects( + exchangeCursorApiKey(API_KEY, { fetchImpl }), + (err: unknown) => + err instanceof CursorApiKeyExchangeError && + err.status === 401 && + !err.message.includes(API_KEY) + ); + } + }); + + it("maps upstream 5xx and malformed bodies to 502", async () => { + const cases: Array<() => Response> = [ + () => new Response("boom", { status: 503 }), + () => new Response("not json", { status: 200 }), + () => new Response(JSON.stringify({ refreshToken: "x" }), { status: 200 }), + ]; + for (const responder of cases) { + const { fetchImpl } = fakeFetch(responder); + await assert.rejects( + exchangeCursorApiKey(API_KEY, { fetchImpl }), + (err: unknown) => err instanceof CursorApiKeyExchangeError && err.status === 502 + ); + } + }); + + it("maps network failures to 502", async () => { + const fetchImpl = async () => { + throw new Error("ECONNRESET"); + }; + await assert.rejects( + exchangeCursorApiKey(API_KEY, { fetchImpl }), + (err: unknown) => err instanceof CursorApiKeyExchangeError && err.status === 502 + ); + }); + + it("caches the session per key and re-exchanges 5 minutes before expiry", async () => { + let nowMs = 1_000_000_000_000; + const now = () => nowMs; + const { fetchImpl, calls } = fakeFetch(() => okExchange(Math.floor(now() / 1000) + 3600)); + + const first = await resolveCursorSessionToken(API_KEY, { fetchImpl, now }); + const second = await resolveCursorSessionToken(API_KEY, { fetchImpl, now }); + assert.equal(calls.length, 1); + assert.equal(second.accessToken, first.accessToken); + + nowMs += 54 * 60 * 1000; + await resolveCursorSessionToken(API_KEY, { fetchImpl, now }); + assert.equal(calls.length, 1, "still fresh at 54 min"); + + nowMs += 2 * 60 * 1000; + const refreshed = await resolveCursorSessionToken(API_KEY, { fetchImpl, now }); + assert.equal(calls.length, 2, "re-exchanged inside the 5 min skew window"); + assert.notEqual(refreshed.accessToken, first.accessToken); + }); + + it("dedupes concurrent exchanges for the same key", async () => { + let release: (() => void) | null = null; + const gate = new Promise((resolve) => { + release = resolve; + }); + const { fetchImpl, calls } = fakeFetch(() => okExchange(Math.floor(Date.now() / 1000) + 3600)); + const gatedFetch = async (url: string, init?: RequestInit) => { + await gate; + return fetchImpl(url, init); + }; + + const pending = Promise.all([ + resolveCursorSessionToken(API_KEY, { fetchImpl: gatedFetch }), + resolveCursorSessionToken(API_KEY, { fetchImpl: gatedFetch }), + resolveCursorSessionToken(API_KEY, { fetchImpl: gatedFetch }), + ]); + release?.(); + const tokens = await pending; + assert.equal(calls.length, 1); + assert.equal(new Set(tokens.map((t) => t.accessToken)).size, 1); + }); + + it("invalidation forces a fresh exchange on the next call", async () => { + const { fetchImpl, calls } = fakeFetch(() => okExchange(Math.floor(Date.now() / 1000) + 3600)); + await resolveCursorSessionToken(API_KEY, { fetchImpl }); + invalidateCursorSessionToken(API_KEY); + await resolveCursorSessionToken(API_KEY, { fetchImpl }); + assert.equal(calls.length, 2); + }); + + it("does not cache a failed exchange", async () => { + let attempt = 0; + const { fetchImpl } = fakeFetch(() => { + attempt += 1; + return attempt === 1 + ? new Response("down", { status: 503 }) + : okExchange(Math.floor(Date.now() / 1000) + 3600); + }); + await assert.rejects(resolveCursorSessionToken(API_KEY, { fetchImpl })); + const session = await resolveCursorSessionToken(API_KEY, { fetchImpl }); + assert.ok(session.accessToken.length > 0); + assert.equal(attempt, 2); + }); + + it("resolveCursorBearerToken prefers the exchanged token for API-key connections", async () => { + const exp = Math.floor(Date.now() / 1000) + 3600; + const { fetchImpl } = fakeFetch(() => okExchange(exp)); + const bearer = await resolveCursorBearerToken( + { apiKey: API_KEY, accessToken: "user_1::stale" }, + { fetchImpl } + ); + assert.equal(bearer, jwtWithExp(exp)); + }); + + it("resolveCursorBearerToken keeps the OAuth path untouched and rejects empty creds", async () => { + const { fetchImpl, calls } = fakeFetch(() => okExchange(1)); + assert.equal( + await resolveCursorBearerToken({ accessToken: "user_1::session.jwt.sig" }, { fetchImpl }), + "session.jwt.sig" + ); + assert.equal(calls.length, 0); + await assert.rejects( + resolveCursorBearerToken({}, { fetchImpl }), + (err: unknown) => err instanceof CursorApiKeyExchangeError && err.status === 401 + ); + }); +}); diff --git a/tests/unit/cursor-apikey-provider.test.ts b/tests/unit/cursor-apikey-provider.test.ts new file mode 100644 index 0000000000..b705d2fc93 --- /dev/null +++ b/tests/unit/cursor-apikey-provider.test.ts @@ -0,0 +1,176 @@ +/** + * `cursor-api` is the API-key sibling of the `cursor` (IDE session) provider: + * same executor, format and model catalog, its own registry/catalog entry so + * API-key and IDE-session connections never share renewal or dashboard + * semantics. The executor swaps the crsr_ key for the exchanged session token + * before dialing. + */ +import { describe, it, afterEach } from "node:test"; +import assert from "node:assert/strict"; + +const { APIKEY_PROVIDERS, OAUTH_PROVIDERS } = + await import("../../src/shared/constants/providers.ts"); +const { isManagedProviderConnectionId } = await import("../../src/lib/providers/catalog.ts"); +const { cursorProvider, cursor_apiProvider } = + await import("../../open-sse/config/providers/registry/cursor/index.ts"); +const { REGISTRY, generateAliasMap, getProviderCategory } = + await import("../../open-sse/config/providerRegistry.ts"); +const { CursorExecutor, getExecutor, hasSpecializedExecutor } = + await import("../../open-sse/executors/index.ts"); +const { __resetCursorApiKeyAuthForTest } = + await import("../../open-sse/services/cursorApiKeyAuth.ts"); +const { validateProviderApiKey } = await import("../../src/lib/providers/validation.ts"); + +const API_KEY = "crsr_provider_test_key"; + +function jwt(exp: number): string { + const b64 = (value: object) => Buffer.from(JSON.stringify(value)).toString("base64url"); + return `${b64({ alg: "HS256" })}.${b64({ exp })}.sig`; +} + +describe("cursor-api provider wiring", () => { + it("is a distinct API-key registry entry sharing the cursor executor, format and models", () => { + assert.equal(cursor_apiProvider.id, "cursor-api"); + assert.equal(cursor_apiProvider.authType, "apikey"); + assert.equal(cursor_apiProvider.format, cursorProvider.format); + assert.equal(cursor_apiProvider.baseUrl, cursorProvider.baseUrl); + assert.equal(cursor_apiProvider.models, cursorProvider.models); + assert.equal(REGISTRY["cursor-api"], cursor_apiProvider); + assert.equal(generateAliasMap()["cursor-api"], "cua"); + assert.equal(getProviderCategory("cursor-api"), "apikey"); + }); + + it("leaves the IDE cursor provider OAuth-only", () => { + assert.equal(cursorProvider.authType, "oauth"); + assert.equal(getProviderCategory("cursor"), "oauth"); + assert.ok(OAUTH_PROVIDERS.cursor); + assert.ok(!APIKEY_PROVIDERS.cursor); + }); + + it("has its own API-key catalog card admitted by the managed-connection gate", () => { + assert.ok(APIKEY_PROVIDERS["cursor-api"]); + assert.equal(APIKEY_PROVIDERS["cursor-api"].alias, "cua"); + assert.ok(!OAUTH_PROVIDERS["cursor-api"]); + assert.equal(isManagedProviderConnectionId("cursor-api"), true); + }); + + it("routes cursor-api and its alias to a CursorExecutor bound to the cursor-api id", () => { + for (const key of ["cursor-api", "cua"]) { + assert.equal(hasSpecializedExecutor(key), true, key); + const executor = getExecutor(key); + assert.ok(executor instanceof CursorExecutor, key); + assert.equal(executor.getProvider(), "cursor-api"); + } + assert.equal(getExecutor("cursor").getProvider(), "cursor"); + }); +}); + +describe("CursorExecutor credential resolution", () => { + const originalFetch = globalThis.fetch; + + afterEach(() => { + globalThis.fetch = originalFetch; + __resetCursorApiKeyAuthForTest(); + }); + + it("sends the stripped IDE session token for OAuth connections", () => { + const executor = new CursorExecutor(); + const headers = executor.buildHeaders({ + accessToken: "user_01::ide.session.jwt", + providerSpecificData: {}, + }); + assert.equal(headers.authorization, "Bearer ide.session.jwt"); + assert.equal(headers["x-cursor-client-type"], "cli"); + }); + + it("exchanges a crsr_ key and sends the session JWT, never the raw key", async () => { + const calls: string[] = []; + const exp = Math.floor(Date.now() / 1000) + 3600; + globalThis.fetch = (async (input: string | URL | Request) => { + calls.push(String(input)); + return new Response(JSON.stringify({ accessToken: jwt(exp), refreshToken: jwt(exp) }), { + status: 200, + headers: { "content-type": "application/json" }, + }); + }) as typeof fetch; + + const executor = new CursorExecutor("cursor-api"); + const resolved = await executor.resolveExecutionCredentials({ + apiKey: API_KEY, + providerSpecificData: {}, + }); + assert.ok(!(resolved instanceof Response)); + const headers = executor.buildHeaders(resolved); + assert.equal(headers.authorization, `Bearer ${jwt(exp)}`); + assert.ok(!headers.authorization.includes(API_KEY)); + assert.equal(calls.length, 1); + assert.match(calls[0], /\/auth\/exchange_user_api_key$/); + }); + + it("returns a sanitized 401 response when Cursor rejects the key", async () => { + globalThis.fetch = (async () => new Response("bad key", { status: 401 })) as typeof fetch; + const executor = new CursorExecutor("cursor-api"); + const resolved = await executor.resolveExecutionCredentials({ apiKey: API_KEY }); + assert.ok(resolved instanceof Response); + assert.equal(resolved.status, 401); + const body = (await resolved.json()) as { error: { message: string; type: string } }; + assert.equal(body.error.type, "authentication_error"); + assert.ok(!body.error.message.includes(API_KEY)); + assert.ok(!body.error.message.includes("at /")); + }); + + it("leaves OAuth credentials untouched without calling the exchange endpoint", async () => { + globalThis.fetch = (async () => { + throw new Error("exchange must not be called"); + }) as typeof fetch; + const executor = new CursorExecutor(); + const credentials = { accessToken: "user_01::ide.session.jwt" }; + const resolved = await executor.resolveExecutionCredentials(credentials); + assert.equal(resolved, credentials); + }); +}); + +describe("cursor-api connection test", () => { + const originalFetch = globalThis.fetch; + + afterEach(() => { + globalThis.fetch = originalFetch; + __resetCursorApiKeyAuthForTest(); + }); + + it("validates by exchanging the key and reports the exchange as the method", async () => { + let exchangeCalls = 0; + globalThis.fetch = (async () => { + exchangeCalls += 1; + return new Response(JSON.stringify({ accessToken: jwt(1_900_000_000), refreshToken: "r" }), { + status: 200, + headers: { "content-type": "application/json" }, + }); + }) as typeof fetch; + const result = await validateProviderApiKey({ provider: "cursor-api", apiKey: API_KEY }); + assert.equal(result.valid, true); + assert.equal(result.unsupported, false); + assert.equal(exchangeCalls, 1); + }); + + it("reports a rejected key as invalid (401), not as unsupported", async () => { + globalThis.fetch = (async () => new Response("nope", { status: 401 })) as typeof fetch; + const result = await validateProviderApiKey({ provider: "cursor-api", apiKey: API_KEY }); + assert.equal(result.valid, false); + assert.equal(result.unsupported, false); + assert.equal(result.statusCode, 401); + assert.ok(!String(result.error).includes(API_KEY)); + }); + + it("rejects keys without the crsr_ prefix locally", async () => { + globalThis.fetch = (async () => { + throw new Error("must not be called"); + }) as typeof fetch; + const result = await validateProviderApiKey({ + provider: "cursor-api", + apiKey: "sk-not-cursor", + }); + assert.equal(result.valid, false); + assert.equal(result.statusCode, 400); + }); +}); diff --git a/tests/unit/cursor-cli-proxy.test.ts b/tests/unit/cursor-cli-proxy.test.ts new file mode 100644 index 0000000000..88ea70457e --- /dev/null +++ b/tests/unit/cursor-cli-proxy.test.ts @@ -0,0 +1,417 @@ +/** + * Cursor CLI passthrough handler (open-sse/handlers/cursorCliProxy.ts). + * + * The handler is exercised through its dependency seam so no SQLite, no + * network and no JWT_SECRET env are needed: every collaborator (API-key + * validation, connection listing, bearer resolution, upstream fetch, call + * logging) is injected per test. + */ +import { describe, it } from "node:test"; +import assert from "node:assert/strict"; +import { SignJWT, decodeJwt } from "jose"; + +import { + CURSOR_CLI_PROXY_PREFIX, + CURSOR_CLI_REQUEST_TYPE, + CURSOR_CLI_SESSION_AUDIENCE, + CURSOR_CLI_SESSION_ISSUER, + CURSOR_CLI_SESSION_TTL_SECONDS, + handleCursorCliProxy, + mintCursorCliSessionToken, + normalizeCursorCliPath, + type CursorCliProxyDeps, +} from "@omniroute/open-sse/handlers/cursorCliProxy.ts"; +import { CursorApiKeyExchangeError } from "@omniroute/open-sse/services/cursorApiKeyAuth.ts"; + +const SECRET = "unit-test-jwt-secret-with-enough-entropy-0123456789"; +const OMNI_KEY = "sk-omniroute-unit-key"; +const CURSOR_KEY = "crsr_unit_cursor_key"; +const UPSTREAM = "https://upstream.example"; +const NOW = 1_800_000_000_000; + +type UpstreamCall = { url: string; init: RequestInit }; + +function makeDeps(overrides: Partial = {}): { + deps: Partial; + upstreamCalls: UpstreamCall[]; + logs: Record[]; +} { + const upstreamCalls: UpstreamCall[] = []; + const logs: Record[] = []; + const deps: Partial = { + fetchImpl: (async (url: string, init: RequestInit) => { + upstreamCalls.push({ url, init }); + return new Response("upstream-ok", { + status: 200, + headers: { "content-type": "application/proto", "content-encoding": "identity" }, + }); + }) as unknown as typeof fetch, + now: () => NOW, + getSecret: () => SECRET, + validateApiKey: async (key) => key === OMNI_KEY, + getApiKeyMetadata: async (key) => (key === OMNI_KEY ? { id: "key-1", name: "unit key" } : null), + getApiKeyById: async (id) => (id === "key-1" ? { isActive: true, revokedAt: null } : null), + requireApiKey: () => true, + listCursorConnections: async () => [{ id: "conn-1", apiKey: CURSOR_KEY, priority: 1 }], + resolveBearer: async ({ apiKey }) => + apiKey === CURSOR_KEY ? "cursor-session-jwt" : "oauth-jwt", + invalidateBearer: () => undefined, + saveCallLog: async (entry) => { + logs.push(entry); + }, + upstreamBaseUrl: UPSTREAM, + ...overrides, + }; + return { deps, upstreamCalls, logs }; +} + +function exchangeRequest(bearer: string | null, body = "{}"): Request { + return new Request("http://omniroute.local/api/cursor-cli/auth/exchange_user_api_key", { + method: "POST", + headers: { + ...(bearer ? { authorization: `Bearer ${bearer}` } : {}), + "content-type": "application/json", + }, + body, + }); +} + +function rpcRequest( + bearer: string | null, + path = "/aiserver.v1.DashboardService/GetMe", + body: BodyInit | null = new Uint8Array([0, 0, 0, 0, 0]) +): Request { + return new Request(`http://omniroute.local/api/cursor-cli${path}?x=1`, { + method: "POST", + headers: { + ...(bearer ? { authorization: `Bearer ${bearer}` } : {}), + "content-type": "application/proto", + "connect-protocol-version": "1", + host: "omniroute.local", + "accept-encoding": "gzip,br", + cookie: "auth_token=dashboard", + }, + body, + }); +} + +async function mintedToken(): Promise { + return mintCursorCliSessionToken({ apiKeyId: "key-1", apiKeyName: "unit key" }, SECRET, NOW); +} + +async function flushLogs(): Promise { + await new Promise((resolve) => setTimeout(resolve, 0)); +} + +describe("cursorCliProxy: path normalisation", () => { + it("joins catch-all segments into the upstream RPC path", () => { + assert.equal( + normalizeCursorCliPath(["aiserver.v1.DashboardService", "GetMe"]), + "/aiserver.v1.DashboardService/GetMe" + ); + assert.equal( + normalizeCursorCliPath(["auth", "exchange_user_api_key"]), + "/auth/exchange_user_api_key" + ); + assert.equal(normalizeCursorCliPath(["v1", "traces"]), "/v1/traces"); + }); + + it("re-encodes segments so encoded slashes and spaces cannot smuggle extra path", () => { + assert.equal(normalizeCursorCliPath(["%2Fetc", "x y"]), "/%2Fetc/x%20y"); + assert.equal(normalizeCursorCliPath(["a%2Fb"]), "/a%2Fb"); + }); +}); + +describe("cursorCliProxy: /auth/exchange_user_api_key", () => { + it("mints a 1h OmniRoute session JWT for a valid OmniRoute API key", async () => { + const { deps, logs } = makeDeps(); + const res = await handleCursorCliProxy( + exchangeRequest(OMNI_KEY), + ["auth", "exchange_user_api_key"], + deps + ); + assert.equal(res.status, 200); + const body = (await res.json()) as { accessToken: string; refreshToken: string }; + assert.equal(body.refreshToken, body.accessToken); + const claims = decodeJwt(body.accessToken); + assert.equal(claims.iss, CURSOR_CLI_SESSION_ISSUER); + assert.equal(claims.aud, CURSOR_CLI_SESSION_AUDIENCE); + assert.equal(claims.sub, "key-1"); + assert.equal(claims.exp, Math.floor(NOW / 1000) + CURSOR_CLI_SESSION_TTL_SECONDS); + assert.ok(!body.accessToken.includes(OMNI_KEY)); + await flushLogs(); + assert.equal(logs.length, 1); + assert.equal(logs[0].path, `${CURSOR_CLI_PROXY_PREFIX}/auth/exchange_user_api_key`); + assert.equal(logs[0].requestType, CURSOR_CLI_REQUEST_TYPE); + assert.equal(logs[0].apiKeyId, "key-1"); + }); + + it("rejects an unknown key with 401 when OmniRoute requires API keys", async () => { + const { deps } = makeDeps(); + const res = await handleCursorCliProxy( + exchangeRequest("sk-wrong"), + ["auth", "exchange_user_api_key"], + deps + ); + assert.equal(res.status, 401); + const body = (await res.json()) as { code: string; message: string }; + assert.equal(body.code, "unauthenticated"); + assert.ok(!body.message.includes("at /")); + }); + + it("falls back to an anonymous session when REQUIRE_API_KEY is off", async () => { + const { deps } = makeDeps({ requireApiKey: () => false }); + const res = await handleCursorCliProxy( + exchangeRequest("anything"), + ["auth", "exchange_user_api_key"], + deps + ); + assert.equal(res.status, 200); + const body = (await res.json()) as { accessToken: string }; + assert.equal(decodeJwt(body.accessToken).sub, "anonymous"); + }); + + it("returns 503 without minting when JWT_SECRET is missing", async () => { + const { deps } = makeDeps({ getSecret: () => undefined }); + const res = await handleCursorCliProxy( + exchangeRequest(OMNI_KEY), + ["auth", "exchange_user_api_key"], + deps + ); + assert.equal(res.status, 503); + }); + + it("rejects non-JSON and non-POST exchange calls", async () => { + const { deps } = makeDeps(); + const bad = await handleCursorCliProxy( + exchangeRequest(OMNI_KEY, "not-json"), + ["auth", "exchange_user_api_key"], + deps + ); + assert.equal(bad.status, 400); + const get = await handleCursorCliProxy( + new Request("http://omniroute.local/api/cursor-cli/auth/exchange_user_api_key", { + method: "GET", + }), + ["auth", "exchange_user_api_key"], + deps + ); + assert.equal(get.status, 405); + }); +}); + +describe("cursorCliProxy: forwarded RPCs", () => { + it("swaps the OmniRoute session token for the Cursor bearer and strips hop headers", async () => { + const { deps, upstreamCalls, logs } = makeDeps(); + const res = await handleCursorCliProxy( + rpcRequest(await mintedToken()), + ["aiserver.v1.DashboardService", "GetMe"], + deps + ); + assert.equal(res.status, 200); + assert.equal(await res.text(), "upstream-ok"); + assert.equal(res.headers.get("content-type"), "application/proto"); + assert.equal(res.headers.get("content-encoding"), null); + + assert.equal(upstreamCalls.length, 1); + assert.equal(upstreamCalls[0].url, `${UPSTREAM}/aiserver.v1.DashboardService/GetMe?x=1`); + const headers = upstreamCalls[0].init.headers as Headers; + assert.equal(headers.get("authorization"), "Bearer cursor-session-jwt"); + assert.equal(headers.get("connect-protocol-version"), "1"); + assert.equal(headers.get("host"), null); + assert.equal(headers.get("cookie"), null); + assert.equal(headers.get("accept-encoding"), null); + assert.equal(upstreamCalls[0].init.method, "POST"); + + await flushLogs(); + assert.equal(logs.length, 1); + assert.equal(logs[0].path, `${CURSOR_CLI_PROXY_PREFIX}/aiserver.v1.DashboardService/GetMe`); + assert.equal(logs[0].provider, "cursor-api"); + assert.equal(logs[0].connectionId, "conn-1"); + assert.equal(logs[0].status, 200); + assert.equal(logs[0].apiKeyId, "key-1"); + }); + + it("rejects a raw OmniRoute API key on RPC paths so the CLI exchanges first", async () => { + const { deps, upstreamCalls } = makeDeps(); + const res = await handleCursorCliProxy( + rpcRequest(OMNI_KEY), + ["aiserver.v1.DashboardService", "GetMe"], + deps + ); + assert.equal(res.status, 401); + assert.equal(upstreamCalls.length, 0); + }); + + it("rejects missing, expired, foreign-audience and tampered tokens with 401", async () => { + const { deps, upstreamCalls } = makeDeps(); + const expired = await mintCursorCliSessionToken( + { apiKeyId: "key-1", apiKeyName: null }, + SECRET, + NOW - (CURSOR_CLI_SESSION_TTL_SECONDS + 60) * 1000 + ); + const foreign = await new SignJWT({}) + .setProtectedHeader({ alg: "HS256" }) + .setIssuer(CURSOR_CLI_SESSION_ISSUER) + .setAudience("dashboard") + .setSubject("key-1") + .setExpirationTime(Math.floor(NOW / 1000) + 600) + .sign(new TextEncoder().encode(SECRET)); + const tampered = (await mintedToken()).slice(0, -4) + "AAAA"; + for (const token of [null, expired, foreign, tampered]) { + const res = await handleCursorCliProxy( + rpcRequest(token), + ["aiserver.v1.DashboardService", "GetMe"], + deps + ); + assert.equal(res.status, 401, `token=${token === null ? "none" : token.slice(0, 12)}`); + } + assert.equal(upstreamCalls.length, 0); + }); + + it("rejects a session whose OmniRoute API key was revoked or deactivated", async () => { + const revoked = makeDeps({ + getApiKeyById: async () => ({ isActive: true, revokedAt: "2026-01-01T00:00:00Z" }), + }); + const deactivated = makeDeps({ + getApiKeyById: async () => ({ isActive: false, revokedAt: null }), + }); + const gone = makeDeps({ getApiKeyById: async () => null }); + for (const { deps } of [revoked, deactivated, gone]) { + const res = await handleCursorCliProxy( + rpcRequest(await mintedToken()), + ["aiserver.v1.DashboardService", "GetMe"], + deps + ); + assert.equal(res.status, 401); + } + }); + + it("returns 503 when no active Cursor connection exists", async () => { + const { deps, logs } = makeDeps({ listCursorConnections: async () => [] }); + const res = await handleCursorCliProxy( + rpcRequest(await mintedToken()), + ["aiserver.v1.DashboardService", "GetMe"], + deps + ); + assert.equal(res.status, 503); + const body = (await res.json()) as { code: string; message: string }; + assert.equal(body.code, "unavailable"); + assert.ok(!body.message.includes("at /")); + await flushLogs(); + assert.equal(logs[0].status, 503); + }); + + it("skips cooling-down connections and falls through when a key cannot be exchanged", async () => { + const { deps, upstreamCalls } = makeDeps({ + listCursorConnections: async () => [ + { + id: "cooling", + apiKey: "crsr_cooling", + priority: 0, + rateLimitedUntil: new Date(NOW + 60_000).toISOString(), + }, + { id: "broken", apiKey: "crsr_broken", priority: 1 }, + { id: "oauth", accessToken: "user::session", priority: 2 }, + ], + resolveBearer: async ({ apiKey, accessToken }) => { + if (apiKey === "crsr_broken") + throw new CursorApiKeyExchangeError("Cursor rejected the API key", 401); + if (apiKey === "crsr_cooling") throw new Error("must not be used"); + return accessToken === "user::session" ? "oauth-jwt" : "unexpected"; + }, + }); + const res = await handleCursorCliProxy( + rpcRequest(await mintedToken()), + ["aiserver.v1.DashboardService", "GetMe"], + deps + ); + assert.equal(res.status, 200); + assert.equal( + (upstreamCalls[0].init.headers as Headers).get("authorization"), + "Bearer oauth-jwt" + ); + }); + + it("surfaces an exchange failure as 401 when no connection resolves", async () => { + const { deps } = makeDeps({ + resolveBearer: async () => { + throw new CursorApiKeyExchangeError("Cursor rejected the API key", 401); + }, + }); + const res = await handleCursorCliProxy( + rpcRequest(await mintedToken()), + ["aiserver.v1.DashboardService", "GetMe"], + deps + ); + assert.equal(res.status, 401); + const body = (await res.json()) as { code: string }; + assert.equal(body.code, "unauthenticated"); + }); + + it("invalidates the cached Cursor session when upstream answers 401", async () => { + const invalidated: string[] = []; + const { deps } = makeDeps({ + fetchImpl: (async () => new Response("expired", { status: 401 })) as unknown as typeof fetch, + invalidateBearer: (key) => { + invalidated.push(key); + }, + }); + const res = await handleCursorCliProxy( + rpcRequest(await mintedToken()), + ["aiserver.v1.DashboardService", "GetMe"], + deps + ); + assert.equal(res.status, 401); + assert.deepEqual(invalidated, [CURSOR_KEY]); + }); + + it("streams SSE bodies through and logs once when the stream completes", async () => { + const encoder = new TextEncoder(); + const upstreamBody = new ReadableStream({ + start(controller) { + controller.enqueue(encoder.encode("event: a\ndata: 1\n\n")); + controller.enqueue(encoder.encode("event: b\ndata: 2\n\n")); + controller.close(); + }, + }); + const { deps, logs } = makeDeps({ + fetchImpl: (async () => + new Response(upstreamBody, { + status: 200, + headers: { "content-type": "text/event-stream", "transfer-encoding": "chunked" }, + })) as unknown as typeof fetch, + }); + const res = await handleCursorCliProxy( + rpcRequest(await mintedToken(), "/agent.v1.AgentService/RunSSE"), + ["agent.v1.AgentService", "RunSSE"], + deps + ); + assert.equal(res.status, 200); + assert.equal(res.headers.get("content-type"), "text/event-stream"); + assert.equal(res.headers.get("transfer-encoding"), null); + assert.equal(await res.text(), "event: a\ndata: 1\n\nevent: b\ndata: 2\n\n"); + await flushLogs(); + assert.equal(logs.length, 1); + assert.equal(logs[0].path, `${CURSOR_CLI_PROXY_PREFIX}/agent.v1.AgentService/RunSSE`); + assert.equal(logs[0].status, 200); + }); + + it("maps upstream network failures to a sanitized 502", async () => { + const { deps, logs } = makeDeps({ + fetchImpl: (async () => { + throw new Error("connect ECONNREFUSED at /home/user/OmniRoute/open-sse/x.ts:1:1"); + }) as unknown as typeof fetch, + }); + const res = await handleCursorCliProxy( + rpcRequest(await mintedToken()), + ["aiserver.v1.DashboardService", "GetMe"], + deps + ); + assert.equal(res.status, 502); + const body = (await res.json()) as { message: string }; + assert.ok(!body.message.includes("at /"), body.message); + await flushLogs(); + assert.equal(logs[0].status, 502); + }); +}); diff --git a/tests/unit/providers-constants-split.test.ts b/tests/unit/providers-constants-split.test.ts index 32632cd2c7..e7b3b0b13f 100644 --- a/tests/unit/providers-constants-split.test.ts +++ b/tests/unit/providers-constants-split.test.ts @@ -21,7 +21,8 @@ // Raycast Pro #8895), then later additions to 199; retiring GitHub Models brings it to 198. // The v3.8.50 free-tier gateway waves (#9631 registry cycle, waves 2-5, #9210 phase 3) grew the // gateways family to 228 measured on the tip; Puter retired (#10210) and chatanywhere restored -// (base-reds round 3, #9985) are both included in that measurement. +// (base-reds round 3, #9985) are both included in that measurement; Cursor API (specialty-media, +// #10729) brings it to 229. import { test } from "node:test"; import assert from "node:assert/strict"; @@ -50,12 +51,12 @@ test("barrel still exports every catalog + key helpers", () => { } }); -test("APIKEY_PROVIDERS merges the 6 family files into 228 entries (no loss / no dup)", async () => { +test("APIKEY_PROVIDERS merges the 6 family files into 229 entries (no loss / no dup)", async () => { const keys = Object.keys((P as Record).APIKEY_PROVIDERS); - assert.equal(keys.length, 228); - assert.equal(new Set(keys).size, 228, "duplicate keys after spread-merge"); + assert.equal(keys.length, 229); + assert.equal(new Set(keys).size, 229, "duplicate keys after spread-merge"); // the merged object's entry-count equals the sum of the 6 semantic family files; families are a - // strict partition (every provider in exactly one), so the sum must be exactly 228. + // strict partition (every provider in exactly one), so the sum must be exactly 229. const families: [string, string][] = [ ["gateways", "APIKEY_PROVIDERS_GATEWAYS"], ["frontier-labs", "APIKEY_PROVIDERS_FRONTIER"], @@ -75,7 +76,7 @@ test("APIKEY_PROVIDERS merges the 6 family files into 228 entries (no loss / no seen.add(k); } } - assert.equal(famTotal, 228, "families must partition all 228 providers"); + assert.equal(famTotal, 229, "families must partition all 229 providers"); }); test("AI_PROVIDERS Proxy aggregates all sections; lookups resolve", () => {