Compare commits

..

7 Commits

Author SHA1 Message Date
diegosouzapw 049ddff6fe feat(release): v2.0.14 — fix model name stripping, multimodal image_url, electron release workflow
Build Electron Desktop App / Validate version (push) Failing after 30s
Build Electron Desktop App / Build Electron (macos-arm64) (push) Has been skipped
Build Electron Desktop App / Build Electron (linux) (push) Has been skipped
Build Electron Desktop App / Build Electron (macos-intel) (push) Has been skipped
Build Electron Desktop App / Build Electron (windows) (push) Has been skipped
Build Electron Desktop App / Create Release (push) Has been skipped
- Fix #243: model.split('/').pop() → slice(1).join('/') preserves vendor namespaces
- Fix #242: image_url → input_image conversion for Responses API backends
- Merge PR #241: electron release workflow (mac x64/arm64 separation, version sync)
- CHANGELOG updated
2026-03-08 02:19:36 -03:00
diegosouzapw 9429d1639e Merge PR #241: fix(electron): resolve release build workflow errors
- Sync electron package.json version with root (2.0.13)
- Separate mac x64 and arm64 into dedicated runner jobs
- Use macos-13 (Intel) runner for x64 build
- Thanks @benzntech for the contribution!
2026-03-08 02:17:46 -03:00
diegosouzapw af7ca4baf7 fix: strip only internal prefix from model name for compatible providers (#243)
- Changed model.split('/').pop() to model.split('/').slice(1).join('/')
- Preserves vendor namespace in model names (e.g. moonshotai/Kimi-K2-Instruct)
- Also fixes multimodal image_url → input_image conversion for Responses API (#242)
- image_url parts from Chat Completions are now properly converted to input_image format
2026-03-08 02:17:21 -03:00
benzntech 7906fdfc1d fix(electron): resolve release build workflow errors
- Sync electron package.json version with root to fix artifact collection

- Separate mac x64 and arm64 targets into dedicated runner jobs

- Use macos-13 (Intel) runner for x64 build to prevent cross-compilation timeouts
2026-03-07 23:46:59 +05:30
diegosouzapw 9911272898 chore: rename docs to uppercase + gitignore cleanup
- Rename a2a-server.md → A2A-SERVER.md, auto-combo.md → AUTO-COMBO.md, mcp-server.md → MCP-SERVER.md
- Update gitignore whitelist to match uppercase names
- Reddit Launch Plan v2 remains gitignored (local only)
2026-03-07 13:18:34 -03:00
diegosouzapw 8909ae041e chore: update llm.txt to v2.0.13 state
- Complete rewrite of llm.txt with current project structure
- Added ACP agents, CLI fingerprint, sidebar reorganization
- Added 30 languages, MCP/A2A servers, anti-ban features
- Updated project structure tree with all dashboard pages
2026-03-07 12:36:24 -03:00
diegosouzapw c9a15772b0 chore: remove docs/new-features from tracking + gitignore cleanup
- Remove docs/new-features/ from git index (224 leaked feature spec files)
- Remove docs/new-features/ from gitignore whitelist
- Add .omnivscodeagent/, omnirouteCloud/, omnirouteSite/ to gitignore
- Remove duplicate omnirouteCloud/omnirouteSite entries
2026-03-07 12:33:56 -03:00
12 changed files with 154 additions and 33 deletions
+3 -3
View File
@@ -55,12 +55,12 @@ jobs:
target: win
ext: .exe
- platform: macos-intel
runner: macos-latest
target: mac
runner: macos-13
target: mac-x64
ext: .dmg
- platform: macos-arm64
runner: macos-latest
target: mac
target: mac-arm64
ext: -arm64.dmg
- platform: linux
runner: ubuntu-latest
+8 -6
View File
@@ -1,5 +1,10 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# project-specific directories
.omnivscodeagent/
omnirouteCloud/
omnirouteSite/
# dependencies
node_modules/
/.pnp
@@ -77,10 +82,9 @@ docs/*
!docs/screenshots/
!docs/i18n/
!docs/i18n/**
!docs/a2a-server.md
!docs/auto-combo.md
!docs/mcp-server.md
!docs/new-features/
!docs/A2A-SERVER.md
!docs/AUTO-COMBO.md
!docs/MCP-SERVER.md
# open-sse tests
open-sse/test/*
@@ -93,8 +97,6 @@ test-results/
playwright-report/
blob-report/
cloud/
omnirouteCloud/
omnirouteSite/
# Security Analysis (standalone project with own git)
security-analysis/
+24
View File
@@ -7,6 +7,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
---
## [2.0.14] — 2026-03-08
> ### 🐛 Bug Fixes + Electron Release Fix
### 🐛 Bug Fixes
- **#243 — OpenAI-Compatible model name stripping** — Fixed `model.split("/").pop()` stripping vendor namespace from model names with slashes. Models like `moonshotai/Kimi-K2-Instruct` were being truncated to just `Kimi-K2-Instruct`. Now uses `slice(1).join("/")` to preserve the full vendor/model path
- **#242 — Multimodal image_url rejection on Responses API** — Fixed `image_url` content parts from Chat Completions format being passed through without conversion to `input_image` format expected by Responses/Codex backends. Now properly converts `{type: "image_url", image_url: {url: "..."}}``{type: "input_image", image_url: "..."}`
### 🔧 Infrastructure
- **PR #241 — Electron release workflow** — Synced `electron/package.json` version to `2.0.13`, separated macOS x64 and arm64 into dedicated CI runner jobs, using `macos-13` (Intel) runner for x64 builds to prevent cross-compilation timeouts (thanks @benzntech)
### 📁 Files Changed
| File | Change |
| ------------------------------------------------- | -------------------------------------------------------- |
| `open-sse/executors/default.ts` | Fix model name stripping: `pop()``slice(1).join("/")` |
| `open-sse/translator/request/openai-responses.ts` | Convert `image_url``input_image` for Responses API |
| `.github/workflows/electron-release.yml` | Separate mac x64/arm64 builds |
| `electron/package.json` | Version sync + arch-specific build scripts |
---
## [2.0.11] — 2026-03-07
> ### 🤖 ACP Agents Dashboard + Anti-Ban Docs
+4 -8
View File
@@ -1,6 +1,6 @@
{
"name": "omniroute-desktop",
"version": "1.6.9",
"version": "2.0.13",
"description": "OmniRoute Desktop Application",
"main": "main.js",
"author": "OmniRoute Team",
@@ -12,6 +12,8 @@
"build": "electron-builder",
"build:win": "electron-builder --win",
"build:mac": "electron-builder --mac",
"build:mac-x64": "electron-builder --mac --x64",
"build:mac-arm64": "electron-builder --mac --arm64",
"build:linux": "electron-builder --linux",
"pack": "electron-builder --dir"
},
@@ -82,13 +84,7 @@
},
"mac": {
"target": [
{
"target": "dmg",
"arch": [
"x64",
"arm64"
]
}
"dmg"
],
"icon": "assets/icon.icns",
"category": "public.app-category.productivity"
+104 -11
View File
@@ -8,6 +8,8 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
**Key value:** One endpoint (`http://localhost:20128/v1`), unlimited models, zero downtime, minimal cost.
**Current version:** 2.0.13
## Tech Stack
- **Runtime:** Node.js >= 18
@@ -19,6 +21,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Background jobs:** Custom token health check scheduler
- **Streaming:** Server-Sent Events (SSE) for real-time proxy responses
- **Proxy engine:** Custom pipeline with format translation, circuit breaker, rate limiting
- **i18n:** next-intl with 30 languages
- **Package:** Published on npm (`omniroute`) and Docker Hub (`diegosouzapw/omniroute`)
## Project Structure
@@ -27,9 +30,27 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
/
├── src/ # Main application source
│ ├── app/ # Next.js App Router pages and API routes
│ │ ├── (dashboard)/ # Dashboard UI pages (providers, combos, analytics, logs, etc.)
│ │ ├── (dashboard)/ # Dashboard UI pages
│ │ │ └── dashboard/
│ │ │ ├── agents/ # ACP Agents dashboard (CLI agent detection + custom agents)
│ │ │ ├── analytics/ # Usage analytics and charts
│ │ │ ├── api-manager/ # API key management
│ │ │ ├── cli-tools/ # CLI tool configuration (Claude, Codex, Gemini, etc.)
│ │ │ ├── combos/ # Model combo management
│ │ │ ├── costs/ # Cost tracking
│ │ │ ├── endpoint/ # Endpoint info and cloud proxy
│ │ │ ├── health/ # System health monitoring
│ │ │ ├── limits/ # Rate limits dashboard
│ │ │ ├── logs/ # Request logs viewer
│ │ │ ├── media/ # Image/video/music generation
│ │ │ ├── playground/ # Model playground (Monaco editor, streaming)
│ │ │ ├── providers/ # Provider management (OAuth + API key + free)
│ │ │ ├── settings/ # Settings tabs (General, Appearance, Security, Routing, Resilience, Advanced)
│ │ │ ├── translator/ # Format translator + debug tools
│ │ │ └── usage/ # Usage history
│ │ ├── api/ # REST API endpoints
│ │ │ ├── v1/ # OpenAI-compatible API (chat, models, embeddings, images, audio)
│ │ │ ├── acp/ # ACP agent management API
│ │ │ ├── oauth/ # OAuth flows per provider (authorize, exchange, callback)
│ │ │ ├── providers/ # Provider CRUD and batch testing
│ │ │ ├── models/ # Dashboard model listing and aliases
@@ -37,7 +58,10 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── ... # Other endpoints (usage, logs, health, settings, etc.)
│ │ └── login/ # Login page
│ ├── domain/ # Domain types and business logic interfaces
│ ├── i18n/ # Internationalization
│ │ └── messages/ # 30 language JSON files (ar, bg, da, de, en, es, fi, fr, he, hu, id, in, it, ja, ko, ms, nl, no, phi, pl, pt, pt-BR, ro, ru, sk, sv, th, uk-UA, vi, zh-CN)
│ ├── lib/ # Core libraries
│ │ ├── acp/ # ACP agent registry and manager (14 built-in agents + custom)
│ │ ├── db/ # SQLite database layer (providers, combos, prompts, logs)
│ │ ├── oauth/ # OAuth providers, services, and utilities
│ │ │ ├── providers/ # Provider-specific OAuth configs (GitHub, Google, Claude, etc.)
@@ -47,28 +71,88 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── tokenHealthCheck.ts # Background OAuth token refresh scheduler
│ │ └── localDb.ts # Unified database access layer
│ ├── shared/ # Shared utilities, components, and constants
│ │ ├── components/ # Reusable UI components (Card, Badge, Button, Modal, etc.)
│ │ ├── components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, etc.)
│ │ ├── constants/ # Provider definitions, model lists, pricing
│ │ ├── validation/ # Zod schemas (settings, providers, etc.)
│ │ └── utils/ # Helpers (auth, CORS, error codes, machine ID)
│ ├── sse/ # SSE proxy pipeline
│ │ ├── services/ # Auth resolution, format translation, response handling
│ │ └── middleware/ # Rate limiting, circuit breaker, caching, idempotency
│ ├── store/ # Zustand client-side stores
│ ├── store/ # Zustand client-side stores (theme, providers, etc.)
│ ├── types/ # TypeScript type definitions
│ ├── proxy.ts # Main proxy request handler
│ └── server-init.ts # Server initialization (DB, health checks)
├── open-sse/ # Standalone SSE server (npm workspace)
│ ├── config/ # Model registries (embedding, image, audio, rerank, moderation)
│ ├── config/ # Model registries (embedding, image, audio, rerank, moderation, CLI fingerprints)
│ ├── handlers/ # Request handlers per API type
── translators/ # Format translators (OpenAI ↔ Claude ↔ Gemini ↔ Responses)
── mcp-server/ # Built-in MCP server (16 tools, audit logging, scope auth)
│ └── translators/ # Format translators (OpenAI ↔ Claude ↔ Gemini ↔ Responses ↔ Ollama)
├── tests/ # Test suites
│ ├── unit/ # Unit tests (32+ test files)
│ └── integration/ # Integration tests
├── docs/ # Documentation and screenshots
├── docs/ # Documentation (with 29-language i18n subdirectories)
│ ├── i18n/ # Translated docs (ar, bg, da, de, es, fi, fr, he, hu, id, in, it, ja, ko, ms, nl, no, phi, pl, pt, pt-BR, ro, ru, sk, sv, th, uk-UA, vi, zh-CN)
│ ├── screenshots/ # Dashboard screenshots
│ ├── a2a-server.md # A2A agent protocol documentation
│ ├── auto-combo.md # Auto-combo engine (6-factor scoring)
│ └── mcp-server.md # MCP server (16 tools)
├── electron/ # Electron desktop app
├── bin/ # CLI entry points (omniroute, reset-password)
└── .env.example # Environment variable template
```
## Key Features (v2.0.13)
### Core Proxy
- **36+ AI providers** with automatic format translation
- **6 routing strategies**: priority, weighted, round-robin, random, least-used, cost-optimized
- **4-tier fallback**: Subscription → API Key → Cheap → Free
- **Semantic caching** with cache hit/miss headers
- **Idempotency** with configurable dedup window
- **Circuit breaker** per provider with configurable thresholds
### Anti-Ban Protection
- **TLS Fingerprint Spoofing** — Browser-like TLS fingerprint to reduce bot detection
- **CLI Fingerprint Matching** — Per-provider request signature matching (headers/body ordering) to match native CLI tools. Proxy IP is preserved.
### Dashboard Pages
- **Providers** — OAuth, API key, and free provider management
- **Combos** — Multi-model fallback chain builder with templates
- **Analytics** — Token consumption, cost, heatmaps, distributions
- **Health** — Uptime, memory, latency percentiles, circuit breakers
- **Logs** — Real-time request log viewer with filtering
- **Costs** — Cost tracking per provider/model
- **Limits** — Rate limit monitoring
- **CLI Tools** — One-click configuration for 10+ AI CLI tools
- **CLI Agents** — Grid of 14 built-in agents with install detection + custom agent registration
- **Playground** — Test any model with Monaco editor, streaming responses
- **Media** — Image/video/music generation (DALL-E, FLUX, AnimateDiff, etc.)
- **Translator** — Format debugging: playground, chat tester, test bench, live monitor
- **Settings** — General, Appearance (7 color themes), Security (TLS/CLI fingerprint, IP filter), Routing, Resilience, Advanced
- **Endpoint** — Unified API endpoint info + cloud proxy
### Sidebar Organization
- **Main**: Home, Endpoints, API Manager, Providers, Combos, Costs, Analytics, Limits
- **CLI**: Tools, Agents
- **Debug**: Translator, Playground, Media
- **System**: Health, Logs, Settings
- **Help**: Docs, Issues
### Protocol Support
- **OpenAI-compatible** — `/v1/chat/completions`, `/v1/models`, `/v1/embeddings`, `/v1/images/generations`, `/v1/audio/transcriptions`
- **Anthropic** — `/v1/messages`, `/v1/messages/count_tokens`
- **OpenAI Responses** — `/v1/responses`
- **Gemini** — `/v1beta/models`, `/v1beta/models/{...path}`
- **Ollama** — `/v1/api/chat`, `/api/tags`
- **MCP** — 16-tool MCP server with scope-based auth
- **A2A** — Agent-to-Agent protocol (smart-routing, quota-management skills)
- **ACP** — Agent detection, custom agent registry
### Internationalization
- 30 languages for UI (sidebar, settings, agents, and all dashboard pages)
- 30 READMEs (root README.md + 29 translated README.*.md)
- 29 translated doc sets in docs/i18n/
## Key Architectural Decisions
1. **OpenAI-compatible API surface:** All incoming requests follow the OpenAI API format (`/v1/chat/completions`, `/v1/models`, etc.). This makes OmniRoute a drop-in replacement for any tool that supports custom OpenAI endpoints.
@@ -77,13 +161,15 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
3. **Connection-based provider model:** Providers are stored as "connections" in SQLite. Each connection has an `id`, `provider`, `authType` (oauth/apikey/free), `isActive` flag, and credentials. Multiple connections per provider are supported for multi-account rotation.
4. **Combo system for fallback:** Users create "combos" — ordered lists of `provider/model` pairs. The proxy tries each in order until one succeeds. Supports 6 strategies: fill-first, round-robin, power-of-two-choices, random, least-used, cost-optimized.
4. **Combo system for fallback:** Users create "combos" — ordered lists of `provider/model` pairs. The proxy tries each in order until one succeeds. Supports 6 strategies.
5. **SSE proxy pipeline (`src/sse/`):** The proxy pipeline is middleware-based: request → auth resolution → rate limiting → circuit breaker → format translation → upstream call → response translation → SSE streaming back to client.
6. **SQLite for persistence:** All state (providers, combos, logs, settings) is stored in a single SQLite database file at `data/omniroute.db`. This keeps the app self-contained and zero-config.
7. **OAuth with PKCE:** OAuth flows use PKCE for security. A local callback server (`src/lib/oauth/utils/server.ts`) handles the redirect. Token refresh is handled by a background job (`tokenHealthCheck.ts`).
7. **OAuth with PKCE:** OAuth flows use PKCE for security. A local callback server handles the redirect. Token refresh is handled by a background job (`tokenHealthCheck.ts`).
8. **ACP Agent Registry:** 14 built-in CLI agents with dynamic detection and a 60-second cache. Custom agents can be added via dashboard or API, stored in settings DB.
## Main Flows
@@ -94,9 +180,10 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
4. For combos: iterate through models in fallback order
5. Auth resolution: get credentials for the target provider
6. Format translation: OpenAI → provider native format
7. Upstream request with circuit breaker and rate limiting
8. Response translation: provider → OpenAI format
9. SSE streaming back to client
7. CLI fingerprint matching (if enabled for provider)
8. Upstream request with circuit breaker and rate limiting
9. Response translation: provider → OpenAI format
10. SSE streaming back to client
### OAuth Flow
1. Dashboard initiates `/api/oauth/[provider]/authorize`
@@ -125,6 +212,12 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
7. **The proxy pipeline is in `src/sse/`**, not in `src/app/api/v1/`. The API routes in `src/app/api/v1/` delegate to the SSE server running on a separate Express instance.
8. **Sidebar sections:** Main nav, CLI (Tools + Agents), Debug (Translator + Playground + Media), System (Health + Logs + Settings), Help (Docs + Issues).
9. **ACP agents** are in `src/lib/acp/registry.ts` (14 built-in) with a 60s detection cache. Custom agents stored via `src/shared/validation/settingsSchemas.ts`.
10. **CLI fingerprint configs** are in `open-sse/config/cliFingerprints.ts`. They match native CLI request patterns per provider.
## Links
- Repository: https://github.com/diegosouzapw/OmniRoute
+1 -1
View File
@@ -82,7 +82,7 @@ export class DefaultExecutor extends BaseExecutor {
this.provider?.startsWith?.("openai-compatible-") ||
this.provider?.startsWith?.("anthropic-compatible-")
) {
const cleanModel = model.includes("/") ? model.split("/").pop() : model;
const cleanModel = model.includes("/") ? model.split("/").slice(1).join("/") : model;
return { ...body, model: cleanModel };
}
return body;
@@ -261,7 +261,13 @@ export function openaiToOpenAIResponsesRequest(
if (contentItem.type === "text") {
return { type: "input_text", text: toString(contentItem.text) };
}
if (contentItem.type === "image_url") return contentValue; // passthrough images
if (contentItem.type === "image_url") {
const imgUrl = contentItem.image_url as string | { url?: string };
return {
type: "input_image",
image_url: typeof imgUrl === "string" ? imgUrl : imgUrl?.url || "",
};
}
return contentValue;
})
: [{ type: "input_text", text: "" }];
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "omniroute",
"version": "2.0.12",
"version": "2.0.13",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "omniroute",
"version": "2.0.12",
"version": "2.0.13",
"hasInstallScript": true,
"license": "MIT",
"workspaces": [
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "omniroute",
"version": "2.0.13",
"version": "2.0.14",
"description": "Smart AI Router with auto fallback — route to FREE & cheap models, zero downtime. Works with Cursor, Cline, Claude Desktop, Codex, and any OpenAI-compatible tool.",
"type": "module",
"bin": {