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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,4 @@ open-sse/test/*
test-results/
playwright-report/
blob-report/
cloud/
70 changes: 66 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,77 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## [Unreleased]

---

## [0.2.0] — 2026-02-14

Major feature release: advanced routing services, security hardening, cost analytics dashboard, and pricing management overhaul.

### Added

- Model selector with autocomplete in Chat Tester and Test Bench modes — prevents "model does not exist" errors by letting users choose available models (`c25230c`)
- OpenAPI specification at `docs/openapi.yaml` covering all 89 API endpoints (`7abda4d`)
- Enhanced `restart.sh` with clean build, health check, graceful shutdown (Ctrl+C), and real-time log tailing (`0db8f3d`)
#### Open-SSE Services

- **Account Selector** — intelligent provider account selection with priority and load-balancing strategies (`accountSelector.js`)
- **Context Manager** — request context tracking and lifecycle management (`contextManager.js`)
- **IP Filter** — allowlist/blocklist IP filtering with CIDR support (`ipFilter.js`)
- **Session Manager** — persistent session tracking across requests (`sessionManager.js`)
- **Signature Cache** — request signature caching for deduplication (`signatureCache.js`)
- **System Prompt** — global system prompt injection into all chat completions (`systemPrompt.js`)
- **Thinking Budget** — token budget management for reasoning models (`thinkingBudget.js`)
- **Wildcard Router** — pattern-based model routing with glob matching (`wildcardRouter.js`)
- Enhanced **Rate Limit Manager** with sliding-window algorithm and per-key quotas

#### Dashboard Settings

- **IP Filter** settings tab — configure allowed/blocked IPs from the UI (`IPFilterSection.js`)
- **System Prompt** settings tab — set global system prompt injection (`SystemPromptTab.js`)
- **Thinking Budget** settings tab — configure reasoning token budgets (`ThinkingBudgetTab.js`)
- **Pricing Tab** — full-page redesign with provider-centric organization, inline editing, search/filter, and save/reset per provider (`PricingTab.js`)
- **Rate Limit Status** component on Usage page (`RateLimitStatus.js`)
- **Sessions Tab** on Usage page — view and manage active sessions (`SessionsTab.js`)

#### Usage & Cost Analytics

- **Cost stat card** (amber accent) prominently displayed in analytics top row
- **Provider Cost Donut** — new chart showing cost distribution across providers
- **Daily Cost Trend** — cost line overlay (amber) on token trend chart with secondary Y-axis
- **Model Table Cost column** — sortable cost column in model breakdown table
- Cost-aware tooltip formatting throughout analytics charts

#### Pricing API

- `/api/pricing/models` endpoint — serves merged model catalog from 3 sources: registry, custom models (DB), and pricing-only models
- Custom model badge in pricing page for user-imported models
- `/api/rate-limits` endpoint for rate limit configuration
- `/api/sessions` endpoint for session management
- `/api/settings/ip-filter`, `/api/settings/system-prompt`, `/api/settings/thinking-budget` endpoints

#### Cloudflare Worker

- Cloud worker module for edge deployment (`cloud/`)

#### Tests

- Unit tests for account selector, context manager, IP filter, enhanced rate limiting, session manager, signature cache, system prompt, thinking budget, and wildcard router (9 new test files)

#### Documentation

- OpenAPI specification at `docs/openapi.yaml` covering all 89 API endpoints
- Enhanced `restart.sh` with clean build, health check, graceful shutdown (Ctrl+C), and real-time log tailing
- Updated architecture documentation and codebase docs with new services and API routes
- Model selector with autocomplete in Chat Tester and Test Bench modes

### Fixed

- Server port collision (EADDRINUSE) during restart — now kills port before `next start` (`e4c5c0c`)
- Server port collision (EADDRINUSE) during restart — now kills port before `next start`
- Icon rendering corrected from `material-symbols-rounded` to `material-symbols-outlined`
- Pricing page only showed hardcoded registry models — now includes custom/imported models

### Changed

- Usage analytics layout reorganized: donuts separated into logical groupings, bottom stats simplified from 6 to 4 cards
- Daily trend chart upgraded from `BarChart` to `ComposedChart` with dual Y-axes
- Routing tab updated with new service integrations

---

Expand Down
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,12 @@ Default URLs:
| 💾 **Cloud Sync** | Sync config across devices | Same setup everywhere |
| 📊 **Usage Analytics** | Track tokens, cost, trends over time | Optimize spending |
| 🌐 **Deploy Anywhere** | Localhost, VPS, Docker, Cloudflare Workers | Flexible deployment options |
| 🛡️ **IP Allowlist/Blocklist** | Restrict API access by IP address | Security for exposed deployments |
| 🧠 **Thinking Budget** | Control reasoning token budget per model | Optimize cost vs quality |
| 💬 **System Prompt Injection** | Global system prompt for all requests | Consistent behavior across models |
| 📊 **Session Tracking** | Track active sessions with fingerprinting | Monitor connected clients |
| ⚡ **Rate Limiting** | Per-account request rate management | Prevent abuse and quota waste |
| 💰 **Model Pricing** | Per-model cost tracking and calculation | Precise usage cost analytics |

<details>
<summary><b>📖 Feature Details</b></summary>
Expand Down Expand Up @@ -1217,6 +1223,11 @@ Expected behavior from recent validation:
- Routing config: `/api/models/alias`, `/api/combos*`, `/api/keys*`, `/api/pricing`
- Usage/logs: `/api/usage/history`, `/api/usage/logs`, `/api/usage/request-logs`, `/api/usage/[connectionId]`
- Cloud sync: `/api/sync/cloud`, `/api/sync/initialize`, `/api/cloud/*`
- IP filter: `/api/settings/ip-filter` (GET/PUT) — Allowlist/blocklist management
- Thinking budget: `/api/settings/thinking-budget` (GET/PUT) — Reasoning token budget config
- System prompt: `/api/settings/system-prompt` (GET/PUT) — Global system prompt injection
- Sessions: `/api/sessions` (GET) — Active session tracking
- Rate limits: `/api/rate-limits` (GET) — Per-account rate limit status
- CLI helpers: `/api/cli-tools/claude-settings`, `/api/cli-tools/codex-settings`, `/api/cli-tools/droid-settings`, `/api/cli-tools/openclaw-settings`
- Generic runtime status: `/api/cli-tools/runtime/[toolId]` (covers `claude`, `codex`, `droid`, `openclaw`, `cursor`, `cline`, `roo`, `continue`)
- CLI `GET` responses expose runtime fields: `installed`, `runnable`, `command`, `commandPath`, `runtimeMode`, `reason`
Expand Down
49 changes: 47 additions & 2 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# OmniRoute Architecture

_Last updated: 2026-02-09_
_Last updated: 2026-02-14_

## Executive Summary

Expand All @@ -20,6 +20,12 @@ Core capabilities:
- Local persistence for providers, keys, aliases, combos, settings, pricing
- Usage/cost tracking and request logging
- Optional cloud sync for multi-device/state sync
- IP allowlist/blocklist for API access control
- Thinking budget management (passthrough/auto/custom/adaptive)
- Global system prompt injection
- Session tracking and fingerprinting
- Per-account enhanced rate limiting
- Signature-based request deduplication cache

Primary runtime model:

Expand Down Expand Up @@ -129,6 +135,11 @@ Management domains:
- Usage: `src/app/api/usage/*`
- Sync/cloud: `src/app/api/sync/*`, `src/app/api/cloud/*`
- CLI tooling helpers: `src/app/api/cli-tools/*`
- IP filter: `src/app/api/settings/ip-filter` (GET/PUT)
- Thinking budget: `src/app/api/settings/thinking-budget` (GET/PUT)
- System prompt: `src/app/api/settings/system-prompt` (GET/PUT)
- Sessions: `src/app/api/sessions` (GET)
- Rate limits: `src/app/api/rate-limits` (GET)

## 2) SSE + Translation Core

Expand All @@ -149,13 +160,24 @@ Main flow modules:
- Image generation handler: `open-sse/handlers/imageGeneration.js`
- Image provider registry: `open-sse/config/imageRegistry.js`

Services (business logic):

- Account selection/scoring: `open-sse/services/accountSelector.js`
- Context lifecycle management: `open-sse/services/contextManager.js`
- IP filter enforcement: `open-sse/services/ipFilter.js`
- Session tracking: `open-sse/services/sessionManager.js`
- Request deduplication: `open-sse/services/signatureCache.js`
- System prompt injection: `open-sse/services/systemPrompt.js`
- Thinking budget management: `open-sse/services/thinkingBudget.js`
- Wildcard model routing: `open-sse/services/wildcardRouter.js`

## 3) Persistence Layer

Primary state DB:

- `src/lib/localDb.js`
- file: `${DATA_DIR}/db.json` (or `$XDG_CONFIG_HOME/omniroute/db.json` when set, else `~/.omniroute/db.json`)
- entities: providerConnections, providerNodes, modelAliases, combos, apiKeys, settings, pricing, **customModels**, **proxyConfig**
- entities: providerConnections, providerNodes, modelAliases, combos, apiKeys, settings, pricing, **customModels**, **proxyConfig**, **ipFilter**, **thinkingBudget**, **systemPrompt**

Usage DB:

Expand Down Expand Up @@ -399,6 +421,24 @@ erDiagram
string global
json providers
}

IP_FILTER {
string mode
string[] allowlist
string[] blocklist
}

THINKING_BUDGET {
string mode
number customBudget
string effortLevel
}

SYSTEM_PROMPT {
boolean enabled
string prompt
string position
}
```

Physical storage files:
Expand Down Expand Up @@ -459,6 +499,11 @@ flowchart LR
- `src/app/api/usage/*`: usage and logs APIs
- `src/app/api/sync/*` + `src/app/api/cloud/*`: cloud sync and cloud-facing helpers
- `src/app/api/cli-tools/*`: local CLI config writers/checkers
- `src/app/api/settings/ip-filter`: IP allowlist/blocklist (GET/PUT)
- `src/app/api/settings/thinking-budget`: thinking token budget config (GET/PUT)
- `src/app/api/settings/system-prompt`: global system prompt (GET/PUT)
- `src/app/api/sessions`: active session listing (GET)
- `src/app/api/rate-limits`: per-account rate limit status (GET)

### Routing and Execution Core

Expand Down
13 changes: 13 additions & 0 deletions docs/CODEBASE_DOCUMENTATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,14 @@ Business logic that supports the handlers and executors.
| `tokenRefresh.js` | OAuth token refresh for **every provider**: Google (Gemini, Antigravity), Claude, Codex, Qwen, iFlow, GitHub (OAuth + Copilot dual-token), Kiro (AWS SSO OIDC + Social Auth). Includes in-flight promise deduplication cache and retry with exponential backoff. |
| `combo.js` | **Combo models**: chains of fallback models. If model A fails with a fallback-eligible error, try model B, then C, etc. Returns actual upstream status codes. |
| `usage.js` | Fetches quota/usage data from provider APIs (GitHub Copilot quotas, Antigravity model quotas, Codex rate limits, Kiro usage breakdowns, Claude settings). |
| `accountSelector.js` | Smart account selection with scoring algorithm: considers priority, health status, round-robin position, and cooldown state to pick the optimal account for each request. |
| `contextManager.js` | Request context lifecycle management: creates and tracks per-request context objects with metadata (request ID, timestamps, provider info) for debugging and logging. |
| `ipFilter.js` | IP-based access control: supports allowlist and blocklist modes. Validates client IP against configured rules before processing API requests. |
| `sessionManager.js` | Session tracking with client fingerprinting: tracks active sessions using hashed client identifiers, monitors request counts, and provides session metrics. |
| `signatureCache.js` | Request signature-based deduplication cache: prevents duplicate requests by caching recent request signatures and returning cached responses for identical requests within a time window. |
| `systemPrompt.js` | Global system prompt injection: prepends or appends a configurable system prompt to all requests, with per-provider compatibility handling. |
| `thinkingBudget.js` | Reasoning token budget management: supports passthrough, auto (strip thinking config), custom (fixed budget), and adaptive (complexity-scaled) modes for controlling thinking/reasoning tokens. |
| `wildcardRouter.js` | Wildcard model pattern routing: resolves wildcard patterns (e.g., `*/claude-*`) to concrete provider/model pairs based on availability and priority. |

#### Token Refresh Deduplication

Expand Down Expand Up @@ -460,6 +468,11 @@ logs/
| `/v1/providers/[provider]/chat/completions` | POST | Dedicated per-provider chat completions with model validation |
| `/v1/providers/[provider]/embeddings` | POST | Dedicated per-provider embeddings with model validation |
| `/v1/providers/[provider]/images/generations` | POST | Dedicated per-provider image generation with model validation |
| `/api/settings/ip-filter` | GET/PUT | IP allowlist/blocklist management |
| `/api/settings/thinking-budget` | GET/PUT | Reasoning token budget configuration (passthrough/auto/custom/adaptive) |
| `/api/settings/system-prompt` | GET/PUT | Global system prompt injection for all requests |
| `/api/sessions` | GET | Active session tracking and metrics |
| `/api/rate-limits` | GET | Per-account rate limit status |

---

Expand Down
1 change: 1 addition & 0 deletions next.config.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/** @type {import('next').NextConfig} */
const nextConfig = {

Copilot AI Feb 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The turbopack: {} configuration is added but appears to be an empty object. Turbopack is Next.js's new bundler (still in beta). If this is intentional to enable Turbopack in development, consider adding a comment explaining its purpose. If it's not being used, this line can be removed. Also verify that all features work correctly with Turbopack enabled, as it may have compatibility issues with some packages or features.

Suggested change
const nextConfig = {
const nextConfig = {
// Enable Turbopack (Next.js experimental bundler) in development with default settings.
// Verify compatibility of all features/packages before relying on this in production.

Copilot uses AI. Check for mistakes.
turbopack: {},
output: "standalone",
transpilePackages: ["@omniroute/open-sse"],
allowedDevOrigins: ["192.168.*"],
Expand Down
15 changes: 15 additions & 0 deletions open-sse/config/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,21 @@ export const BACKOFF_CONFIG = {
maxLevel: 15, // Cap backoff level
};

// Configurable backoff steps for rate limits (Phase 1 — enhanced rate limiting)
// Used for per-model lockouts with increasing severity
export const BACKOFF_STEPS_MS = [60_000, 120_000, 300_000, 600_000, 1_200_000];
// 1min → 2min → 5min → 10min → 20min

// Structured error classification for rate limiting decisions
export const RateLimitReason = {
QUOTA_EXHAUSTED: 'quota_exhausted', // Daily/monthly quota depleted
RATE_LIMIT_EXCEEDED: 'rate_limit_exceeded', // RPM/RPD limits hit
MODEL_CAPACITY: 'model_capacity', // Model overloaded (529, 503)
SERVER_ERROR: 'server_error', // 5xx errors
AUTH_ERROR: 'auth_error', // 401, 403
UNKNOWN: 'unknown',
};

// Error-based cooldown times (aligned with CLIProxyAPI)
export const COOLDOWN_MS = {
unauthorized: 2 * 60 * 1000, // 401 → 30 min
Expand Down
Loading