Compare commits
115 Commits
chore/reco
...
fix/codeql
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
528fba953d | ||
|
|
1ee4818224 | ||
|
|
6afc7ddab0 | ||
|
|
71fd806bb0 | ||
|
|
adedc351d7 | ||
|
|
1d476e4ced | ||
|
|
18d5b75335 | ||
|
|
00d385b498 | ||
|
|
7b9b36836c | ||
|
|
ae8ab27294 | ||
|
|
9237a0562f | ||
|
|
c4d149c2eb | ||
|
|
a0422b9af8 | ||
|
|
5f5d1101ba | ||
|
|
5b8fe4d8c7 | ||
|
|
d1768de716 | ||
|
|
c11f661a8a | ||
|
|
0481f61750 | ||
|
|
86c03f1fed | ||
|
|
8abcd639d1 | ||
|
|
9f1f5ecf1f | ||
|
|
e616130496 | ||
|
|
7a10d3856a | ||
|
|
5984c43f5b | ||
|
|
331580b499 | ||
|
|
3a7ed20bcd | ||
|
|
9c34e88f6b | ||
|
|
131f8cb15a | ||
|
|
2617841449 | ||
|
|
65aeaeece8 | ||
|
|
d351960be9 | ||
|
|
4914954866 | ||
|
|
b7d91a6b6e | ||
|
|
ebbfcf4ffe | ||
|
|
2d185de9d9 | ||
|
|
c63e519b09 | ||
|
|
a02b4b404d | ||
|
|
6e96057f1d | ||
|
|
5eebee5dcc | ||
|
|
608c90f592 | ||
|
|
b61a530a33 | ||
|
|
6ffa012c3e | ||
|
|
eccb66042c | ||
|
|
5c1a882b95 | ||
|
|
8cb2d0c047 | ||
|
|
1ea13454d5 | ||
|
|
0a792216d6 | ||
|
|
4449ba3173 | ||
|
|
fe12208e30 | ||
|
|
f40f6e18da | ||
|
|
91ede70bcb | ||
|
|
954d58b528 | ||
|
|
88939a35d1 | ||
|
|
b9fd4aa00b | ||
|
|
ff1ed20bb8 | ||
|
|
5cc213e46b | ||
|
|
5d7d4cb953 | ||
|
|
bd4a7629b6 | ||
|
|
bfac589529 | ||
|
|
e0ea3f92e1 | ||
|
|
64ffddf5e5 | ||
|
|
a9dd1dd0fe | ||
|
|
f69cd9f3bd | ||
|
|
6eb7bf0ba9 | ||
|
|
ae22c157f4 | ||
|
|
b84ae072ea | ||
|
|
be6cbe7de5 | ||
|
|
721ee2a038 | ||
|
|
892f359305 | ||
|
|
7b7196f05d | ||
|
|
a8f9024c20 | ||
|
|
9ad90fe7a3 | ||
|
|
3f6a881b6c | ||
|
|
fff62f10a7 | ||
|
|
d3c395bbcf | ||
|
|
3863dab149 | ||
|
|
ffd8984a59 | ||
|
|
6787fc9aa9 | ||
|
|
64a28b559c | ||
|
|
98cec759ae | ||
|
|
62b3f9d36d | ||
|
|
891c1af0ea | ||
|
|
1ad06d2059 | ||
|
|
0023a9ec04 | ||
|
|
9862f129e2 | ||
|
|
700819a29b | ||
|
|
7cfabfc5c9 | ||
|
|
026d26edb7 | ||
|
|
8a8d0cf336 | ||
|
|
ee4e37154d | ||
|
|
60eb0806df | ||
|
|
a63b3e21b9 | ||
|
|
ae7a843e86 | ||
|
|
a15af27c78 | ||
|
|
78d10da84c | ||
|
|
17e4ddfc77 | ||
|
|
28601b456e | ||
|
|
436ce4869f | ||
|
|
e48ffd38d3 | ||
|
|
30026b2e96 | ||
|
|
3804ffb6ff | ||
|
|
eb9b4cec54 | ||
|
|
57461af5cf | ||
|
|
1a8c6d13a1 | ||
|
|
987b67420a | ||
|
|
a8dbf7bbb8 | ||
|
|
a179ffed5b | ||
|
|
23fa2709a9 | ||
|
|
6435f618f4 | ||
|
|
b39e5ecb20 | ||
|
|
a0ceccc6f0 | ||
|
|
14ca809924 | ||
|
|
c8ca024e29 | ||
|
|
613fc71e98 | ||
|
|
c472dbccc4 |
49
.env.example
@@ -403,8 +403,17 @@ ALLOW_API_KEY_REVEAL=false
|
||||
# OMNIROUTE_CHAT_LARGE_BODY_BYTES=262144
|
||||
# Actual-byte hard cap enforced during bounded ingestion. Default 52428800 (50 MB).
|
||||
# OMNIROUTE_CHAT_HARD_MAX_BODY_BYTES=52428800
|
||||
# Maximum heavyweight requests simultaneously admitted in one process. Default 1.
|
||||
# Legacy request-COUNT cap (#503-fanout). Now binds only when explicitly set here —
|
||||
# left unset, heavyweight admission is gated by OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES below
|
||||
# instead (an auto-derived byte budget), fixing coding-agent fan-out (multiple
|
||||
# subagents/CLIs) collapsing to an effective concurrency of ~1 and 503ing.
|
||||
# OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT=1
|
||||
# Override for the auto-derived ingest byte budget (#503-fanout). Default: 25% of the
|
||||
# process's effective memory ceiling (V8 heap limit, or the tighter cgroup/container
|
||||
# limit) divided by an 8x transient-amplification factor, clamped between 8 MiB and
|
||||
# 2 GiB; explicit overrides are clamped to the same safe range. Read
|
||||
# chatAdmission.maxInflightBytes/budgetSource at /api/monitoring/health before overriding.
|
||||
# OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES=134217728
|
||||
# Heap-pressure shed ratio (heapUsed/heap_size_limit) for the structural admission gate
|
||||
# (#10183, #10268): a second concurrent heavyweight request past OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT
|
||||
# is only shed with a retryable 503 when the heap is ALSO under this much pressure — on a
|
||||
@@ -916,6 +925,11 @@ NEXT_PUBLIC_ENABLE_SOCKS5_PROXY=true
|
||||
# web_fetch). Default: 60000. Used by: open-sse/mcp-server/fetchTimeout.ts
|
||||
# OMNIROUTE_MCP_UPSTREAM_TIMEOUT_MS=60000
|
||||
|
||||
# Maximum number of local-corpus index instances cached in memory.
|
||||
# Used by: src/lib/localCorpus/configured.ts — bounds the LRU cache of
|
||||
# LocalCorpusIndex objects (one per indexed root directory). Default: 5.
|
||||
# OMNIROUTE_CORPUS_CACHE_SIZE=5
|
||||
|
||||
# Model catalog sync interval in hours.
|
||||
# Used by: src/shared/services/modelSyncScheduler.ts — periodic model refresh.
|
||||
# Default: 24
|
||||
@@ -1788,6 +1802,13 @@ APP_LOG_TO_FILE=true
|
||||
# SEMANTIC_CACHE_MAX_BYTES=4194304 # Max total cache size in bytes (default: 4 MB)
|
||||
# SEMANTIC_CACHE_TTL_MS=1800000 # Cache entry TTL (default: 30 minutes)
|
||||
|
||||
# ── Local corpus index cache ──
|
||||
# How many local-corpus roots keep a live in-memory index at once. The cache is
|
||||
# LRU: reaching the limit evicts the least-recently-used root's index, which is
|
||||
# then rebuilt on its next query. Clamped to a minimum of 1; a non-numeric value
|
||||
# falls back to the default. Used by: src/lib/localCorpus/configured.ts
|
||||
# OMNIROUTE_CORPUS_CACHE_SIZE=5
|
||||
|
||||
# ── In-memory log buffers ──
|
||||
# Maximum recent stream events kept in memory for the Dashboard live view.
|
||||
# STREAM_HISTORY_MAX=50
|
||||
@@ -1983,6 +2004,26 @@ APP_LOG_TO_FILE=true
|
||||
# Custom path to cloudflared binary for tunnel management.
|
||||
# Used by: src/lib/cloudflaredTunnel.ts
|
||||
# CLOUDFLARED_BIN=/usr/local/bin/cloudflared
|
||||
#
|
||||
# Transport protocol for the tunnel. One of: http2 (default), quic, auto.
|
||||
# CLOUDFLARED_PROTOCOL=http2
|
||||
#
|
||||
# ── Named / persistent tunnel (stable hostname) ──
|
||||
# By default OmniRoute runs an ephemeral quick tunnel (random *.trycloudflare.com
|
||||
# URL that changes on every restart). To bind a stable, named hostname instead,
|
||||
# create a locally-managed tunnel with the cloudflared CLI:
|
||||
# cloudflared tunnel login
|
||||
# cloudflared tunnel create <name>
|
||||
# cloudflared tunnel route dns <name> ai.example.com
|
||||
# then write a ~/.cloudflared/config.yml with `tunnel:`, `credentials-file:`, and
|
||||
# `ingress:` rules routing your hostname to http://localhost:<PORT> (default 20128).
|
||||
# Point OmniRoute at that config to switch into named-tunnel mode — it runs
|
||||
# `cloudflared tunnel --config <path> run`.
|
||||
# CLOUDFLARED_CONFIG=/home/you/.cloudflared/config.yml
|
||||
# CLOUDFLARED_HOSTNAME is optional — when unset, OmniRoute reads the public hostname
|
||||
# from the config's first ingress rule. Set it to override what is reported as
|
||||
# publicUrl/apiUrl.
|
||||
# CLOUDFLARED_HOSTNAME=ai.example.com
|
||||
|
||||
# ── Search cache ──
|
||||
# TTL for search API response caching (Perplexity, Brave, etc.).
|
||||
@@ -3026,3 +3067,9 @@ QUOTA_STORE_DRIVER=sqlite
|
||||
# without a configured budget are always considered affordable. Requires the
|
||||
# provider_quota_state table (migration 148).
|
||||
# OMNIROUTE_QUOTA_AWARE_ROUTING=0
|
||||
|
||||
# ─── LOCAL CORPUS (opt-in document index) ───
|
||||
# Size of the in-memory LRU index cache for the local document corpus used by
|
||||
# corpus-aware retrieval. Higher values keep more index entries hot.
|
||||
# Used by: src/lib/localCorpus/configured.ts
|
||||
# OMNIROUTE_CORPUS_CACHE_SIZE=5
|
||||
|
||||
1
.github/workflows/ci.yml
vendored
@@ -126,6 +126,7 @@ jobs:
|
||||
- run: npm run check:route-validation:t06
|
||||
- run: npm run check:any-budget:t11
|
||||
- run: npm run check:provider-consistency
|
||||
- run: npm run check:model-lifecycle
|
||||
- run: npm run check:fetch-targets
|
||||
- run: npm run check:deps
|
||||
- run: npm run check:file-size
|
||||
|
||||
10
.github/workflows/docker-publish.yml
vendored
@@ -68,6 +68,16 @@ jobs:
|
||||
"$EVENT_NAME" "$REF_TYPE" "$REF_NAME" "$INPUT_VERSION" "$DEFAULT_BRANCH")
|
||||
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
||||
|
||||
# Frozen release branches keep receiving coordination commits after the
|
||||
# next cycle becomes the default branch. They must not overwrite :next,
|
||||
# but that expected no-op is not a workflow failure.
|
||||
if [ "$VERSION" = "skip" ]; then
|
||||
echo "promote_latest=false" >> "$GITHUB_OUTPUT"
|
||||
echo "skip=true" >> "$GITHUB_OUTPUT"
|
||||
echo "Skipping Docker publish from non-default release branch: $REF_NAME"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 2) Decide whether to promote :latest. Floating channels are never
|
||||
# eligible, and the helper independently fails closed for non-semver.
|
||||
PROMOTE="false"
|
||||
|
||||
4
.github/workflows/opencode-plugin-ci.yml
vendored
@@ -2,11 +2,11 @@ name: opencode-plugin CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, "release/**"]
|
||||
branches: [main, release/v3.8.2]
|
||||
paths:
|
||||
- "@omniroute/opencode-plugin/**"
|
||||
pull_request:
|
||||
branches: [main, "release/**"]
|
||||
branches: [main, release/v3.8.2]
|
||||
paths:
|
||||
- "@omniroute/opencode-plugin/**"
|
||||
types: [opened, synchronize, reopened, ready_for_review]
|
||||
|
||||
2
.github/workflows/quality.yml
vendored
@@ -273,7 +273,7 @@ jobs:
|
||||
migration-numbering public-creds db-rules known-symbols
|
||||
route-guard-membership test-discovery test-runner-api
|
||||
mutation-test-coverage any-budget:t11 build-scope pack-policy
|
||||
complexity-ratchets
|
||||
complexity-ratchets model-lifecycle
|
||||
cycles lockfile duplication dead-code type-coverage compression-budget
|
||||
# #8781: open-sse workspace typecheck gate — the workspace imports @/ which
|
||||
# escapes to src/ via undeclared path aliases. See check-open-sse-typecheck.mjs.
|
||||
|
||||
10
AGENTS.md
@@ -46,7 +46,7 @@ Repository map and Reference Documentation sections below.
|
||||
|
||||
## Project at a Glance
|
||||
|
||||
**OmniRoute** — unified AI proxy/router. One endpoint, 353 LLM providers, auto-fallback.
|
||||
**OmniRoute** — unified AI proxy/router. One endpoint, 354 LLM providers, auto-fallback.
|
||||
|
||||
| Layer | Location | Purpose |
|
||||
| ------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
@@ -56,7 +56,7 @@ Repository map and Reference Documentation sections below.
|
||||
| Translators | `open-sse/translator/` | Format conversion (OpenAI↔Claude↔Gemini) |
|
||||
| Transformer | `open-sse/transformer/` | Responses API ↔ Chat Completions |
|
||||
| Services | `open-sse/services/` | Combo routing, rate limits, caching, etc |
|
||||
| Database | `src/lib/db/` | SQLite domain modules (159 migrations) |
|
||||
| Database | `src/lib/db/` | SQLite domain modules (160 migrations) |
|
||||
| Domain/Policy | `src/domain/` | Policy engine, cost rules, fallback logic |
|
||||
| MCP Server | `open-sse/mcp-server/` | 110 tools (44 canonical + memory/skill/GitHub/pool/gamification/plugin/Notion/Obsidian/local-corpus/RTK modules), 3 transports (stdio / SSE / Streamable HTTP), 33 scopes |
|
||||
| A2A Server | `src/lib/a2a/` | JSON-RPC 2.0 agent protocol |
|
||||
@@ -83,7 +83,7 @@ Client → /v1/chat/completions (Next.js route)
|
||||
|
||||
API routes follow a consistent pattern: `Route → CORS preflight → Zod body validation → Optional auth (extractApiKey/isValidApiKey) → API key policy enforcement → Handler delegation (open-sse)`. No global Next.js middleware — interception is route-specific.
|
||||
|
||||
**Combo routing** (`open-sse/services/combo.ts`): 19 public strategies (priority, weighted, fill-first, round-robin, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, cache-optimized, context-relay, fusion, pipeline). Each target calls `handleSingleModel()` which wraps `handleChatCore()` with per-target error handling and circuit breaker checks. The `fusion` strategy is the exception: it fans out to a panel of models in parallel, then a judge model synthesizes one final answer (`open-sse/services/fusion.ts`). See `docs/routing/AUTO-COMBO.md` for the 14-factor Auto-Combo scoring + the full strategy table and `docs/architecture/RESILIENCE_GUIDE.md` for the 3 resilience layers.
|
||||
**Combo routing** (`open-sse/services/combo.ts`): 19 public strategies (priority, weighted, fill-first, round-robin, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, cache-optimized, context-relay, fusion, pipeline). Each target calls `handleSingleModel()` which wraps `handleChatCore()` with per-target error handling and circuit breaker checks. The `fusion` strategy is the exception: it fans out to a panel of models in parallel, then a judge model synthesizes one final answer (`open-sse/services/fusion.ts`). See `docs/routing/AUTO-COMBO.md` for the 15-factor Auto-Combo scoring + the full strategy table and `docs/architecture/RESILIENCE_GUIDE.md` for the 3 resilience layers.
|
||||
|
||||
---
|
||||
|
||||
@@ -197,7 +197,7 @@ baseCooldownMs * 2 ** failureIndex;
|
||||
The anti-thundering-herd guard prevents concurrent failures on the same connection from
|
||||
repeatedly extending the cooldown or double-incrementing `backoffLevel`.
|
||||
|
||||
Terminal states are not cooldowns. `banned`, `expired`, and `credits_exhausted` are
|
||||
Terminal states are not cooldowns. `banned`, `expired` (which becomes terminal only after N bounded retries via `EXPIRED_RETRY_MAX`), and `credits_exhausted` are
|
||||
intended to stay unavailable until credentials/settings change or an operator resets
|
||||
them. Do not overwrite terminal states with transient cooldown state.
|
||||
|
||||
@@ -411,7 +411,7 @@ For any non-trivial change, read the matching deep-dive first:
|
||||
| Repo navigation | `docs/architecture/REPOSITORY_MAP.md` |
|
||||
| Architecture | `docs/architecture/ARCHITECTURE.md` |
|
||||
| Engineering reference | `docs/architecture/CODEBASE_DOCUMENTATION.md` |
|
||||
| Auto-Combo (14-factor scoring, 19 strategies) | `docs/routing/AUTO-COMBO.md` |
|
||||
| Auto-Combo (15-factor scoring, 19 strategies) | `docs/routing/AUTO-COMBO.md` |
|
||||
| Resilience (3 mechanisms) | `docs/architecture/RESILIENCE_GUIDE.md` |
|
||||
| Reasoning replay | `docs/routing/REASONING_REPLAY.md` |
|
||||
| Skills framework | `docs/frameworks/SKILLS.md` |
|
||||
|
||||
@@ -19,23 +19,31 @@ RUN apt-get update \
|
||||
FROM base AS builder
|
||||
WORKDIR /app
|
||||
|
||||
COPY . .
|
||||
# Cache dependency layer
|
||||
COPY package.json bun.lock* pnpm-workspace.yaml* ./
|
||||
COPY open-sse/package.json ./open-sse/package.json
|
||||
COPY packages/ ./packages/
|
||||
|
||||
# Root postinstall helpers needed during bun install lifecycle
|
||||
COPY scripts/build/ ./scripts/build/
|
||||
COPY scripts/dev/sync-env.mjs ./scripts/dev/sync-env.mjs
|
||||
|
||||
# Fast Bun native package install
|
||||
RUN bun install --include=optional --quiet
|
||||
|
||||
# Compile native better-sqlite3 Node-API addon under Bun
|
||||
RUN if [ -d "node_modules/better-sqlite3" ]; then \
|
||||
(cd node_modules/better-sqlite3 && bunx node-gyp rebuild); \
|
||||
fi
|
||||
|
||||
# Fetch tls-client-node native binary if script exists
|
||||
RUN if [ -f "node_modules/tls-client-node/scripts/postinstall.js" ]; then \
|
||||
RUN if [ -f "node_modules/tls-client-node/scripts/postinstall.js" ] && [ ! -d "node_modules/tls-client-node/bin" ]; then \
|
||||
bun node_modules/tls-client-node/scripts/postinstall.js || true; \
|
||||
fi
|
||||
|
||||
# Disable Turbopack for Bun builder stage (Turbopack V8 internal worker bindings require Node)
|
||||
ENV OMNIROUTE_USE_TURBOPACK=0
|
||||
# Smoke check native database driver used by Bun (bun:sqlite)
|
||||
RUN bun -e "import { Database } from 'bun:sqlite'; const db = new Database(':memory:'); db.query('SELECT 1 AS ok').get(); db.close(); console.log('bun:sqlite smoke: OK');"
|
||||
|
||||
COPY . .
|
||||
|
||||
# Turbopack is supported on Bun 1.4 + Next 16.3; override via --build-arg OMNIROUTE_USE_TURBOPACK=0 if needed
|
||||
ARG OMNIROUTE_USE_TURBOPACK=1
|
||||
ENV OMNIROUTE_USE_TURBOPACK=${OMNIROUTE_USE_TURBOPACK}
|
||||
|
||||
ARG OMNIROUTE_BASE_PATH=""
|
||||
ENV OMNIROUTE_BASE_PATH=$OMNIROUTE_BASE_PATH
|
||||
@@ -65,6 +73,7 @@ RUN apt-get update \
|
||||
libsecret-1-0 \
|
||||
ca-certificates \
|
||||
curl \
|
||||
sqlite3 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV NODE_ENV=production
|
||||
@@ -76,11 +85,23 @@ ENV DATA_DIR=/app/data
|
||||
RUN mkdir -p /app/data
|
||||
|
||||
COPY --from=builder /app/.build/next/standalone ./
|
||||
COPY --from=builder /app/node_modules/better-sqlite3 ./node_modules/better-sqlite3
|
||||
|
||||
ENV OMNIROUTE_MIGRATIONS_DIR=/app/migrations
|
||||
|
||||
COPY --from=builder /app/scripts/dev/healthcheck.mjs ./healthcheck.mjs
|
||||
|
||||
# Bun uses bun:sqlite. Remove every standalone/vendor copy of the Node-only
|
||||
# addon so no traced chunk can dlopen it and abort the process before fallback.
|
||||
RUN find /app \
|
||||
-path '*/node_modules/better-sqlite3' \
|
||||
-prune \
|
||||
-exec rm -rf '{}' + \
|
||||
&& test -z "$(find /app -type f -name 'better_sqlite3.node' -print -quit)"
|
||||
|
||||
RUN chown -R bun:bun /app /app/data
|
||||
|
||||
USER bun
|
||||
|
||||
EXPOSE 20128
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \
|
||||
@@ -141,6 +162,7 @@ RUN apt-get update \
|
||||
ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
|
||||
ENV PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/chromium
|
||||
|
||||
# Return to the base image non-root user after the apt install (mirrors the
|
||||
# Node Dockerfile runner-web stage, which re-asserts USER node).
|
||||
# Drop back to default non-root user
|
||||
USER bun
|
||||
|
||||
ENTRYPOINT ["bun", "dev/run-standalone.mjs"]
|
||||
|
||||
@@ -424,7 +424,7 @@ All **19** strategies — mix & match per combo step:
|
||||
<tr>
|
||||
<td align="center">16</td>
|
||||
<td nowrap><code>lkgp</code></td>
|
||||
<td>Last-Known-Good Path — sticky to the last successful target</td>
|
||||
<td>Last-Known-Good Path — pins to the last successful provider, then falls back to rules</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">17</td>
|
||||
@@ -1202,7 +1202,7 @@ Métricas canônicas em 2026-08-24: **1.029 vídeos únicos** · **11.132.922 vi
|
||||
<tr><td nowrap><b>Runtime</b></td><td>Node.js 22.x / 24.x LTS — <code>>=22.22.2 <23 || >=24.0.0 <27</code></td></tr>
|
||||
<tr><td nowrap><b>Language</b></td><td>TypeScript 6.0 — <b>100% TypeScript</b> across <code>src/</code> and <code>open-sse/</code> (zero <code>any</code> in core since v2.0)</td></tr>
|
||||
<tr><td nowrap><b>Framework</b></td><td>Next.js 16 + React 19 + Tailwind CSS 4</td></tr>
|
||||
<tr><td nowrap><b>Database</b></td><td>better-sqlite3 (SQLite, WAL journaling) + LowDB (JSON legacy) — 120 domain modules, 159 migrations</td></tr>
|
||||
<tr><td nowrap><b>Database</b></td><td>better-sqlite3 (SQLite, WAL journaling) + LowDB (JSON legacy) — 120 domain modules, 160 migrations</td></tr>
|
||||
<tr><td nowrap><b>Memory</b></td><td>SQLite FTS5 full-text + int8-quantized vector embeddings, typed decay</td></tr>
|
||||
<tr><td nowrap><b>Schemas</b></td><td>Zod 4 — MCP tool I/O validation + API contracts</td></tr>
|
||||
<tr><td nowrap><b>Protocols</b></td><td>MCP (stdio / HTTP / SSE) + A2A v0.3 (JSON-RPC 2.0 + SSE)</td></tr>
|
||||
|
||||
@@ -24,9 +24,9 @@ function wantsProviderSetup(opts) {
|
||||
return opts.addProvider || Boolean(opts.provider) || Boolean(opts.apiKey);
|
||||
}
|
||||
|
||||
async function resolvePassword(opts, prompt, nonInteractive) {
|
||||
if (opts.password) return opts.password;
|
||||
if (process.env.INITIAL_PASSWORD) return process.env.INITIAL_PASSWORD;
|
||||
async function resolvePassword(opts, prompt, nonInteractive, settings) {
|
||||
if (opts.password !== undefined) return opts.password;
|
||||
if (!settings.password && process.env.INITIAL_PASSWORD) return process.env.INITIAL_PASSWORD;
|
||||
if (nonInteractive) return "";
|
||||
|
||||
const answer = await prompt.ask("Set an admin password now? [y/N]", "N");
|
||||
@@ -41,9 +41,9 @@ async function resolvePassword(opts, prompt, nonInteractive) {
|
||||
}
|
||||
|
||||
async function setupPassword(db, opts, prompt, nonInteractive) {
|
||||
const password = await resolvePassword(opts, prompt, nonInteractive);
|
||||
const settings = getSettings(db);
|
||||
const password = await resolvePassword(opts, prompt, nonInteractive, settings);
|
||||
if (!password) {
|
||||
const settings = getSettings(db);
|
||||
if (!settings.password) {
|
||||
updateSettings(db, { requireLogin: false });
|
||||
}
|
||||
|
||||
@@ -26,6 +26,17 @@ let resolvedCached = null;
|
||||
export async function loadSqliteRuntime() {
|
||||
if (resolvedCached) return resolvedCached;
|
||||
|
||||
if (process.versions.bun) {
|
||||
try {
|
||||
const bunSqlite = await import("bun:sqlite");
|
||||
resolvedCached = {
|
||||
driver: { kind: "bun-sqlite", Database: bunSqlite.Database },
|
||||
source: "bun-sqlite",
|
||||
};
|
||||
return resolvedCached;
|
||||
} catch {}
|
||||
}
|
||||
|
||||
const bundled = await tryLoadBundled();
|
||||
if (bundled) {
|
||||
resolvedCached = { driver: bundled, source: "bundled" };
|
||||
|
||||
1
changelog.d/features/11471-bun-turbopack.md
Normal file
@@ -0,0 +1 @@
|
||||
- **build(bun):** allow Turbopack bundler flag on Bun 1.4+ with configurable Webpack fallback ([#11471](https://github.com/diegosouzapw/OmniRoute/pull/11471)) — thanks @TheDemonTuan
|
||||
@@ -0,0 +1 @@
|
||||
- **feat(rankings):** the Free Provider Rankings page shows what each provider actually served over the last 24 h. It ranked by ELO alone, which left a provider that answers every call with an error in first place; the usage data was already served by the API but never requested. A provider with too small a sample shows a dash, not a number ([#11546](https://github.com/diegosouzapw/OmniRoute/pull/11546))
|
||||
1
changelog.d/features/nimble-search-and-fetch.md
Normal file
@@ -0,0 +1 @@
|
||||
- **feat(providers):** add **Nimble** as a web-search and web-fetch provider (`nimble-search`) — `/v1/search` routes to Nimble's search API at `lite` depth (locale, freshness and include/exclude domain filters mapped onto the shared request contract), and `/v1/web/fetch` routes to Nimble Extract, which covers all four fetch formats (`markdown`, `html`, `links`, `screenshot`) from a single call. One API key serves both surfaces.
|
||||
1
changelog.d/features/opper-provider.md
Normal file
@@ -0,0 +1 @@
|
||||
- **feat(providers):** Add **Opper** as an API-key gateway provider — EU-hosted AI gateway with 700+ models from 30+ providers behind one OpenAI-compatible API and one key (`OPPER_API_KEY`); model ids use `provider/model` format (e.g. `anthropic/claude-sonnet-4-6`, `openai/gpt-5`); live model catalog at `https://api.opper.ai/v3/compat/models`; entry mirrors `requesty` (same shape, `passthroughModels: true`, no static seed)
|
||||
@@ -0,0 +1 @@
|
||||
- **Provider connections:** keep `tokenExpiresAt` when a connection is created. The create-path allowlist omitted it, so every insert stored NULL and the dashboard token badge could read a fresh connection as expired until its first background refresh ([#11368](https://github.com/diegosouzapw/OmniRoute/pull/11368)).
|
||||
1
changelog.d/fixes/11468-bun-sqlite-startup.md
Normal file
@@ -0,0 +1 @@
|
||||
- **fix(bun):** use native `bun:sqlite` in `bootstrap-env` and `sync-env` to avoid loading `better-sqlite3` N-API addon during Bun startup ([#11468](https://github.com/diegosouzapw/OmniRoute/pull/11468)) — thanks @TheDemonTuan
|
||||
1
changelog.d/fixes/11470-dockerfile-bun-install-sqlite.md
Normal file
@@ -0,0 +1 @@
|
||||
- **fix(docker-bun):** make `Dockerfile.bun` install reliable with pre-install script helpers and native `bun:sqlite` smoke check ([#11470](https://github.com/diegosouzapw/OmniRoute/pull/11470)) — thanks @TheDemonTuan
|
||||
1
changelog.d/fixes/11482-bun-runtime-native-addon.md
Normal file
@@ -0,0 +1 @@
|
||||
- **fix(docker-bun):** remove every vendored `better-sqlite3` native addon from the Bun runtime image so startup cannot abort before the `bun:sqlite` fallback ([#11482](https://github.com/diegosouzapw/OmniRoute/pull/11482)) — thanks @TheDemonTuan
|
||||
1
changelog.d/fixes/11492-taskfitness-scores-as.md
Normal file
@@ -0,0 +1 @@
|
||||
- **fix(autoCombo):** effort/alias model variants (`gpt-5.6-sol-xhigh`, `gpt-5.6`, cursor's `claude-4.6-opus-high`) inherit their base model's task fitness instead of falling to the wildcard 0.5 ([#11492](https://github.com/diegosouzapw/OmniRoute/pull/11492))
|
||||
1
changelog.d/fixes/11506-arena-elo-base-rows.md
Normal file
@@ -0,0 +1 @@
|
||||
- **fix(intelligence):** Arena ELO sync stores a synthesized base-model row for every effort/harness variant (`claude-opus-5-max` → `claude-opus-5`, `gpt-5.6-sol-xhigh (codex-harness)` → `gpt-5.6-sol`), so bare model requests reach the synced intelligence layer instead of the static fallback table; the hand-maintained `MODEL_ALIAS_MAP` — which collapsed generations (`gpt-5.5` → `gpt-5`) — is gone ([#11506](https://github.com/diegosouzapw/OmniRoute/pull/11506))
|
||||
1
changelog.d/fixes/11507-catalog-hygiene.md
Normal file
@@ -0,0 +1 @@
|
||||
- **fix(autoCombo,sse):** catalog hygiene — the static task-fitness table no longer ranks retired models above live ones (dead rows dropped, patterns matched on segment boundaries), the 7 deprecation aliases that forwarded to retired or non-existent models now point at the vendors' published replacements, an alias is no longer rewritten when the serving provider offers the id as-is, and a new `check:model-lifecycle` gate diffs both tables against a vendor lifecycle snapshot ([#11507](https://github.com/diegosouzapw/OmniRoute/pull/11507))
|
||||
1
changelog.d/fixes/11523-stale-release-docker-skip.md
Normal file
@@ -0,0 +1 @@
|
||||
- Treat Docker publishing from a non-default release branch as an expected skip instead of a failed workflow, while preserving the guard that prevents it from overwriting the `next` channel.
|
||||
@@ -0,0 +1 @@
|
||||
- fix(search): prefer credentialed providers over duckduckgo-free fallback (#11524) — the fallback-only loop ran before the credentialed-providers loop in `executeWebSearch`, making configured providers unreachable when `duckduckgo-free` was available.
|
||||
@@ -0,0 +1 @@
|
||||
- **fix(ci):** protocol-clients E2E harness boots the peer-stamped custom server (`run-next.mjs dev`) instead of the bare `next` CLI, so `LOCAL_ONLY` locality resolves from the real TCP peer stamp and `/api/mcp/audit` answers 200 (open bootstrap preserved via an `OMNIROUTE_E2E_BOOTSTRAP_MODE=open` credential clear in `run-next.mjs`, pinned to loopback `HOST`) instead of a deterministic 403 (#11535)
|
||||
1
changelog.d/fixes/11545-scoring-factor-count.md
Normal file
@@ -0,0 +1 @@
|
||||
- **fix(docs):** the Auto-Combo engine is described with the number of factors it actually declares. Four different counts were in circulation — 6, 9, 13 and 14 across `AGENTS.md`, four guides and six code comments — while `DEFAULT_WEIGHTS` declares 15. `check:docs-counts` now reads that number from the source, so adding a factor without updating the prose fails CI ([#11545](https://github.com/diegosouzapw/OmniRoute/pull/11545))
|
||||
1
changelog.d/fixes/11547-quota-share-inflight-lease.md
Normal file
@@ -0,0 +1 @@
|
||||
- **fix(quota-share):** in-flight leases are per request, so an aborted request's slot ages out instead of being kept alive by later traffic on the same connection ([#11547](https://github.com/diegosouzapw/OmniRoute/pull/11547)) — thanks @abhisheksharma2411
|
||||
@@ -0,0 +1 @@
|
||||
- The free-tier summary route now serves the refreshed Radar catalog when the feed is active — the same numbers the dashboard shows — and states which catalog answered plus its real build date, instead of always reporting release-frozen figures with a stale curation date. The supporter-key live feed stays reserved to authenticated callers of the instance.
|
||||
@@ -0,0 +1 @@
|
||||
- fix(chat): shed any of the matched provider-node's routing identifiers (public prefix or internal id) before model lookup, so composites like `<connId>/<connId>/<model>` no longer reach upstream verbatim (#11557)
|
||||
1
changelog.d/fixes/11573-semantic-cache-ttl.md
Normal file
@@ -0,0 +1 @@
|
||||
- **fix(cache):** a semantic-cache entry now expires on its TTL instead of surviving until the next UTC midnight, and `dbEntries` stops counting expired rows ([#11573](https://github.com/diegosouzapw/OmniRoute/pull/11573))
|
||||
1
changelog.d/fixes/11574-v1-models-after-scheduler.md
Normal file
@@ -0,0 +1 @@
|
||||
- **fix(api):** `/v1/models` schedules its stale-while-revalidate rebuild through Next's `after()` again, so a stale catalog reaches the client before the rebuild blocks the event loop ([#11574](https://github.com/diegosouzapw/OmniRoute/pull/11574))
|
||||
1
changelog.d/fixes/11582-known-symbols-async-executor.md
Normal file
@@ -0,0 +1 @@
|
||||
- **fix(check):** the `known-symbols` executor conformance gate awaits the now-async `getExecutor()`, so it stops reporting all 142 registered aliases as dead symbols and can detect a lazy import that fails ([#11582](https://github.com/diegosouzapw/OmniRoute/pull/11582))
|
||||
@@ -0,0 +1 @@
|
||||
- **fix(pack):** register `bin/cli/utils/volatileEnvPath.mjs` in `PACK_ARTIFACT_REQUIRED_PATHS`, so the prune can no longer silently drop a module the published CLI imports on every boot ([#11588](https://github.com/diegosouzapw/OmniRoute/pull/11588))
|
||||
1
changelog.d/fixes/11589-i18n-vi-reliability.md
Normal file
@@ -0,0 +1 @@
|
||||
- **i18n(vi):** translate the five reliability-column strings on the free-provider rankings page, which rendered as `__MISSING__:` markers in the Vietnamese UI ([#11589](https://github.com/diegosouzapw/OmniRoute/pull/11589))
|
||||
1
changelog.d/fixes/11595-combo-success-rate-scale.md
Normal file
@@ -0,0 +1 @@
|
||||
- **fix(dashboard):** Provider Stats now displays combo success rates on their native 0–100 percentage scale instead of multiplying them twice ([#11595](https://github.com/diegosouzapw/OmniRoute/pull/11595)) — thanks @pacocartones
|
||||
1
changelog.d/fixes/11597-duckduckgo-web-duckai.md
Normal file
@@ -0,0 +1 @@
|
||||
- **fix(providers):** route DuckDuckGo Web Chat through the verified `duck.ai` endpoint, refresh its free model catalog, and avoid forwarding unsolved anti-abuse challenges ([#11597](https://github.com/diegosouzapw/OmniRoute/pull/11597))
|
||||
@@ -0,0 +1 @@
|
||||
- **fix(ui):** Console log Refresh and Copy controls now expose localized accessible names, keep copy actions visible on keyboard focus, and announce copy completion safely ([#11599](https://github.com/diegosouzapw/OmniRoute/pull/11599)) — thanks @pacocartones
|
||||
1
changelog.d/fixes/11602-provider-allowlist.md
Normal file
@@ -0,0 +1 @@
|
||||
- fix(handoff): enforce provider allowlist for universal handoff (#11602) — universal handoff now skips summarization when the selected summary model's provider is not included in the configured provider allowlist.
|
||||
@@ -0,0 +1 @@
|
||||
- **fix(dashboard):** Show a stable error state when Search Analytics returns an HTTP error or malformed data ([#11603](https://github.com/diegosouzapw/OmniRoute/pull/11603)) — thanks @pacocartones
|
||||
1
changelog.d/fixes/11604-profile-xp-consistency.md
Normal file
@@ -0,0 +1 @@
|
||||
- **fix(dashboard):** Keep the Profile level and progress aligned with aggregate XP, including bounded handling for invalid totals ([#11604](https://github.com/diegosouzapw/OmniRoute/pull/11604)) — thanks @pacocartones
|
||||
1
changelog.d/fixes/11605-profile-hidden-badge-details.md
Normal file
@@ -0,0 +1 @@
|
||||
- **fix(dashboard):** Prevent locked hidden badges from revealing their icon or opening private badge details before they are earned ([#11605](https://github.com/diegosouzapw/OmniRoute/pull/11605)) — thanks @pacocartones
|
||||
1
changelog.d/fixes/11607-modal-focus-restoration.md
Normal file
@@ -0,0 +1 @@
|
||||
- **fix(dashboard):** Restore keyboard focus after shared modals close and cancel delayed autofocus during cleanup ([#11607](https://github.com/diegosouzapw/OmniRoute/pull/11607)) — thanks @pacocartones
|
||||
1
changelog.d/fixes/11610-datatable-keyboard-activation.md
Normal file
@@ -0,0 +1 @@
|
||||
- **fix(dashboard):** Enable Enter and Space activation for clickable data-table rows without hijacking nested controls ([#11610](https://github.com/diegosouzapw/OmniRoute/pull/11610)) — thanks @pacocartones
|
||||
1
changelog.d/fixes/11625-retired-pool.md
Normal file
@@ -0,0 +1 @@
|
||||
- **fix(autoCombo,sse):** vendor-retired catalog ids are dropped from the auto-combo candidate pool and no longer win on leftover `arena_elo` / `user_override` rows; `getModelLifecycleDecision` consults `model-lifecycle.json` (prefix-stripped) so aggregator traffic is not `untracked` for ids the snapshot already knows ([#11625](https://github.com/diegosouzapw/OmniRoute/issues/11625))
|
||||
1
changelog.d/fixes/7592-windows-packaged-smoke.md
Normal file
@@ -0,0 +1 @@
|
||||
- **fix(electron):** the packaged Windows desktop build now passes the #7592 cold-restart smoke end to end. Five defects were found and fixed on the way: (1) optional-pack staging failed on any machine whose `tar` is GNU tar — it reads the drive letter in an absolute `-f C:\...` archive path as a remote rsh host (`Cannot connect to C:`), so staging now passes a bare filename with `cwd` at the tarball directory and surfaces tar stderr on failure; (2) the Electron `files` allowlist was missing `lib/loginHeaderCapture.js`, so the packaged main process crashed at startup with `Cannot find module './lib/loginHeaderCapture'`; (3) electron-builder ≥26 injects an `!**/node_modules/**` ignore into every extraResources pattern list that no positive filter can override, which silently dropped the staged runtime `node_modules` (including the better-sqlite3 N-API prebuild) from `resources/app` — a fresh v3.8.50 desktop build would have shipped with no native SQLite driver and reproduced the #7592 sql.js fallback on every machine; an `afterPack` hook now restores the staged `node_modules` after packing; (4) the packaged-app smoke harness redirected `USERPROFILE` into its temp DATA_DIR, but Electron resolves the Roaming profile from `%USERPROFILE%\AppData\Roaming\<name>` (USERPROFILE takes precedence over the APPDATA env var) and the path service throws instead of creating it, so `requestSingleInstanceLock()` returned false and the app exited(0) silently before `app.whenReady()` — the harness now pre-creates the derived tree, and `ensureSmokeEnvDirs` is exported and unit-tested; (5) the #7592 driver assertion parsed a `[DB] Driver: ...` line that the server's primary DB path never printed (only the unused `openDatabaseAsync()` did) — `getDbInstance()` now emits the same line on open so the guard can actually assert the native driver. Also: the smoke env-allowlist unit test hardcoded POSIX paths and could only pass on Linux/macOS; expectations are now host-agnostic, with new regression tests for the USERPROFILE-derived tree and `tarPack` under absolute Windows-style paths
|
||||
1
changelog.d/fixes/autocombo-tier-lifecycle-11508.md
Normal file
@@ -0,0 +1 @@
|
||||
- **fix(autoCombo):** layer 3 (`models_dev_tier`) no longer scores retired models as premium, merge cross-provider capability rows deterministically, and inherit tier scores through variant ids ([#11508](https://github.com/diegosouzapw/OmniRoute/issues/11508)). `getModelsDevTierFitness` now vetoes ids present in `config/quality/model-lifecycle.json` with status `retired` before any other signal; `loadModelCapabilities()` aggregates per `model_id` (any-non-null-true for booleans, max for `limit_context`) instead of last-write-wins over SQLite's undefined row order; a capabilities miss retries through `resolveScoresAs()`'s base id and reports `models_dev_tier:inherited`, matching layers 1–2 (#11492). Adds `getModelsDevTierFitnessWithSource()` and an `invalidateCapabilitiesCache()` test/ops hook.
|
||||
1
changelog.d/fixes/claude-code-model-probe-max-tokens.md
Normal file
@@ -0,0 +1 @@
|
||||
- fix(sse): accept Claude `content:[]` + `stop_reason: max_tokens`/`tool_use` in `detectMalformedNonStream` (match `isEmptyContentResponse`) so Claude Code `/model` probes with `max_tokens: 1` no longer become a false 502
|
||||
1
changelog.d/fixes/duckduckgo-stream-chunk-boundaries.md
Normal file
@@ -0,0 +1 @@
|
||||
- Fixed DuckDuckGo streaming responses losing JSON lines and UTF-8 characters split across network chunks.
|
||||
1
changelog.d/fixes/generated-relay-header-sanitization.md
Normal file
@@ -0,0 +1 @@
|
||||
- Harden generated Cloudflare, Vercel, and Deno relays by stripping hop-by-hop, framing, and proxy authentication headers before forwarding requests upstream.
|
||||
1
changelog.d/fixes/oss026-auto-router-connection-id.md
Normal file
@@ -0,0 +1 @@
|
||||
- Fixed auto-router strategies preserving the selected connection through ranking and dispatch when multiple connections share the same provider and model.
|
||||
1
changelog.d/fixes/oss026-chat-responses-json-object.md
Normal file
@@ -0,0 +1 @@
|
||||
- Preserve Chat Completions JSON-object response formats when translating requests to the Responses API.
|
||||
@@ -0,0 +1 @@
|
||||
- Fix idempotency fingerprints so Responses API requests include `input` and other semantic generation fields using stable serialization, while excluding credentials and request metadata.
|
||||
@@ -0,0 +1 @@
|
||||
- **fix(sessions):** preserve legacy Sessions data when the additive exclusive-session projection is unavailable, returning an empty projection and warning only once per contiguous outage instead of failing the endpoint; the Sessions badge intentionally reflects the merged legacy and exclusive row count introduced by [#11389](https://github.com/diegosouzapw/OmniRoute/pull/11389)
|
||||
1
changelog.d/fixes/quota-card-footer-flex-wrap.md
Normal file
@@ -0,0 +1 @@
|
||||
- fix(ui): wrap quota card footer action buttons to prevent clipping Refresh button on narrow cards — when extra action buttons such as `View credits` are present on Codex cards, allow the footer row to flex-wrap with `shrink-0` buttons so `Refresh now` remains visible and clickable across all responsive card widths
|
||||
1
changelog.d/fixes/tailscale-port-and-windows-path.md
Normal file
@@ -0,0 +1 @@
|
||||
- Fixed Tailscale tunnel setup to reject ports outside the valid 1-65535 range and safely install Windows MSI packages from paths containing apostrophes.
|
||||
1
changelog.d/fixes/tunnel-process-routes-local-only.md
Normal file
@@ -0,0 +1 @@
|
||||
- Classify Cloudflared and Tailscale process-management routes as local-only and spawn-capable while preserving remote access to read-only tunnel status endpoints.
|
||||
1
changelog.d/maintenance/11502-release-v3851-basereds.md
Normal file
@@ -0,0 +1 @@
|
||||
- **chore(release):** clear the `release/v3.8.51` base-red gates — docs migration count (+38 i18n mirrors), stryker `tap.testFiles`, lockfile registry host, stale ESLint suppressions, the 7 lint regressions they were hiding, the stale `APIKEY_PROVIDERS` partition count (231 → 233), the `glm-5.3-max` tier missing from the GLM test table, a dead `modelType === "chat"` comparison in the models catalog, and the `resolveLiveWsUrl` / `sanitizeLiveWsPort` helpers from #11388 that a later merge dropped from `wsPath.ts` (dashboard live WebSocket URL resolution) ([#11502](https://github.com/diegosouzapw/OmniRoute/pull/11502))
|
||||
@@ -0,0 +1 @@
|
||||
- **chore(free-models):** the free-tier regime table now declares which totals figure each regime feeds and whether it may take the no-auth shortcut, so the sets that used to repeat those answers by hand are derived from it — a new `freeType` no longer compiles until it has answered every question, instead of silently contributing to no total ([#11537](https://github.com/diegosouzapw/OmniRoute/pull/11537))
|
||||
@@ -0,0 +1 @@
|
||||
- **docs(routing):** LKGP strategy copy now states provider-level stickiness and the explicit rules fallback instead of promising per-target pinning ([#11555](https://github.com/diegosouzapw/OmniRoute/pull/11555))
|
||||
@@ -0,0 +1 @@
|
||||
- **test(chatcore):** pin the response tool-name alias resolution against the ordering hazard that broke every Gemini/Antigravity MCP tool call in v3.8.49. `extractRequestToolIdentityMap` deletes `translatedBody._toolNameMap`, so the later read is always undefined and the ledger survives only through the `requestToolIdentityMap` fallback — removing that fallback previously left the entire tool-name suite green. The resolution moves into `resolveResponseToolNameMap()` next to the map it depends on, with a regression guard that fails without the recovery. No behaviour change. ([#11575](https://github.com/diegosouzapw/OmniRoute/pull/11575))
|
||||
@@ -0,0 +1 @@
|
||||
- **docs(env):** document `OMNIROUTE_CORPUS_CACHE_SIZE` in `.env.example` and `ENVIRONMENT.md`, so the env/docs contract check stops failing Docs Gates on every branch ([#11576](https://github.com/diegosouzapw/OmniRoute/pull/11576))
|
||||
1
changelog.d/maintenance/11577-stryker-tap-testfiles.md
Normal file
@@ -0,0 +1 @@
|
||||
- **chore(stryker):** register `route-guard-tunnel-processes-local-only` and `universal-quota-aware-routing` in `tap.testFiles`, so their mutant kills count for the three modules they cover ([#11577](https://github.com/diegosouzapw/OmniRoute/pull/11577))
|
||||
@@ -0,0 +1 @@
|
||||
- **test(authz):** pin `LOCAL_ONLY_API_GET_EXEMPTIONS` by exact membership instead of by entry count, so the guard names the offending path and also catches a substitution ([#11580](https://github.com/diegosouzapw/OmniRoute/pull/11580))
|
||||
1
changelog.d/maintenance/11583-bundler-flag-contract.md
Normal file
@@ -0,0 +1 @@
|
||||
- **test(build):** pin `resolveNextBuildBundlerFlag` to the `OMNIROUTE_USE_TURBOPACK` contract it implements, across runtimes, instead of asserting an unimplemented Bun override ([#11583](https://github.com/diegosouzapw/OmniRoute/pull/11583))
|
||||
@@ -0,0 +1 @@
|
||||
- **test(claude-web):** the Claude Web transport test's barrel anchors no longer pin the exact construction spelling. #11421 made the executor map lazy, so `/"claude-web": new ClaudeWebExecutor\(\)/` stopped matching and the test went red on `release/v3.8.51` itself — a base-red gate every open PR inherited. The anchors now match the alias key and the class name and tolerate either spelling in between, and were checked to still fail when an alias is genuinely repointed at another executor ([#11585](https://github.com/diegosouzapw/OmniRoute/pull/11585))
|
||||
@@ -0,0 +1 @@
|
||||
- **test(models):** pin `qwen3.8-max` resolution per provider — two of the four catalogs now serve the bare id and no longer carry `-preview` ([#11590](https://github.com/diegosouzapw/OmniRoute/pull/11590))
|
||||
@@ -0,0 +1 @@
|
||||
- **test(executors):** drop the stale 128-tool truncation assertion that contradicted the #11444 pass-through contract ([#11591](https://github.com/diegosouzapw/OmniRoute/pull/11591))
|
||||
@@ -0,0 +1 @@
|
||||
- **test(token-health):** pin the current terminal-skip boundary — expired with retry budget is probed, `account_deactivated` stays skipped ([#11592](https://github.com/diegosouzapw/OmniRoute/pull/11592))
|
||||
1
changelog.d/maintenance/11593-gemini-alias-target.md
Normal file
@@ -0,0 +1 @@
|
||||
- **test(models):** follow #11503's retarget of the `gemini-3-pro-high` alias to the hyphenated catalog id ([#11593](https://github.com/diegosouzapw/OmniRoute/pull/11593))
|
||||
@@ -159,11 +159,6 @@
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"open-sse/executors/index.ts": {
|
||||
"@typescript-eslint/no-unused-vars": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"open-sse/executors/kiro.ts": {
|
||||
"@typescript-eslint/no-unused-vars": {
|
||||
"count": 3
|
||||
@@ -476,11 +471,6 @@
|
||||
"count": 2
|
||||
}
|
||||
},
|
||||
"open-sse/services/autoCombo/routerStrategy.ts": {
|
||||
"@typescript-eslint/no-unused-vars": {
|
||||
"count": 2
|
||||
}
|
||||
},
|
||||
"open-sse/services/bailianQuotaFetcher.ts": {
|
||||
"no-restricted-syntax": {
|
||||
"count": 1
|
||||
@@ -2372,16 +2362,6 @@
|
||||
"count": 2
|
||||
}
|
||||
},
|
||||
"src/lib/guardrails/videoBridgeContactSheet.ts": {
|
||||
"@typescript-eslint/no-unused-vars": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"src/lib/guardrails/videoBridgeRuntime.ts": {
|
||||
"@typescript-eslint/no-unused-vars": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"src/lib/guardrails/visionBridgeHelpers.ts": {
|
||||
"@typescript-eslint/no-unused-vars": {
|
||||
"count": 1
|
||||
@@ -3113,11 +3093,6 @@
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"src/sse/services/auth.ts": {
|
||||
"@typescript-eslint/no-unused-vars": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"src/sse/services/model.ts": {
|
||||
"no-restricted-imports": {
|
||||
"count": 2
|
||||
@@ -4130,7 +4105,7 @@
|
||||
},
|
||||
"tests/unit/cli-oneproxy-commands.test.ts": {
|
||||
"@typescript-eslint/no-explicit-any": {
|
||||
"count": 14
|
||||
"count": 13
|
||||
},
|
||||
"@typescript-eslint/no-unused-vars": {
|
||||
"count": 1
|
||||
@@ -6617,4 +6592,4 @@
|
||||
"count": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -310,7 +310,7 @@
|
||||
"_rebaseline_2026_07_27_v3849_train1h": "Merge-train 1H (31 PRs) — owner-approved 2026-07-27. Two distinct causes, kept separate on purpose: (1) GENUINE irreducible growth at existing chokepoints — providerLimits/auth (#8632 Kimi quota-reset recovery), rateLimitManager (#8616 idle wedged limiters), models-catalog-route.test (#8610 OpenCode Go effort aliases); (2) COLLISION with #8585, which banked shrinks measured on the pre-train release tip while 30 sibling PRs in the SAME train grew those files again — chat/accountFallback (#8628), chatCore (#8613), videoGeneration (#8581), imageGeneration. The zero-headroom frozen entries cannot absorb either. Ceilings re-pinned to the post-merge tip; #8612 (also in this train) automates shrink-banking so this self-inflicted drift stops recurring. Detail: src/lib/usage/providerLimits.ts 1006->1013 (#8632); src/sse/services/auth.ts 2492->2508 (#8632); open-sse/services/rateLimitManager.ts 1014->1060 (#8616); src/sse/handlers/chat.ts 1842->1845 (#8628); open-sse/handlers/chatCore.ts 4939->4955 (#8613); open-sse/handlers/imageGeneration.ts 3100->3101 ((sem PR — teto do #8585)); open-sse/handlers/videoGeneration.ts 1038->1063 (#8581); open-sse/services/accountFallback.ts 1965->1966 (#8628); tests/unit/models-catalog-route.test.ts 1608->1636 (#8610)",
|
||||
"frozen": {
|
||||
"_rebaseline_2026_08_20_10878_10799_provider_health_probes": "PRs #10878 (unsupported OpenAI-like validation probes stay neutral) + #10799 (preserve credential health on inconclusive NVIDIA-timeout/Antigravity-400 probes) own growth: src/app/api/providers/[id]/test/route.ts 946->1025 (+79, sum of both boarded together). Both add narrowly-scoped classification branches at the existing test-route dispatch chokepoint (unsupported-capability skip, credential-inconclusive detection) rather than new files, mirroring the prior 2026_06_27_5193 rebaseline of the same file. Covered by tests/unit/provider-validation-unsupported-neutral.test.ts + tests/unit/provider-health-inconclusive-probes.test.ts.",
|
||||
"src/app/api/providers/[id]/test/route.ts": 1237,
|
||||
"src/app/api/providers/[id]/test/route.ts": 1262,
|
||||
"_rebaseline_2026_08_23_11141_oauth_400_recovery": "PR #11141 (HouMinXi) own growth: test/route.ts 1025->1215 (+190, the reactive-400 recovery path — a fully rebuilt probe for refresh+retry on refreshable non-rotating connections, with inconclusive-status preservation and rotating-provider exclusion; all growth is the new probe builder + guards at the existing test-route dispatch, extraction would split the retry flow mid-logic). Covered by tests/unit/oauth-400-recovery.test.ts (8, bug-injection proof). Owner pre-authorized baseline bumps 2026-08-22.",
|
||||
"_rebaseline_2026_06_22_4644_deepseek_web_tools": "PR #4644 (BugsBag/robust deepseek-web tool-call parsing): open-sse/executors/deepseek-web.ts 1117->1125 (+8). The new agentic tool-call path emits surrounding text + reasoning before tool_calls and swaps to the dedicated deepseekWebTools.ts parser; the +8 lines are cohesive wiring at the existing transformSSE chokepoint (the parser itself lives in the new deepseekWebTools.ts file, already under cap). The PR's own fast-gate (PR->release) does not run check:file-size, so this surfaced only at release reconcile. Covered by tests/unit/deepseek-web-tools-variants.test.ts + deepseek-web-tools-execute.test.ts.",
|
||||
"_rebaseline_2026_06_23_4712_deepseek_web_tool_results": "PR for #4712 (deepseek-web drops role:tool): open-sse/executors/deepseek-web.ts 1125->1148 (+23). messagesToPrompt() now folds role:\"tool\" results into the single-prompt transcript (recovering the tool name from the preceding assistant tool_calls by tool_call_id) instead of silently dropping them; the lines are cohesive wiring inside the existing function. Covered by tests/unit/deepseek-web-tool-result-prompt-4712.test.ts.",
|
||||
@@ -435,7 +435,7 @@
|
||||
"src/shared/components/analytics/charts.tsx": 1346,
|
||||
"src/shared/services/cliRuntime.ts": 1459,
|
||||
"src/sse/handlers/chat.ts": 2493,
|
||||
"src/sse/services/auth.ts": 3346,
|
||||
"src/sse/services/auth.ts": 3432,
|
||||
"_rebaseline_2026_08_24_lasterror_provider_error_detail": "PR (ntdat812) own growth: src/sse/services/auth.ts 3344->3346 (+2). One line is the import of describeUpstreamFailure from @/shared/utils/upstreamError, which replaces the string-only collapse `typeof errorText === \"string\" ? errorText.slice(0, 100) : \"Provider error\"` at the single markAccountUnavailable chokepoint (net 0 lines there) — the logic itself lives in upstreamError.ts, next to the extractErrorMessage it reuses, so nothing else moved into this file. The second line is the repo's own lint-staged prettier pass splitting a pre-existing two-statements-on-one-line at getProviderCredentials (`invalidateManagedLease(...); log.warn(...)`); it re-applies on any commit that touches this file, so it is not separable from the change. Covered by tests/unit/provider-error-detail-lastError.test.ts.",
|
||||
"_rebaseline_2026_08_23_11186_synced_inventory_routing": "PR #11186 (pacocartones) own growth: src/sse/services/auth.ts 3260->3337 (+77, loadAdvertisedModelsForSelfHostedConnections + the modelNotAdvertised candidate-filter predicate — pins chat routing to the connection whose synced inventory actually advertises the model, fixing spurious model-not-found on multi-host self-hosted setups; at the existing credential-selection chokepoint, not extractable without splitting the selection flow). Covered by tests/unit/chat-routing-synced-inventory-11089.test.ts. Owner pre-authorized baseline bumps 2026-08-22.",
|
||||
"tests/unit/account-fallback-service.test.ts": 2044,
|
||||
@@ -459,7 +459,7 @@
|
||||
"_rebaseline_2026_08_22_11156_enter_check_disabled": "PR #11156 (rqzbeh) own growth: AddApiKeyModal.tsx 1080->1082 (+2, Enter keydown handler now mirrors the isCheckDisabled condition — owner-requested post-merge polish from #11056; the rest of the diff is Prettier reflow). Covered by tests/unit/ui/add-api-key-modal-enter-key.test.tsx (jsdom render test, Enter dispatch assertions).",
|
||||
"src/app/(dashboard)/dashboard/providers/[id]/hooks/useProviderConnections.ts": 1051,
|
||||
"src/shared/components/ModelSelectModal.tsx": 1138,
|
||||
"src/shared/constants/providers/apikey/gateways.ts": 1321,
|
||||
"src/shared/constants/providers/apikey/gateways.ts": 1330,
|
||||
"open-sse/vendor/codex-chatgpt-web/bridge.ts": 1387,
|
||||
"_rebaseline_2026_08_11_v3850_merge_storm_provider_registry": "DRIFT do merge-storm 2026-08-11 (99 PRs mergeados no release/v3.8.50). AddApiKeyModal.tsx (PR #8949 ChatGPT Web provider) e useProviderConnections.ts/ModelSelectModal.tsx (PRs #9011 combo test-all, #9499 image combos) = UI nova legitima acima do cap; gateways.ts = god-file de catalogo de providers que cresceu com PRs #9009/#9421/#9468/#9594 (qualquer split arriscaria corromper o merge de novo — o proprio PR #9421 quebrou o arquivo); bridge.ts (PR #8949) = ponte Chromium vendored; proxyFetch.ts 1207->1220 = drift herdado de merges. Owner autorizou rebaseline com anotacao (2026-08-11).",
|
||||
"src/lib/modelCapabilities.ts": 1072,
|
||||
@@ -479,7 +479,9 @@
|
||||
"_rebaseline_2026_08_24_11355_cooldown_recovery_guards": "PR #11355 own growth: test/route.ts 1215->1237, +22 (startup crash-recovery guard: clearStaleCrashCooldowns() now parses the persisted rate_limited_until deadline and skips clearing rows still genuinely in the future, instead of clearing every non-terminal cooldown unconditionally). Cohesive fix at the existing test-route dispatch chokepoint alongside the #11141 probe builder. Covered by tests/unit/startup-stale-cooldown-recovery.test.ts + tests/unit/repro-zai-cooldown-cleared-by-connection-test.test.ts.",
|
||||
"src/lib/guardrails/videoBridgeRuntime.ts": 1009,
|
||||
"_rebaseline_2026_08_24_video_bridge_fu02_fu07_sampler": "PRs #11344 (FU-02 one-frame scene-aware determinism) + #11381 (FU-07 opt-in segment_aware structural sampling) own growth: videoBridgeRuntime.ts <1000->1009, +9 (sum of both boarded together in the same merge-batch). #11344 adds the deterministic one-frame midpoint fallback + policyEffective=uniform report at the existing scene_aware seam; #11381 adds the bounded local-only FFmpeg structural pre-analysis pass (scene/freeze/blur/exposure/SI-TI) and its budget-reallocation logic. Covered by tests/unit/guardrails/videoBridgeSampler.test.ts, tests/unit/guardrails/videoBridgeFu07StructuralSampling.test.ts, tests/integration/video-bridge-sampler-ffmpeg.test.ts. Owner pre-authorized rebaseline for legitimate PR growth (2026-08-19 directive).",
|
||||
"open-sse/services/autoCombo/virtualFactory.ts": 1130
|
||||
"open-sse/services/autoCombo/virtualFactory.ts": 1130,
|
||||
"src/lib/cloudflaredTunnel.ts": 1078,
|
||||
"src/shared/components/RequestLoggerDetail.tsx": 1018
|
||||
},
|
||||
"_rebaseline_base_2026_08_10_proxyfetch": "Base-red fix (green-prs sweep, issue #9985): open-sse/utils/proxyFetch.ts 1207 > cap 1000 — new proxied-TLS fetch helper introduced by the Fal reference-image work. Owner-authorized quick rebaseline to green; structural slim tracked for v3.9.0.",
|
||||
"_rebaseline_2026_07_27_v3849_train2": "Merge-train 2 (7 PRs) — owner-approved 2026-07-27. Single entry: chatCore.ts 4955->5006 (#8595, Responses multi-turn image compaction before the context hard-reject). Genuine irreducible growth at the existing compaction chokepoint in handleChatCore — the PR adds a last-resort retry against the concrete budget plus the estimateFinalInputTokens helper, both wired at the pre-existing call site rather than a new branch. Covered by tests/unit/8560-responses-image-compaction.test.ts (4 tests).",
|
||||
@@ -648,5 +650,7 @@
|
||||
"_rebaseline_2026_08_20_v3850_merge_train_batch1": "Merge-train batch1 (2026-08-19/20, 30 PRs boarded onto release/v3.8.50): gateways.ts 1255->1268 = PR #10722 (Token Kiosk OpenAI-compatible provider gateway catalog entry, +13 declarative lines, same god-file no-split rationale as prior gateways.ts rebaselines); chatHelpers.ts (uncapped, not previously frozen) new 1017 = PR #10797 (relay/bifrost error normalization, +23/-2, own-PR growth, existing file already near cap from accumulated chokepoint wiring per its own rebaseline history above); chatBodyAdmission.ts (uncapped) new 1005 = pre-existing base-red on the pure release tip (1004>1000 before this train boarded anything, no PR in this batch touches this file) — frozen here at its current size, not authorizing further growth. Owner-authorized rebaseline (2026-08-19 merge-prs session).",
|
||||
"_rebaseline_2026_08_20_8338_cursor_image_provider": "PR (reimplementation of #8338, @valvesss): imageRegistry.ts 1019->1033 = new cursor IMAGE_PROVIDERS entry (Cursor plan image generation via Agent CLI), +14 lines of declarative provider metadata. Same god-registry no-split rationale as prior imageRegistry/gateways rebaselines.",
|
||||
"_rebaseline_2026_08_20_imageregistry_1034": "imageRegistry.ts 1033->1034: +1 line drift between #10842 (cursor image provider, froze at 1033) and its actual merged state on release (measured 1034) — trivial rebaseline, not a new feature.",
|
||||
"_rebaseline_2026_08_25_11146_subscription_first_auto": "PR #11146 (@yourspraveen, subscription-first auto groupings auto/subscription+auto/thrifty): open-sse/services/autoCombo/virtualFactory.ts is a NEW file in this PR landing at 1128 lines (+2 margin) — two opt-in flat auto ids built on the established auto/best-free pattern (connectionBillingCatalog + subscriptionLadder pure functions). Frozen at merge size per owner-authorized rebaseline directive (2026-08-19, merge-batch Step 4); no further growth without split rationale."
|
||||
"_rebaseline_2026_08_25_11146_subscription_first_auto": "PR #11146 (@yourspraveen, subscription-first auto groupings auto/subscription+auto/thrifty): open-sse/services/autoCombo/virtualFactory.ts is a NEW file in this PR landing at 1128 lines (+2 margin) — two opt-in flat auto ids built on the established auto/best-free pattern (connectionBillingCatalog + subscriptionLadder pure functions). Frozen at merge size per owner-authorized rebaseline directive (2026-08-19, merge-batch Step 4); no further growth without split rationale.",
|
||||
"_rebaseline_2026_08_26_mergebatch_v3851_batch1": "/merge-batch 2026-08-26 (v3.8.51): three legitimate growths from this batch. #11448 src/app/api/providers/[id]/test/route.ts 1237->1262 (auto-test-on-create wiring). #11495 src/sse/services/auth.ts 3346->3376 (web-cookie health-sweep verify-only path). #11561 src/lib/cloudflaredTunnel.ts new named-tunnel mode, lands at 1078 (+78 over the 1000 new-file cap) for the CLOUDFLARED_CONFIG named-tunnel flow (login->create->route dns config parsing + readiness detection). Owner-authorized rebaseline per merge-batch Step 4 (2026-08-19 directive); no further growth without split rationale.",
|
||||
"_rebaseline_2026_08_26_mergebatch_v3851_batch2": "/merge-batch 2026-08-26 (v3.8.51) batch 2: three legitimate growths. #11083 src/shared/components/RequestLoggerDetail.tsx new-file cap, lands at 1018 (+18 over 1000) — copy-all button for request detail modal. #11631 src/shared/constants/providers/apikey/gateways.ts 1321->1330 (1min.ai gateway entry). #11628 src/sse/services/auth.ts 3376->3432 (credential-health isolation from model failures). Owner-authorized rebaseline per merge-batch Step 4 (2026-08-19 directive); no further growth without split rationale."
|
||||
}
|
||||
|
||||
658
config/quality/model-lifecycle.json
Normal file
@@ -0,0 +1,658 @@
|
||||
{
|
||||
"//": "Vendor model lifecycle snapshot (#11503). Hand-curated from the first-party deprecation pages listed in `sources`; regenerate with `npm run quality:refresh-model-lifecycle`. Consumed by `npm run check:model-lifecycle` and by the FITNESS_TABLE / BUILT_IN_ALIASES regression tests. `replacement` is null where the vendor publishes none — never invent one.",
|
||||
"generatedAt": "2026-08-25",
|
||||
"sources": [
|
||||
"https://platform.claude.com/docs/en/about-claude/model-deprecations",
|
||||
"https://developers.openai.com/api/docs/deprecations",
|
||||
"https://ai.google.dev/gemini-api/docs/deprecations",
|
||||
"https://docs.x.ai/docs/models",
|
||||
"https://console.groq.com/docs/deprecations"
|
||||
],
|
||||
"allowedRetiredInCatalog": [
|
||||
"chatgpt-4o-latest",
|
||||
"claude-3-5-sonnet-20241022",
|
||||
"claude-3-7-sonnet-20250219",
|
||||
"google/gemini-2.0-flash",
|
||||
"gpt-4-0125-preview",
|
||||
"openai/gpt-5.2-codex"
|
||||
],
|
||||
"allowedRetiredInCatalog_note": "TODO(#11503): ratchet to burn down. Each id is retired by its vendor but still routable from the provider catalog. Removing a catalog row or adding a BUILT_IN_ALIASES forward is a maintainer call (some aggregators still serve these ids), so they are allowlisted here rather than silently dropped. Delete an entry as soon as it is forwarded or removed; never add one without a tracking issue.",
|
||||
"retired": {
|
||||
"claude-opus-4-1-20250805": {
|
||||
"vendor": "anthropic",
|
||||
"status": "retired",
|
||||
"retiredOn": "2026-08-05",
|
||||
"replacement": "claude-opus-4-8"
|
||||
},
|
||||
"claude-opus-4-20250514": {
|
||||
"vendor": "anthropic",
|
||||
"status": "retired",
|
||||
"retiredOn": "2026-06-15",
|
||||
"replacement": "claude-opus-4-8"
|
||||
},
|
||||
"claude-sonnet-4-20250514": {
|
||||
"vendor": "anthropic",
|
||||
"status": "retired",
|
||||
"retiredOn": "2026-06-15",
|
||||
"replacement": "claude-sonnet-4-6"
|
||||
},
|
||||
"claude-3-7-sonnet-20250219": {
|
||||
"vendor": "anthropic",
|
||||
"status": "retired",
|
||||
"retiredOn": "2026-02-19",
|
||||
"replacement": "claude-sonnet-4-6"
|
||||
},
|
||||
"claude-3-5-haiku-20241022": {
|
||||
"vendor": "anthropic",
|
||||
"status": "retired",
|
||||
"retiredOn": "2026-02-19",
|
||||
"replacement": "claude-haiku-4-5-20251001"
|
||||
},
|
||||
"claude-3-haiku-20240307": {
|
||||
"vendor": "anthropic",
|
||||
"status": "retired",
|
||||
"retiredOn": "2026-04-20",
|
||||
"replacement": "claude-haiku-4-5-20251001"
|
||||
},
|
||||
"claude-3-opus-20240229": {
|
||||
"vendor": "anthropic",
|
||||
"status": "retired",
|
||||
"retiredOn": "2026-01-05",
|
||||
"replacement": "claude-opus-4-8"
|
||||
},
|
||||
"claude-3-5-sonnet-20240620": {
|
||||
"vendor": "anthropic",
|
||||
"status": "retired",
|
||||
"retiredOn": "2025-10-28",
|
||||
"replacement": "claude-sonnet-4-6"
|
||||
},
|
||||
"claude-3-5-sonnet-20241022": {
|
||||
"vendor": "anthropic",
|
||||
"status": "retired",
|
||||
"retiredOn": "2025-10-28",
|
||||
"replacement": "claude-sonnet-4-6"
|
||||
},
|
||||
"claude-3-sonnet-20240229": {
|
||||
"vendor": "anthropic",
|
||||
"status": "retired",
|
||||
"retiredOn": "2025-07-21",
|
||||
"replacement": "claude-sonnet-4-6"
|
||||
},
|
||||
"claude-2.0": {
|
||||
"vendor": "anthropic",
|
||||
"status": "retired",
|
||||
"retiredOn": "2025-07-21",
|
||||
"replacement": "claude-opus-4-8"
|
||||
},
|
||||
"claude-2.1": {
|
||||
"vendor": "anthropic",
|
||||
"status": "retired",
|
||||
"retiredOn": "2025-07-21",
|
||||
"replacement": "claude-opus-4-8"
|
||||
},
|
||||
"claude-1.0": {
|
||||
"vendor": "anthropic",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"claude-1.1": {
|
||||
"vendor": "anthropic",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"claude-1.2": {
|
||||
"vendor": "anthropic",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"claude-1.3": {
|
||||
"vendor": "anthropic",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"claude-instant-1.0": {
|
||||
"vendor": "anthropic",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"claude-instant-1.1": {
|
||||
"vendor": "anthropic",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"claude-instant-1.2": {
|
||||
"vendor": "anthropic",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"claude-mythos-preview": {
|
||||
"vendor": "anthropic",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": "claude-mythos-5"
|
||||
},
|
||||
"gpt-5-codex": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-5.1-codex": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-5.1-codex-max": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-5.1-codex-mini": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-5.2-codex": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-5-chat-latest": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-5.1-chat-latest": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-5.2-chat-latest": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-5.3-chat-latest": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"o1-mini": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"o1-preview": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"chatgpt-4o-latest": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"codex-mini-latest": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-4.5-preview": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"computer-use-preview": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"computer-use-preview-2025-03-11": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"o3-deep-research": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"o4-mini-deep-research": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-4o-search-preview-2025-03-11": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-4o-mini-search-preview-2025-03-11": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"dall-e-2": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"dall-e-3": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-4-0314": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-4-0125-preview": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-4-turbo-preview": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-4-32k": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-4-32k-0613": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-4-32k-0314": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-4-vision-preview": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"text-moderation-latest": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-3.5-turbo-0613": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-3.5-turbo-16k-0613": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-4o-realtime-preview": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-4o-audio-preview": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-4o-mini-audio-preview": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-4o-mini-realtime-preview": {
|
||||
"vendor": "openai",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-3.5-turbo-0125": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-3.5-turbo": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-4-0613": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-4": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-4-1106-preview": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-4-turbo": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-4-turbo-2024-04-09": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-4.1-nano": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-4.1-nano-2025-04-14": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-4o-2024-05-13": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-image-1": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"o1-2024-12-17": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"o1": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"o1-pro-2025-03-19": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"o1-pro": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"o3-mini-2025-01-31": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"o3-mini": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"o4-mini-2025-04-16": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"o4-mini": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-3.5-turbo-instruct": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"babbage-002": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"davinci-002": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-3.5-turbo-1106": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-5-2025-08-07": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-5-mini-2025-08-07": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-5-nano-2025-08-07": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-5-pro-2025-10-06": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"o3-2025-04-16": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"o3-pro-2025-06-10": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-realtime": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-audio": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-4o-audio": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-4o-realtime": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-image-1-mini": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gpt-image-1.5": {
|
||||
"vendor": "openai",
|
||||
"status": "retiring",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gemini-2.0-flash": {
|
||||
"vendor": "google",
|
||||
"status": "retired",
|
||||
"retiredOn": "2026-06-01",
|
||||
"replacement": null
|
||||
},
|
||||
"gemini-2.0-flash-001": {
|
||||
"vendor": "google",
|
||||
"status": "retired",
|
||||
"retiredOn": "2026-06-01",
|
||||
"replacement": null
|
||||
},
|
||||
"gemini-2.0-flash-lite": {
|
||||
"vendor": "google",
|
||||
"status": "retired",
|
||||
"retiredOn": "2026-06-01",
|
||||
"replacement": null
|
||||
},
|
||||
"gemini-2.0-flash-lite-001": {
|
||||
"vendor": "google",
|
||||
"status": "retired",
|
||||
"retiredOn": "2026-06-01",
|
||||
"replacement": null
|
||||
},
|
||||
"gemini-1.5-pro": {
|
||||
"vendor": "google",
|
||||
"status": "retired",
|
||||
"retiredOn": "2025-09-29",
|
||||
"replacement": null
|
||||
},
|
||||
"gemini-1.5-flash": {
|
||||
"vendor": "google",
|
||||
"status": "retired",
|
||||
"retiredOn": "2025-09-29",
|
||||
"replacement": null
|
||||
},
|
||||
"gemini-1.5-flash-8b": {
|
||||
"vendor": "google",
|
||||
"status": "retired",
|
||||
"retiredOn": "2025-09-29",
|
||||
"replacement": null
|
||||
},
|
||||
"gemini-robotics-er-1.5-preview": {
|
||||
"vendor": "google",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gemini-3-pro-preview": {
|
||||
"vendor": "google",
|
||||
"status": "retired",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"gemini-robotics-er-1.6-preview": {
|
||||
"vendor": "google",
|
||||
"status": "retiring",
|
||||
"retiredOn": "2026-08-31",
|
||||
"replacement": null
|
||||
},
|
||||
"grok-voice-think-fast-1.0": {
|
||||
"vendor": "xai",
|
||||
"status": "deprecated",
|
||||
"retiredOn": null,
|
||||
"replacement": null
|
||||
},
|
||||
"llama3-8b-8192": {
|
||||
"vendor": "groq",
|
||||
"status": "retired",
|
||||
"retiredOn": "2025-08-30",
|
||||
"replacement": "llama-3.1-8b-instant"
|
||||
},
|
||||
"llama3-70b-8192": {
|
||||
"vendor": "groq",
|
||||
"status": "retired",
|
||||
"retiredOn": "2025-08-30",
|
||||
"replacement": "llama-3.3-70b-versatile"
|
||||
},
|
||||
"llama-3.1-8b-instant": {
|
||||
"vendor": "groq",
|
||||
"status": "retiring",
|
||||
"retiredOn": "2026-08-16",
|
||||
"replacement": "openai/gpt-oss-20b"
|
||||
},
|
||||
"codestral-2405": {
|
||||
"vendor": "mistral",
|
||||
"status": "retired",
|
||||
"retiredOn": "2025-06-16",
|
||||
"replacement": "codestral-2508"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -188,13 +188,14 @@
|
||||
"dedicatedGate": true
|
||||
},
|
||||
"bundleSize": {
|
||||
"value": 8045,
|
||||
"value": 8461,
|
||||
"direction": "down",
|
||||
"dedicatedGate": true,
|
||||
"_rebaseline_2026_07_07_v3846_release_close": "5601->6534 (+933). v3.8.46 release close: gzip of the 4 bin/*.mjs entrypoints (size-limit + @size-limit/file) grew from this cycle's feature/fix merges pulled transitively into the CLI entrypoints (new providers, combo pipeline strategy #6396, effort/thinking standardization #6241, catalog cache-invalidation #6408). Measured 6534 locally via `check:bundle-size --ratchet` (deterministic gzip, matches CI). Legitimate cycle growth; shrink is separate debt.",
|
||||
"_rebaseline_2026_07_19_7808_codeql_alias_resolver_hook": "6534->6762 (+228). PR #7808 (CodeQL js/incomplete-url-substring-sanitization fix): the ESM loader hook source moved out of the inline `HOOK_SOURCE` template literal in bin/aliasResolver.mjs into a real file bin/aliasResolverHook.mjs, loaded via pathToFileURL() instead of a dynamically-built `data:text/javascript,...` URL. The new file is now counted by size-limit as a 5th bin/*.mjs entrypoint. Net +228 = the hook's gzip size (previously hidden inside aliasResolver.mjs because the template literal was compressed away). Security-driven; no shrink opportunity.",
|
||||
"_rebaseline_2026_07_28_v3849_release_preflight": "6762 -> 7666 (+904). Fechamento do ciclo v3.8.49: gzip dos entrypoints bin/*.mjs (size-limit + @size-limit/file) cresceu com o que os merges do ciclo puxam transitivamente para o CLI (novos provedores — 271->290, seletor de protocolo por conexão #8861, catálogos de busca #8814, resiliência). Crescimento legítimo de ciclo, medido localmente com `npm run check:bundle-size` = 7666 (gzip determinístico, bate com o CI). Encolher é dívida separada.",
|
||||
"_rebaseline_2026_08_09_v3850_release_close": "7666 -> 8045 (+379 gzip bytes, +4.9%). Release v3.8.50 close reconciliation measured twice with the real size-limit + @size-limit/file path on tip e0ce95c592. Per-entry measurements remain below their absolute budgets: omniroute.mjs 4380/15000, mcp-server.mjs 1195/5000, nodeRuntimeSupport.mjs 887/8000, reset-password.mjs 1583/6000. The growth accumulated through legitimate CLI/runtime work in this cycle, including global-install ESM alias resolution, Termux cache preparation, and MCP stdio startup hardening; no entrypoint is near its absolute ceiling. The direction:down ratchet stays blocking from this exact measured tip."
|
||||
"_rebaseline_2026_08_09_v3850_release_close": "7666 -> 8045 (+379 gzip bytes, +4.9%). Release v3.8.50 close reconciliation measured twice with the real size-limit + @size-limit/file path on tip e0ce95c592. Per-entry measurements remain below their absolute budgets: omniroute.mjs 4380/15000, mcp-server.mjs 1195/5000, nodeRuntimeSupport.mjs 887/8000, reset-password.mjs 1583/6000. The growth accumulated through legitimate CLI/runtime work in this cycle, including global-install ESM alias resolution, Termux cache preparation, and MCP stdio startup hardening; no entrypoint is near its absolute ceiling. The direction:down ratchet stays blocking from this exact measured tip.",
|
||||
"_rebaseline_2026_08_24_ci_green_gates_f95b03d7": "8045 -> 8461 (+416 gzip bytes, +5.2%). CI run 32786966560 (release PR #8875, tip f95b03d7) measured bundleSize=8461 via check:bundle-size --ratchet, above the 8045 baseline left at the v3.8.50 close. The growth comes from the post-freeze back-merge cycle landing in the CLI entrypoints (Synthetic + Kilo Gateway providers, kilo-gateway routing surface). Re-baseline per the gate's own instruction (legitimate cycle growth); shrinking the entrypoints remains separate debt; direction:down ratchet stays blocking from this measured tip."
|
||||
},
|
||||
"openapiBreaking": {
|
||||
"value": 4,
|
||||
|
||||
@@ -76,6 +76,10 @@
|
||||
"tests/unit/plugins-sandbox.test.ts": {
|
||||
"sourceRemoved": ["src/lib/plugins/sandbox.ts"],
|
||||
"reason": "v3.8.50 #9126 (commit 8fac6bcd48): sandbox.ts foi removido por completo junto com pluginWorker.ts e signing.ts (\"zero importers confirmed\", subsistema de sandbox de plugins nunca ligado a nenhum consumidor). O teste cobria SandboxLevel/getSandboxLabel exportados por sandbox.ts; sem o arquivo-fonte não há mais símbolo a testar. Mesma causa-raiz de tests/unit/plugin-sandbox-permissions.test.ts nesta entrada."
|
||||
},
|
||||
"tests/unit/gemini-3-5-flash-thinking.test.ts": {
|
||||
"replacement": "tests/unit/model-capabilities-registry.test.ts",
|
||||
"reason": "v3.8.50 back-merge f95b03d7: the provider-neutral Gemini 3.5 Flash tier catalog was RETIRED (MODEL_SPECS entries removed; the thinking tiers now live under antigravity/gemini-3.7-flash-*), so the deleted file's thinking-capable/routing-policy fixtures pinned a retired surface and red-fail against HEAD. The replacement guards the retirement itself (retired ids have no provider-neutral specs) plus resolvable capability floors for the surviving gemini-3-flash-agent id. Verified legitimate, not masking."
|
||||
}
|
||||
},
|
||||
"tests/unit/catalog-updates-v3x.test.ts": "v3.8.45 #6248: fix(providers) remove deprecated MiMo V2 entries — os 5 asserts removidos pinavam specs de modelos mimo-v2-* que deixaram de existir no catálogo (54→49). Asserts seguem a remoção dos modelos, não enfraquecimento. Verificado legítimo. Prune após v3.8.45 mergear para main.",
|
||||
|
||||
@@ -64,6 +64,7 @@ Runs on every PR to `main`. Blocks merge on failure.
|
||||
| `check:route-validation:t06` | Zod schemas present on all routes (Tier 6 policy) | Yes |
|
||||
| `check:any-budget:t11` | `@ts-expect-error // any` count does not exceed budget (Tier 11 catraca) | Yes |
|
||||
| `check:provider-consistency` | Every provider in `providers.ts` has a matching entry in `providerRegistry.ts` (and vice-versa, within the allowlist) | Yes |
|
||||
| `check:model-lifecycle` | The two hand-maintained routing tables do not point at retired models (#11503): `FITNESS_TABLE` (`taskFitness.ts`) scores no routable retired id, every `BUILT_IN_ALIASES` target is a live catalog model, and every retired id the catalog still routes is either forwarded or listed in `allowedRetiredInCatalog`. Offline — compares against the vendor snapshot `config/quality/model-lifecycle.json`, refreshed by hand with `npm run quality:refresh-model-lifecycle` (network; not wired into CI). `allowedRetiredInCatalog` is a burn-down ratchet: add an entry only with a tracking issue. | Yes |
|
||||
| `check:fetch-targets` | Every `fetch("/api/...")` in client-side `src/` resolves to a real `route.ts` | Yes |
|
||||
| `check:deps` | All `npm install`-able deps across every `package.json` in the repo are in `dependency-allowlist.json`; new unpinned or slopsquatted packages flagged | Yes |
|
||||
| `audit:deps` | `npm audit` (root + electron) — no high/critical advisories (overlaps osv `check:vuln-ratchet`; see Rationalization Backlog) | Yes |
|
||||
|
||||
@@ -82,7 +82,7 @@ OmniRoute has three distinct but related resilience mechanisms. Each has a diffe
|
||||
**Terminal states (NOT cooldowns):**
|
||||
|
||||
- `banned` — set by banned-keyword / account-ban detection (see [BAN_DETECTION](../security/BAN_DETECTION.md))
|
||||
- `expired`
|
||||
- `expired` (transitions to terminal after bounded retries — `EXPIRED_RETRY_MAX = 3` with exponential backoff — so transient OAuth errors can self-heal before the account is permanently deactivated)
|
||||
- `credits_exhausted`
|
||||
|
||||
These persist until credentials change or an operator resets them. Do not overwrite terminal states with transient cooldown state.
|
||||
|
||||
@@ -9,20 +9,49 @@ lastUpdated: 2026-08-10
|
||||
OmniRoute has **two** process-local lane systems with different scopes. They are
|
||||
complementary; operators should know which one they are looking at.
|
||||
|
||||
## 1. Byte-level per-connection lanes (`chatBodyAdmission.ts`)
|
||||
## 1. Byte-level process-wide admission (`chatBodyAdmission.ts`)
|
||||
|
||||
- **Scope:** the buffered-body/heap path for `POST /v1/chat/completions`. Guards
|
||||
- **Scope:** the buffered-body/heap path for `POST /v1/chat/completions`,
|
||||
`/v1/messages`, `/v1/responses`, and the other chat-shaped routes. Guards
|
||||
against heap amplification from large coding-agent bodies (#4380).
|
||||
- **Gate:** **always on.** Each distinct API key (hashed) — or `anonymous` — gets its
|
||||
own lane with `CHAT_MAX_HEAVY_IN_FLIGHT` capacity, so one session's burst cannot
|
||||
starve another session's heavyweight slot.
|
||||
- **One process-global controller, not per-key lanes (#10110).** Every API key
|
||||
(hashed) or `anonymous` session admits against the **same** shared budget —
|
||||
the hashed session id is used ONLY as a fairness scheduling key (round-robin
|
||||
dispatch across waiters), never as a capacity shard. A prior version of this
|
||||
doc described per-key lanes with independent capacity; that model was
|
||||
removed in #10110 because it let unauthenticated fake credentials multiply
|
||||
the process-wide bound.
|
||||
- **Gate (#503-fanout): an auto-derived ingest BYTE budget, not a fixed request
|
||||
count.** The legacy `CHAT_MAX_HEAVY_IN_FLIGHT` request-count cap (default `1`
|
||||
before this fix) collapsed coding-agent fan-out (multiple subagents/CLIs,
|
||||
bodies routinely > 256 KB) to an effective concurrency of ~1, which 503'd
|
||||
under completely normal load. It now binds only when an operator explicitly
|
||||
sets `OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT`. Left unset, admission is instead
|
||||
gated by `OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES` — a budget auto-derived from the
|
||||
process's real memory ceiling (`src/shared/middleware/admissionBudget.ts`):
|
||||
25% of the tighter of the V8 heap limit and any cgroup/container limit,
|
||||
divided by an 8x transient-amplification factor, clamped between 8 MiB and
|
||||
2 GiB. Explicit overrides use the same clamps. This scales itself from a
|
||||
512 MB container to a 32 GB desktop with no env tuning. A body that cannot
|
||||
fit within the effective budget fails immediately with `413 body_exceeds_budget`;
|
||||
only contention among individually serviceable bodies enters the bounded
|
||||
fairness queue. A live multi-signal resource-pressure tracker (V8 heap ratio,
|
||||
cgroup, PSI, OOM events — `open-sse/utils/resourcePressurePolicy.ts`) shortens
|
||||
the bounded wait under `high` pressure and sheds immediately with
|
||||
`503 resource_pressure` under `critical` pressure, before any bytes are even
|
||||
ingested.
|
||||
- **Tuning:**
|
||||
- `OMNIROUTE_CHAT_VIRTUAL_TTL_MS` — idle-lane eviction (default 60000)
|
||||
- `OMNIROUTE_CHAT_VIRTUAL_MAX_SESSIONS` — lane count cap (default 64)
|
||||
- `OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES` — override for the auto-derived byte budget
|
||||
- `OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT` — legacy request-count cap, opt-in only
|
||||
- `OMNIROUTE_CHAT_ADMISSION_QUEUE_MS` — queue-wait before 503 (default 2000)
|
||||
- `OMNIROUTE_CHAT_ADMISSION_MAX_QUEUED_BYTES` — queued-bytes heap valve (default 4 MB)
|
||||
- **Reports:** not in `GET /api/monitoring/health` today; observable via
|
||||
`PerConnectionAdmissionController.snapshot()` (sessionId hash, activeHeavy, idleMs).
|
||||
- `OMNIROUTE_CHAT_VIRTUAL_TTL_MS` / `OMNIROUTE_CHAT_VIRTUAL_MAX_SESSIONS` — deprecated
|
||||
no-ops since #10110 (accepted for config compatibility, ignored)
|
||||
- **Reports:** `GET /api/monitoring/health` → `chatAdmission` (#11244) — including
|
||||
the #503-fanout additions `inflightBytes`, `maxInflightBytes`, `budgetSource`
|
||||
(`v8_heap` | `cgroup` | `override`), `pressureSeverity`, and `countCapEnabled`
|
||||
(false on a default deployment — confirms the byte budget, not the legacy
|
||||
count cap, is what is actually binding).
|
||||
|
||||
## 2. Adaptive runtime virtual lanes (`open-sse/services/admission`)
|
||||
|
||||
|
||||
1
docs/changelog/fragments/7778.md
Normal file
@@ -0,0 +1 @@
|
||||
feat(resilience): atomically enforce cumulative global, provider, and account concurrency limits
|
||||
@@ -1,4 +1,4 @@
|
||||
<svg viewBox="0 0 1200 350" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Animated terminal demoing the OmniRoute CLI: omniroute providers list (353 providers registered, anthropic, codex, glm, kimi shown active), omniroute combo list (always-on priority, cost-saver, fusion-panel, context-relay) and omniroute health (healthy, 18412 requests in 24h, p95 412ms, circuit breakers 24 closed, 1 half-open, 0 open), cycling over 85 top-level commands: providers, oauth, keys, combo, nodes, models, cache, compression, cost, usage, quota, health, resilience, telemetry, logs, audit, mcp, a2a, cloud, memory, skills, eval, doctor, repl, tunnel, backup, sync, webhooks, policy, pricing, translator, simulate and more.">
|
||||
<svg viewBox="0 0 1200 350" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Animated terminal demoing the OmniRoute CLI: omniroute providers list (354 providers registered, anthropic, codex, glm, kimi shown active), omniroute combo list (always-on priority, cost-saver, fusion-panel, context-relay) and omniroute health (healthy, 18412 requests in 24h, p95 412ms, circuit breakers 24 closed, 1 half-open, 0 open), cycling over 85 top-level commands: providers, oauth, keys, combo, nodes, models, cache, compression, cost, usage, quota, health, resilience, telemetry, logs, audit, mcp, a2a, cloud, memory, skills, eval, doctor, repl, tunnel, backup, sync, webhooks, policy, pricing, translator, simulate and more.">
|
||||
<desc>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.</desc>
|
||||
<defs><clipPath id="tickerClip"><rect x="12" y="304" width="1176" height="40"/></clipPath><clipPath id="tw0"><rect x="64" y="46" height="26" width="0"><animate attributeName="width" calcMode="discrete" values="0;31;61;92;122;153;184;214;245;245" keyTimes="0;0.012;0.018;0.024;0.030;0.036;0.042;0.048;0.054;1" dur="18s" repeatCount="indefinite"/></rect></clipPath><clipPath id="tw1"><rect x="64" y="46" height="26" width="0"><animate attributeName="width" calcMode="discrete" values="0;26;51;76;102;128;153;178;204;204" keyTimes="0;0.348;0.351;0.357;0.363;0.369;0.375;0.381;0.387;1" dur="18s" repeatCount="indefinite"/></rect></clipPath><clipPath id="tw2"><rect x="64" y="46" height="26" width="0"><animate attributeName="width" calcMode="discrete" values="0;20;41;61;82;102;122;143;163;163" keyTimes="0;0.678;0.684;0.690;0.696;0.702;0.708;0.714;0.720;1" dur="18s" repeatCount="indefinite"/></rect></clipPath></defs>
|
||||
<rect width="1200" height="350" fill="#0d1117"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
@@ -1,4 +1,4 @@
|
||||
<svg viewBox="0 0 1200 780" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Comparison table: OmniRoute versus 9router, OpenRouter, CLIProxyAPI and LiteLLM across 13 capabilities. OmniRoute is the only one with the full set: 353 providers, 90+ free providers built-in, 19 routing strategies, 12-engine token compression, a built-in MCP server with 110 tools, A2A protocol, persistent memory, guardrails, cloud agents, TLS fingerprint stealth, desktop/Termux/PWA, 43 UI locales and 100% MIT self-hosted. 9router has free providers, RTK compression and translation but no MCP, A2A, memory, guardrails, cloud agents or stealth. OpenRouter is a hosted SaaS with 400+ models, guardrails and a hosted MCP but is not self-hosted and lacks A2A, memory, cloud agents and stealth. CLIProxyAPI is a light OAuth proxy with two routing strategies. LiteLLM has 100+ providers, A2A and extensive guardrails but no memory, compression, free tier, stealth or cloud agents.">
|
||||
<svg viewBox="0 0 1200 780" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Comparison table: OmniRoute versus 9router, OpenRouter, CLIProxyAPI and LiteLLM across 13 capabilities. OmniRoute is the only one with the full set: 354 providers, 90+ free providers built-in, 19 routing strategies, 12-engine token compression, a built-in MCP server with 110 tools, A2A protocol, persistent memory, guardrails, cloud agents, TLS fingerprint stealth, desktop/Termux/PWA, 43 UI locales and 100% MIT self-hosted. 9router has free providers, RTK compression and translation but no MCP, A2A, memory, guardrails, cloud agents or stealth. OpenRouter is a hosted SaaS with 400+ models, guardrails and a hosted MCP but is not self-hosted and lacks A2A, memory, cloud agents and stealth. CLIProxyAPI is a light OAuth proxy with two routing strategies. LiteLLM has 100+ providers, A2A and extensive guardrails but no memory, compression, free tier, stealth or cloud agents.">
|
||||
<desc>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.</desc>
|
||||
<defs>
|
||||
<pattern id="gC" width="32" height="32" patternUnits="userSpaceOnUse"><path d="M 32 0 L 0 0 0 32" fill="none" stroke="#ffffff" stroke-opacity="0.05" stroke-width="1"/></pattern>
|
||||
|
||||
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
@@ -1,4 +1,4 @@
|
||||
<svg viewBox="0 0 1200 540" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="The OmniRoute promise: one endpoint and 353 providers. Six pillars. Resilient fallback: automatic routing continues while another healthy target is available. Save up to 95 percent of eligible tokens: RTK plus Caveman stacked compression averages about 89 percent on tool-heavy sessions. Zero dollars to start: 90+ providers with a free tier and 56 recurring or keyless free-forever providers. Every tool works: 35 CLI and agent integration records, including Claude Code, Codex, Cursor, Cline, Copilot and Antigravity, through one config. One endpoint: OpenAI, Claude, Gemini and Responses API translation at /v1. Production controls: circuit breakers, TLS stealth, MCP with 110 tools, A2A, memory, guardrails, evals, and 39,000+ static test declarations across 5,100+ tracked test files.">
|
||||
<svg viewBox="0 0 1200 540" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="The OmniRoute promise: one endpoint and 354 providers. Six pillars. Resilient fallback: automatic routing continues while another healthy target is available. Save up to 95 percent of eligible tokens: RTK plus Caveman stacked compression averages about 89 percent on tool-heavy sessions. Zero dollars to start: 90+ providers with a free tier and 56 recurring or keyless free-forever providers. Every tool works: 35 CLI and agent integration records, including Claude Code, Codex, Cursor, Cline, Copilot and Antigravity, through one config. One endpoint: OpenAI, Claude, Gemini and Responses API translation at /v1. Production controls: circuit breakers, TLS stealth, MCP with 110 tools, A2A, memory, guardrails, evals, and 39,000+ static test declarations across 5,100+ tracked test files.">
|
||||
<desc>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.</desc>
|
||||
<defs>
|
||||
<pattern id="gridPaperP" width="32" height="32" patternUnits="userSpaceOnUse">
|
||||
@@ -21,7 +21,7 @@
|
||||
<line x1="150" y1="53" x2="1160" y2="53" stroke="#232b38" stroke-width="1.5"/>
|
||||
</g>
|
||||
<g>
|
||||
<text x="40" y="100" font-family="Inter, 'Segoe UI', Arial, Helvetica, system-ui, sans-serif" font-size="23" font-weight="600" fill="#c9d1d9">One endpoint. <tspan fill="#a78bfa" font-weight="800">353 providers.</tspan> Never stop building — OmniRoute picks <tspan fill="#7ee787" font-weight="700">the cheapest one that works</tspan>.</text>
|
||||
<text x="40" y="100" font-family="Inter, 'Segoe UI', Arial, Helvetica, system-ui, sans-serif" font-size="23" font-weight="600" fill="#c9d1d9">One endpoint. <tspan fill="#a78bfa" font-weight="800">354 providers.</tspan> Never stop building — OmniRoute picks <tspan fill="#7ee787" font-weight="700">the cheapest one that works</tspan>.</text>
|
||||
</g>
|
||||
|
||||
<g font-family="Inter, 'Segoe UI', Arial, Helvetica, system-ui, sans-serif">
|
||||
@@ -38,7 +38,7 @@
|
||||
<line x1="3.9" y1="3.9" x2="18.1" y2="18.1"/>
|
||||
</g>
|
||||
<text x="102" y="170" font-size="18" font-weight="800" fill="#74b9ff">Never hit limits</text>
|
||||
<text x="66" y="204" font-size="13.5" fill="#a1a1aa">Auto-fallback across 353 providers in</text>
|
||||
<text x="66" y="204" font-size="13.5" fill="#a1a1aa">Auto-fallback across 354 providers in</text>
|
||||
<text x="66" y="226" font-size="13.5" fill="#a1a1aa">milliseconds. Quota out? The next provider</text>
|
||||
<text x="66" y="248" font-size="13.5" fill="#a1a1aa">takes over while a healthy target remains.</text>
|
||||
</g>
|
||||
|
||||
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
@@ -1,4 +1,4 @@
|
||||
<svg viewBox="0 0 1200 548" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="OmniRoute hero: Never stop coding. Every AI tool to 353 providers — 90+ free — through one endpoint. Claude Code, Codex, Cursor, Cline, Copilot and Antigravity into free Claude, GPT and Gemini with auto-fallback. RTK + Caveman stacked compression saves 15 to 95 percent of tokens — about 89 percent average on tool-heavy sessions — so you never hit limits. Stats: 353 AI providers, 90+ free tiers, about 1.51B free tokens per month, 15 to 95 percent token savings, 19 routing strategies, zero dollars to start.">
|
||||
<svg viewBox="0 0 1200 548" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="OmniRoute hero: Never stop coding. Every AI tool to 354 providers — 90+ free — through one endpoint. Claude Code, Codex, Cursor, Cline, Copilot and Antigravity into free Claude, GPT and Gemini with auto-fallback. RTK + Caveman stacked compression saves 15 to 95 percent of tokens — about 89 percent average on tool-heavy sessions — so you never hit limits. Stats: 354 AI providers, 90+ free tiers, about 1.51B free tokens per month, 15 to 95 percent token savings, 19 routing strategies, zero dollars to start.">
|
||||
<desc>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.</desc>
|
||||
<defs>
|
||||
<pattern id="gridPaperH" width="32" height="32" patternUnits="userSpaceOnUse">
|
||||
@@ -28,7 +28,7 @@
|
||||
<text x="48" y="138" font-family="Inter, 'Segoe UI', Arial, Helvetica, system-ui, sans-serif" font-size="60" font-weight="800" fill="#e9edf3">Never stop coding<tspan fill="#a855f7">.</tspan></text>
|
||||
|
||||
<!-- subheadline -->
|
||||
<text x="48" y="184" font-family="Inter, 'Segoe UI', Arial, Helvetica, system-ui, sans-serif" font-size="25" font-weight="600" fill="#c9d1d9">Every AI tool → <tspan fill="#a78bfa" font-weight="800">353 providers</tspan> — <tspan fill="#7ee787" font-weight="800">90+ free</tspan> — through one endpoint.</text>
|
||||
<text x="48" y="184" font-family="Inter, 'Segoe UI', Arial, Helvetica, system-ui, sans-serif" font-size="25" font-weight="600" fill="#c9d1d9">Every AI tool → <tspan fill="#a78bfa" font-weight="800">354 providers</tspan> — <tspan fill="#7ee787" font-weight="800">90+ free</tspan> — through one endpoint.</text>
|
||||
|
||||
<!-- plug line -->
|
||||
<text x="48" y="222" font-family="Inter, 'Segoe UI', Arial, Helvetica, system-ui, sans-serif" font-size="16.5" fill="#a1a1aa">Claude Code · Codex · Cursor · Cline · Copilot · Antigravity  →  <tspan fill="#7ee787" font-weight="700">FREE</tspan> Claude / GPT / Gemini · auto-fallback</text>
|
||||
|
||||
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
@@ -57,7 +57,7 @@ New tab for extracting content from a URL via `POST /v1/web/fetch` (created in p
|
||||
- Submit → fetch → render `ScrapeResult.tsx`.
|
||||
- `ScrapeResult` renders markdown preview + raw toggle.
|
||||
- Cap: if response body > **256 KB**, UI shows `(truncated, view raw)` and opens raw in a Monaco modal (D21).
|
||||
- Metadata panel: provider (firecrawl/jina-reader/tavily-search/tinyfish), latency, cost, response size, links count.
|
||||
- Metadata panel: provider (firecrawl/jina-reader/tavily-search/tinyfish/nimble-search), latency, cost, response size, links count.
|
||||
- Uses `useScrapeFetch.ts` hook.
|
||||
|
||||
### Compare Tab
|
||||
@@ -108,7 +108,7 @@ Runs the same query/URL across up to **4 providers in parallel** (D22):
|
||||
| Field | Source |
|
||||
| ------------------------------ | ------------------------------------------------------------------------------------------ |
|
||||
| `id`, `name` | `searchRegistry.ts` |
|
||||
| `kind` | `"search"` (12 providers) or `"fetch"` (firecrawl, jina-reader, tavily-search, tinyfish) |
|
||||
| `kind` | `"search"` or `"fetch"` (firecrawl, jina-reader, tavily-search, tinyfish, nimble-search) |
|
||||
| `costPerQuery` | Registry data |
|
||||
| `freeMonthlyQuota` | Registry data |
|
||||
| `searchTypes` / `fetchFormats` | Registry data |
|
||||
@@ -136,7 +136,7 @@ Only one backend change was needed for this feature:
|
||||
|
||||
`src/app/api/search/providers/route.ts` was extended to:
|
||||
|
||||
- Include all 4 fetch providers (`firecrawl`, `jina-reader`, `tavily-search`, `tinyfish`) in the array.
|
||||
- Include every fetch provider (`firecrawl`, `jina-reader`, `tavily-search`, `tinyfish`, `nimble-search`) in the array.
|
||||
- Add `kind: "search" | "fetch"` to every item.
|
||||
- Add `status: "configured" | "missing" | "rate_limited"` derived from live credential state.
|
||||
- Maintain backward compatibility — existing fields (`id`, `name`, etc.) unchanged.
|
||||
|
||||
@@ -561,7 +561,7 @@ External Postgres / multi-writer HA is **not** a documented stock path. If you n
|
||||
|
||||
## Scale-out: N independent processes
|
||||
|
||||
One Node process is **one V8 heap**. Two overlapping ~3 MiB / ~750k-token coding-agent `POST /v1/responses` (RTK + Caveman) abort that heap at ~12 Gi (`FATAL ERROR: Reached heap limit`) and can OOM a 16 Gi cgroup. See [#7849](https://github.com/diegosouzapw/OmniRoute/issues/7849). Raising `OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT` on that process reintroduces the abort. Small chats, `/healthz`, `/v1/models`, and MCP are **not** in that cap.
|
||||
One Node process is **one V8 heap**. Two overlapping ~3 MiB / ~750k-token coding-agent `POST /v1/responses` (RTK + Caveman) abort that heap at ~12 Gi (`FATAL ERROR: Reached heap limit`) and can OOM a 16 Gi cgroup. See [#7849](https://github.com/diegosouzapw/OmniRoute/issues/7849). Heavyweight chat admission is gated by an auto-derived ingest byte budget (`OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES`, `src/shared/middleware/admissionBudget.ts`) sized from that same V8/cgroup ceiling -- it already scales itself to the process's real memory, so overriding it upward (or setting the legacy `OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT` request-count cap) on an already-sized process reintroduces the abort. Small chats, `/healthz`, `/v1/models`, and MCP are **not** in that cap.
|
||||
|
||||
To go beyond two concurrent **large** jobs **today**:
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ Visual guide to every section of the OmniRoute dashboard.
|
||||
|
||||
The v3.7.x → v3.8.0 cycle added zero-config auto routing, new providers, OAuth flows, deeper resilience, and a much richer CLI experience. Headline features below — full details further in the document and in linked specs.
|
||||
|
||||
- 🤖 **Auto Combo / Zero-config auto-routing** — use prefixes `auto/coding`, `auto/fast`, `auto/cheap`, `auto/offline`, `auto/smart`, `auto/lkgp`. Backed by a 13-factor scoring engine and 4 curated **mode packs** (ship-fast, cost-saver, quality-first, offline-friendly)
|
||||
- 🤖 **Auto Combo / Zero-config auto-routing** — use prefixes `auto/coding`, `auto/fast`, `auto/cheap`, `auto/offline`, `auto/smart`, `auto/lkgp`. Backed by a 15-factor scoring engine and 4 curated **mode packs** (ship-fast, cost-saver, quality-first, offline-friendly)
|
||||
- 🆕 **Command Code provider** (#2199) — first-class registration with model catalog and quota tracking
|
||||
- 🆕 **Z.AI provider** — new free-tier provider with quota labels
|
||||
- 🎬 **KIE media expansion** — extended catalog including video generation models
|
||||
|
||||
@@ -238,7 +238,7 @@ provider that ships at least one strong free model.
|
||||
`user_override → arena_elo → models_dev_tier → static table`). So after you connect
|
||||
the top free providers, routing with `model: "auto"` (e.g. `auto/coding`) will
|
||||
automatically prefer the higher-quality free models per request. See
|
||||
[Auto-Combo](../routing/AUTO-COMBO.md) for the full 13-factor scoring.
|
||||
[Auto-Combo](../routing/AUTO-COMBO.md) for the full 15-factor scoring.
|
||||
|
||||
---
|
||||
|
||||
@@ -248,7 +248,7 @@ provider that ships at least one strong free model.
|
||||
providers, no credit card required.
|
||||
- [Free Tiers directory](../reference/FREE_TIERS.md) — full catalog of free providers
|
||||
and their limits.
|
||||
- [Auto-Combo](../routing/AUTO-COMBO.md) — the 13-factor routing engine that consumes the
|
||||
- [Auto-Combo](../routing/AUTO-COMBO.md) — the 15-factor routing engine that consumes the
|
||||
same Arena ELO task-fitness data.
|
||||
- [Environment variables](../reference/ENVIRONMENT.md) — `ARENA_ELO_SYNC_ENABLED` /
|
||||
`ARENA_ELO_SYNC_INTERVAL` reference.
|
||||
|
||||
@@ -69,7 +69,7 @@ rate limits — circuit breaker recovers them on backoff.
|
||||
Dashboard → **Tiers** → assign your providers. Defaults (from `tierDefaults.json`) are
|
||||
sensible; edit when you have specific subscriptions to prioritize or providers to exclude.
|
||||
|
||||
Auto-Combo's 13-factor scoring also considers tier. See
|
||||
Auto-Combo's 15-factor scoring also considers tier. See
|
||||
[`docs/routing/AUTO-COMBO.md`](../routing/AUTO-COMBO.md).
|
||||
|
||||
## Telemetry
|
||||
|
||||
@@ -58,11 +58,11 @@ export OMNIROUTE_CHAT_ADMISSION_QUEUE_MS=5000 # longer bounded wait for heavywei
|
||||
|
||||
Set these in the OmniRoute process environment (the daemon, e.g. via the LaunchAgent plist or `systemctl edit`), then restart OmniRoute. The rotation flag is the single highest-leverage lever: it converts a hard failure into a transparent retry against a healthy provider in the pool.
|
||||
|
||||
**Note**: `OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT` (default `1`, per process) caps how many heavyweight — long-context — requests run at once; the bound is an admission gate, not a provider rate limiter. Raising it only reduces client-visible `503 chat_admission_busy` rejects for heavy requests. The per-provider rate limiting (`open-sse/services/rateLimitManager.ts`) is governed separately by `RATE_LIMIT_MAX_WAIT_MS`, `RATE_LIMIT_MAX_QUEUE_DEPTH`, and `RATE_LIMIT_AUTO_ENABLE` — see `.env.example`.
|
||||
**Note**: `OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT` caps how many heavyweight — long-context — requests run at once; the bound is an admission gate, not a provider rate limiter. **#503-fanout update:** this var is no longer set by default (it now binds only when explicitly configured, as above) — heavyweight admission is instead gated by an auto-derived byte budget (`OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES`) that scales itself from the host's real memory ceiling, so a fresh deployment should see far fewer `503 chat_admission_busy` rejects without setting this var at all; explicitly setting it here still works exactly as documented. Explicit byte-budget overrides clamp to 8 MiB–2 GiB. A `413 body_exceeds_budget` is not transient: increase that byte budget, lower `OMNIROUTE_CHAT_HARD_MAX_BODY_BYTES`, or increase the process memory ceiling. An `inflight_bytes_budget` shed is temporary contention and remains retryable. The per-provider rate limiting (`open-sse/services/rateLimitManager.ts`) is governed separately by `RATE_LIMIT_MAX_WAIT_MS`, `RATE_LIMIT_MAX_QUEUE_DEPTH`, and `RATE_LIMIT_AUTO_ENABLE` — see `.env.example`.
|
||||
|
||||
**How to verify it worked**: run your agent/cron twice in quick succession and confirm both succeed. Before the fix, the second run typically throws `429`/`401`. After the fix, failures (if any) are retried transparently and the call completes. You can also `curl /monitoring/health` and watch the `rateLimitedUntil` field on the provider connections and the `circuitBreakers.providerBreakers[].state` for the affected providers — the state is one of `CLOSED`, `DEGRADED`, `OPEN`, or `HALF_OPEN` (see `src/shared/utils/circuitBreaker.ts`), and a provider that keeps failing will flip `CLOSED → DEGRADED → OPEN` before the reset window lets a probe through (`HALF_OPEN`).
|
||||
|
||||
**If you still see 429**: the active account for that provider has genuinely exhausted its *quota* (not just rate). Add a second account for the same provider in the OmniRoute dashboard → Providers → Accounts, or mix in another free provider (e.g. `routeway`, `auggie`). Rotation only helps with transient rate/400/401; a hard quota exhaustion requires a second credential or a different provider.
|
||||
**If you still see 429**: the active account for that provider has genuinely exhausted its _quota_ (not just rate). Add a second account for the same provider in the OmniRoute dashboard → Providers → Accounts, or mix in another free provider (e.g. `routeway`, `auggie`). Rotation only helps with transient rate/400/401; a hard quota exhaustion requires a second credential or a different provider.
|
||||
|
||||
**If you see 403 on vision models (`auto/vision`, `bazaarlink/*`)**: the connected account lacks a paid plan that includes vision, or the API key has insufficient permissions. Verify in the provider dashboard that the key scope includes vision/multimodal, or connect a paid tier account and keep it as the vision target.
|
||||
|
||||
@@ -567,34 +567,41 @@ Each process uses a process-local guard to reserve limited heavyweight capacity
|
||||
and parsing a large request body. A heavyweight lease remains held for the lifetime of an SSE
|
||||
response.
|
||||
|
||||
**#503-fanout:** before this fix, the guard capped concurrency at a fixed request COUNT
|
||||
(`OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT`, default `1`) regardless of host memory, so coding-agent
|
||||
fan-out (multiple subagents/CLIs, bodies routinely > 256 KB) collapsed to an effective
|
||||
concurrency of ~1 and 503'd under completely normal load. The guard now self-tunes: it is gated
|
||||
by an auto-derived ingest BYTE budget (`OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES`) sized from the
|
||||
process's real memory ceiling, and it also consults a live resource-pressure signal — so it
|
||||
only sheds when the host is genuinely under memory pressure, not merely because more than one
|
||||
heavy request arrived at once. The old count cap (`OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT`) is
|
||||
still honored, but only if you explicitly set it.
|
||||
|
||||
When capacity is busy, a heavyweight request first waits up to
|
||||
`OMNIROUTE_CHAT_ADMISSION_QUEUE_MS` (default `5000`, `0` disables the wait) for a slot to free up
|
||||
`OMNIROUTE_CHAT_ADMISSION_QUEUE_MS` (default `2000`, `0` disables the wait) for a slot to free up
|
||||
before answering the retryable `503`. The bounded wait exists so agent-style clients
|
||||
(OpenCode, Claude Code, Cursor) that fan out heavy sub-requests concurrently serialize the burst
|
||||
instead of burning their whole retry budget on immediate rejections and dying mid-task.
|
||||
Current heavyweight lease occupancy is not surfaced in the dashboard.
|
||||
Current heavyweight lease occupancy, the resolved byte budget, and live pressure severity are
|
||||
surfaced at `GET /api/monitoring/health` → `chatAdmission` (`inflightBytes`, `maxInflightBytes`,
|
||||
`budgetSource`, `pressureSeverity`, `countCapEnabled`) — check these before touching any env var.
|
||||
Settings → Resilience → Request Queue → Concurrent Requests does not control this; that setting
|
||||
governs a separate provider request-queue mechanism.
|
||||
|
||||
**Fix:**
|
||||
|
||||
1. Retry first. Clients should honor `Retry-After` and use backoff rather than immediately
|
||||
repeating the request. Note that with the default `OMNIROUTE_CHAT_ADMISSION_QUEUE_MS=5000`
|
||||
a heavy request already waited up to 5 seconds before the `503`, so a client retry loop should
|
||||
back off beyond that instead of hammering.
|
||||
2. If normal deployment traffic repeatedly exhausts the guard, you can cautiously raise
|
||||
`OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT` from its default of `1`. Increase it one step at a time,
|
||||
restart OmniRoute after each change, and observe memory headroom under representative load.
|
||||
Every additional heavyweight request can increase concurrent V8 heap use and container or
|
||||
host OOM risk. No value is safe for every deployment; validate the setting against your own
|
||||
traffic and memory limits rather than assuming that `2` is universally safe.
|
||||
3. Prefer widening the wait (`OMNIROUTE_CHAT_ADMISSION_QUEUE_MS`) over raising the in-flight
|
||||
limit when bursts are short: waiting costs latency, while an extra concurrent heavyweight
|
||||
request costs heap residency for the whole request lifetime.
|
||||
repeating the request.
|
||||
2. Check `/api/monitoring/health` → `chatAdmission` before tuning anything. `countCapEnabled:
|
||||
false` and a generous `maxInflightBytes` mean the auto-derived budget is already doing its
|
||||
job; a `pressureSeverity` of `high`/`critical` means the host is genuinely low on memory —
|
||||
that is not fixable by an admission env var, it needs more RAM or a smaller workload.
|
||||
3. Only if `/api/monitoring/health` shows the auto-derived budget is genuinely too small for
|
||||
your host (rare — it already scales from container to bare-metal), override it directly with
|
||||
`OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES` rather than falling back to the legacy request-count cap.
|
||||
|
||||
See the [environment-variable reference](../reference/ENVIRONMENT.md#4-security--authentication)
|
||||
for the authoritative admission settings. Loosening the heavyweight classification thresholds
|
||||
can let expensive requests bypass this guard and is riskier than a cautious in-flight increase.
|
||||
for the authoritative admission settings.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -827,7 +827,7 @@ Configure via **Dashboard → Settings → Routing**. The dashboard exposes the
|
||||
- `p2c` (Power of Two Choices)
|
||||
- `least-used` and `cost-optimized`
|
||||
- `auto` — score-driven across all candidates
|
||||
- `lkgp` (Last Known Good Provider) — sticks to the last successful model per session
|
||||
- `lkgp` (Last Known Good Provider) — pins to the last successful provider, then falls back to rules
|
||||
- `context-optimized` — picks the model with the largest free context window
|
||||
- `context-relay` — chains long-context models for follow-up turns
|
||||
|
||||
@@ -1088,15 +1088,15 @@ Access via **Dashboard → Health**. Real-time system health overview with 6 car
|
||||
|
||||
OmniRoute ships with a **score-driven auto-router** that picks the best model for each request across every connected provider — no combo to maintain. Just send the request with one of the `auto/*` prefixes and OmniRoute will assemble a virtual combo on the fly, scoring candidates on latency, cost, success rate, context fit, model fitness for the task, recent failures, quota, and circuit-breaker state.
|
||||
|
||||
| Prefix | Optimizes for |
|
||||
| -------------- | ----------------------------------------------------------------------------- |
|
||||
| `auto` | Balanced default (latency × cost × success rate) |
|
||||
| `auto/coding` | Coding tasks: prefers Claude, GPT-5, GLM, Kimi, Qwen Coder, DeepSeek coders |
|
||||
| `auto/cheap` | Lowest $/token, accepts higher latency |
|
||||
| `auto/fast` | Lowest latency, ignores cost |
|
||||
| `auto/offline` | Local-only providers (Ollama, vLLM, llama.cpp) — useful for air-gapped setups |
|
||||
| `auto/smart` | Reasoning quality first (Opus, GPT-5 xhigh, R1, GLM 5.1 reasoning) |
|
||||
| `auto/lkgp` | "Last Known Good Provider" — sticky to the most recently successful target |
|
||||
| Prefix | Optimizes for |
|
||||
| -------------- | ------------------------------------------------------------------------------------------- |
|
||||
| `auto` | Balanced default (latency × cost × success rate) |
|
||||
| `auto/coding` | Coding tasks: prefers Claude, GPT-5, GLM, Kimi, Qwen Coder, DeepSeek coders |
|
||||
| `auto/cheap` | Lowest $/token, accepts higher latency |
|
||||
| `auto/fast` | Lowest latency, ignores cost |
|
||||
| `auto/offline` | Local-only providers (Ollama, vLLM, llama.cpp) — useful for air-gapped setups |
|
||||
| `auto/smart` | Reasoning quality first (Opus, GPT-5 xhigh, R1, GLM 5.1 reasoning) |
|
||||
| `auto/lkgp` | "Last Known Good Provider" — pins to the last successful provider, then falls back to rules |
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
@@ -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 353 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 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 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
|
||||
|
||||
## Overview
|
||||
|
||||
@@ -18,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
|
||||
|
||||
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
|
||||
- **Framework:** Next.js 16 (App Router) with TypeScript 6
|
||||
- **Database:** SQLite via better-sqlite3 (local, zero-config, 159 migrations)
|
||||
- **Database:** SQLite via better-sqlite3 (local, zero-config, 160 migrations)
|
||||
- **State management:** Zustand (client), SQLite (server persistence)
|
||||
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons
|
||||
- **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
|
||||
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
|
||||
## Key Features (v3.8.50)
|
||||
|
||||
### Core Proxy
|
||||
- **353 AI providers** with automatic format translation
|
||||
- **354 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
|
||||
@@ -438,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
|
||||
|
||||
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`.
|
||||
|
||||
5. **Database layer:** Operations go through `src/lib/db/` modules (120 domain-specific files, 159 migrations). `localDb.ts` is re-exports only — add new functions to the proper `db/*.ts` module.
|
||||
5. **Database layer:** Operations go through `src/lib/db/` modules (120 domain-specific files, 160 migrations). `localDb.ts` is re-exports only — add new functions to the proper `db/*.ts` module.
|
||||
|
||||
6. **Tests** use Node.js built-in test runner + Vitest. Run `npm test`. Vitest for MCP/autoCombo (`npm run test:vitest`). Playwright for E2E (`npm run test:e2e`). Coverage gate: ratchet vs `quality-baseline.json`, absolute floor 60% statements/lines/functions/branches.
|
||||
|
||||
@@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
|
||||
|
||||
## v3.8.x Highlights
|
||||
|
||||
- **353-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
|
||||
- **354-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 110 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
|
||||
|
||||
@@ -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 353 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 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 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
|
||||
|
||||
## Overview
|
||||
|
||||
@@ -18,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
|
||||
|
||||
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
|
||||
- **Framework:** Next.js 16 (App Router) with TypeScript 6
|
||||
- **Database:** SQLite via better-sqlite3 (local, zero-config, 159 migrations)
|
||||
- **Database:** SQLite via better-sqlite3 (local, zero-config, 160 migrations)
|
||||
- **State management:** Zustand (client), SQLite (server persistence)
|
||||
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons
|
||||
- **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
|
||||
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
|
||||
## Key Features (v3.8.50)
|
||||
|
||||
### Core Proxy
|
||||
- **353 AI providers** with automatic format translation
|
||||
- **354 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
|
||||
@@ -438,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
|
||||
|
||||
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`.
|
||||
|
||||
5. **Database layer:** Operations go through `src/lib/db/` modules (120 domain-specific files, 159 migrations). `localDb.ts` is re-exports only — add new functions to the proper `db/*.ts` module.
|
||||
5. **Database layer:** Operations go through `src/lib/db/` modules (120 domain-specific files, 160 migrations). `localDb.ts` is re-exports only — add new functions to the proper `db/*.ts` module.
|
||||
|
||||
6. **Tests** use Node.js built-in test runner + Vitest. Run `npm test`. Vitest for MCP/autoCombo (`npm run test:vitest`). Playwright for E2E (`npm run test:e2e`). Coverage gate: ratchet vs `quality-baseline.json`, absolute floor 60% statements/lines/functions/branches.
|
||||
|
||||
@@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
|
||||
|
||||
## v3.8.x Highlights
|
||||
|
||||
- **353-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
|
||||
- **354-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 110 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
|
||||
|
||||
@@ -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 353 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 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 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
|
||||
|
||||
## Overview
|
||||
|
||||
@@ -18,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
|
||||
|
||||
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
|
||||
- **Framework:** Next.js 16 (App Router) with TypeScript 6
|
||||
- **Database:** SQLite via better-sqlite3 (local, zero-config, 159 migrations)
|
||||
- **Database:** SQLite via better-sqlite3 (local, zero-config, 160 migrations)
|
||||
- **State management:** Zustand (client), SQLite (server persistence)
|
||||
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons
|
||||
- **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
|
||||
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
|
||||
## Key Features (v3.8.50)
|
||||
|
||||
### Core Proxy
|
||||
- **353 AI providers** with automatic format translation
|
||||
- **354 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
|
||||
@@ -438,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
|
||||
|
||||
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`.
|
||||
|
||||
5. **Database layer:** Operations go through `src/lib/db/` modules (120 domain-specific files, 159 migrations). `localDb.ts` is re-exports only — add new functions to the proper `db/*.ts` module.
|
||||
5. **Database layer:** Operations go through `src/lib/db/` modules (120 domain-specific files, 160 migrations). `localDb.ts` is re-exports only — add new functions to the proper `db/*.ts` module.
|
||||
|
||||
6. **Tests** use Node.js built-in test runner + Vitest. Run `npm test`. Vitest for MCP/autoCombo (`npm run test:vitest`). Playwright for E2E (`npm run test:e2e`). Coverage gate: ratchet vs `quality-baseline.json`, absolute floor 60% statements/lines/functions/branches.
|
||||
|
||||
@@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
|
||||
|
||||
## v3.8.x Highlights
|
||||
|
||||
- **353-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
|
||||
- **354-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 110 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
|
||||
|
||||
@@ -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 353 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 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 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
|
||||
|
||||
## Overview
|
||||
|
||||
@@ -18,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
|
||||
|
||||
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
|
||||
- **Framework:** Next.js 16 (App Router) with TypeScript 6
|
||||
- **Database:** SQLite via better-sqlite3 (local, zero-config, 159 migrations)
|
||||
- **Database:** SQLite via better-sqlite3 (local, zero-config, 160 migrations)
|
||||
- **State management:** Zustand (client), SQLite (server persistence)
|
||||
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons
|
||||
- **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
|
||||
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
|
||||
## Key Features (v3.8.50)
|
||||
|
||||
### Core Proxy
|
||||
- **353 AI providers** with automatic format translation
|
||||
- **354 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
|
||||
@@ -438,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
|
||||
|
||||
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`.
|
||||
|
||||
5. **Database layer:** Operations go through `src/lib/db/` modules (120 domain-specific files, 159 migrations). `localDb.ts` is re-exports only — add new functions to the proper `db/*.ts` module.
|
||||
5. **Database layer:** Operations go through `src/lib/db/` modules (120 domain-specific files, 160 migrations). `localDb.ts` is re-exports only — add new functions to the proper `db/*.ts` module.
|
||||
|
||||
6. **Tests** use Node.js built-in test runner + Vitest. Run `npm test`. Vitest for MCP/autoCombo (`npm run test:vitest`). Playwright for E2E (`npm run test:e2e`). Coverage gate: ratchet vs `quality-baseline.json`, absolute floor 60% statements/lines/functions/branches.
|
||||
|
||||
@@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
|
||||
|
||||
## v3.8.x Highlights
|
||||
|
||||
- **353-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
|
||||
- **354-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 110 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
|
||||
|
||||
@@ -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 353 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 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 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
|
||||
|
||||
## Overview
|
||||
|
||||
@@ -18,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
|
||||
|
||||
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
|
||||
- **Framework:** Next.js 16 (App Router) with TypeScript 6
|
||||
- **Database:** SQLite via better-sqlite3 (local, zero-config, 159 migrations)
|
||||
- **Database:** SQLite via better-sqlite3 (local, zero-config, 160 migrations)
|
||||
- **State management:** Zustand (client), SQLite (server persistence)
|
||||
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons
|
||||
- **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
|
||||
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
|
||||
## Key Features (v3.8.50)
|
||||
|
||||
### Core Proxy
|
||||
- **353 AI providers** with automatic format translation
|
||||
- **354 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
|
||||
@@ -438,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
|
||||
|
||||
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`.
|
||||
|
||||
5. **Database layer:** Operations go through `src/lib/db/` modules (120 domain-specific files, 159 migrations). `localDb.ts` is re-exports only — add new functions to the proper `db/*.ts` module.
|
||||
5. **Database layer:** Operations go through `src/lib/db/` modules (120 domain-specific files, 160 migrations). `localDb.ts` is re-exports only — add new functions to the proper `db/*.ts` module.
|
||||
|
||||
6. **Tests** use Node.js built-in test runner + Vitest. Run `npm test`. Vitest for MCP/autoCombo (`npm run test:vitest`). Playwright for E2E (`npm run test:e2e`). Coverage gate: ratchet vs `quality-baseline.json`, absolute floor 60% statements/lines/functions/branches.
|
||||
|
||||
@@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
|
||||
|
||||
## v3.8.x Highlights
|
||||
|
||||
- **353-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
|
||||
- **354-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 110 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
|
||||
|
||||
@@ -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 353 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 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 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
|
||||
|
||||
## Overview
|
||||
|
||||
@@ -18,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
|
||||
|
||||
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
|
||||
- **Framework:** Next.js 16 (App Router) with TypeScript 6
|
||||
- **Database:** SQLite via better-sqlite3 (local, zero-config, 159 migrations)
|
||||
- **Database:** SQLite via better-sqlite3 (local, zero-config, 160 migrations)
|
||||
- **State management:** Zustand (client), SQLite (server persistence)
|
||||
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons
|
||||
- **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
|
||||
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
|
||||
## Key Features (v3.8.50)
|
||||
|
||||
### Core Proxy
|
||||
- **353 AI providers** with automatic format translation
|
||||
- **354 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
|
||||
@@ -438,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
|
||||
|
||||
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`.
|
||||
|
||||
5. **Database layer:** Operations go through `src/lib/db/` modules (120 domain-specific files, 159 migrations). `localDb.ts` is re-exports only — add new functions to the proper `db/*.ts` module.
|
||||
5. **Database layer:** Operations go through `src/lib/db/` modules (120 domain-specific files, 160 migrations). `localDb.ts` is re-exports only — add new functions to the proper `db/*.ts` module.
|
||||
|
||||
6. **Tests** use Node.js built-in test runner + Vitest. Run `npm test`. Vitest for MCP/autoCombo (`npm run test:vitest`). Playwright for E2E (`npm run test:e2e`). Coverage gate: ratchet vs `quality-baseline.json`, absolute floor 60% statements/lines/functions/branches.
|
||||
|
||||
@@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
|
||||
|
||||
## v3.8.x Highlights
|
||||
|
||||
- **353-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
|
||||
- **354-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 110 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
|
||||
|
||||
@@ -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 353 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 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 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
|
||||
|
||||
## Overview
|
||||
|
||||
@@ -18,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
|
||||
|
||||
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
|
||||
- **Framework:** Next.js 16 (App Router) with TypeScript 6
|
||||
- **Database:** SQLite via better-sqlite3 (local, zero-config, 159 migrations)
|
||||
- **Database:** SQLite via better-sqlite3 (local, zero-config, 160 migrations)
|
||||
- **State management:** Zustand (client), SQLite (server persistence)
|
||||
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons
|
||||
- **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
|
||||
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
|
||||
## Key Features (v3.8.50)
|
||||
|
||||
### Core Proxy
|
||||
- **353 AI providers** with automatic format translation
|
||||
- **354 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
|
||||
@@ -438,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
|
||||
|
||||
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`.
|
||||
|
||||
5. **Database layer:** Operations go through `src/lib/db/` modules (120 domain-specific files, 159 migrations). `localDb.ts` is re-exports only — add new functions to the proper `db/*.ts` module.
|
||||
5. **Database layer:** Operations go through `src/lib/db/` modules (120 domain-specific files, 160 migrations). `localDb.ts` is re-exports only — add new functions to the proper `db/*.ts` module.
|
||||
|
||||
6. **Tests** use Node.js built-in test runner + Vitest. Run `npm test`. Vitest for MCP/autoCombo (`npm run test:vitest`). Playwright for E2E (`npm run test:e2e`). Coverage gate: ratchet vs `quality-baseline.json`, absolute floor 60% statements/lines/functions/branches.
|
||||
|
||||
@@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
|
||||
|
||||
## v3.8.x Highlights
|
||||
|
||||
- **353-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
|
||||
- **354-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 110 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
|
||||
|
||||
@@ -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 353 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 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 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
|
||||
|
||||
## Overview
|
||||
|
||||
@@ -18,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
|
||||
|
||||
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
|
||||
- **Framework:** Next.js 16 (App Router) with TypeScript 6
|
||||
- **Database:** SQLite via better-sqlite3 (local, zero-config, 159 migrations)
|
||||
- **Database:** SQLite via better-sqlite3 (local, zero-config, 160 migrations)
|
||||
- **State management:** Zustand (client), SQLite (server persistence)
|
||||
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons
|
||||
- **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
|
||||
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
|
||||
## Key Features (v3.8.50)
|
||||
|
||||
### Core Proxy
|
||||
- **353 AI providers** with automatic format translation
|
||||
- **354 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
|
||||
@@ -438,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
|
||||
|
||||
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`.
|
||||
|
||||
5. **Database layer:** Operations go through `src/lib/db/` modules (120 domain-specific files, 159 migrations). `localDb.ts` is re-exports only — add new functions to the proper `db/*.ts` module.
|
||||
5. **Database layer:** Operations go through `src/lib/db/` modules (120 domain-specific files, 160 migrations). `localDb.ts` is re-exports only — add new functions to the proper `db/*.ts` module.
|
||||
|
||||
6. **Tests** use Node.js built-in test runner + Vitest. Run `npm test`. Vitest for MCP/autoCombo (`npm run test:vitest`). Playwright for E2E (`npm run test:e2e`). Coverage gate: ratchet vs `quality-baseline.json`, absolute floor 60% statements/lines/functions/branches.
|
||||
|
||||
@@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
|
||||
|
||||
## v3.8.x Highlights
|
||||
|
||||
- **353-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
|
||||
- **354-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 110 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
|
||||
|
||||
@@ -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 353 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 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 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
|
||||
|
||||
## Overview
|
||||
|
||||
@@ -18,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
|
||||
|
||||
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
|
||||
- **Framework:** Next.js 16 (App Router) with TypeScript 6
|
||||
- **Database:** SQLite via better-sqlite3 (local, zero-config, 159 migrations)
|
||||
- **Database:** SQLite via better-sqlite3 (local, zero-config, 160 migrations)
|
||||
- **State management:** Zustand (client), SQLite (server persistence)
|
||||
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons
|
||||
- **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
|
||||
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
|
||||
## Key Features (v3.8.50)
|
||||
|
||||
### Core Proxy
|
||||
- **353 AI providers** with automatic format translation
|
||||
- **354 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
|
||||
@@ -438,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
|
||||
|
||||
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`.
|
||||
|
||||
5. **Database layer:** Operations go through `src/lib/db/` modules (120 domain-specific files, 159 migrations). `localDb.ts` is re-exports only — add new functions to the proper `db/*.ts` module.
|
||||
5. **Database layer:** Operations go through `src/lib/db/` modules (120 domain-specific files, 160 migrations). `localDb.ts` is re-exports only — add new functions to the proper `db/*.ts` module.
|
||||
|
||||
6. **Tests** use Node.js built-in test runner + Vitest. Run `npm test`. Vitest for MCP/autoCombo (`npm run test:vitest`). Playwright for E2E (`npm run test:e2e`). Coverage gate: ratchet vs `quality-baseline.json`, absolute floor 60% statements/lines/functions/branches.
|
||||
|
||||
@@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
|
||||
|
||||
## v3.8.x Highlights
|
||||
|
||||
- **353-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
|
||||
- **354-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 110 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
|
||||
|
||||
@@ -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 353 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 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 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
|
||||
|
||||
## Overview
|
||||
|
||||
@@ -18,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
|
||||
|
||||
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
|
||||
- **Framework:** Next.js 16 (App Router) with TypeScript 6
|
||||
- **Database:** SQLite via better-sqlite3 (local, zero-config, 159 migrations)
|
||||
- **Database:** SQLite via better-sqlite3 (local, zero-config, 160 migrations)
|
||||
- **State management:** Zustand (client), SQLite (server persistence)
|
||||
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons
|
||||
- **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
|
||||
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
|
||||
## Key Features (v3.8.50)
|
||||
|
||||
### Core Proxy
|
||||
- **353 AI providers** with automatic format translation
|
||||
- **354 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
|
||||
@@ -438,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
|
||||
|
||||
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`.
|
||||
|
||||
5. **Database layer:** Operations go through `src/lib/db/` modules (120 domain-specific files, 159 migrations). `localDb.ts` is re-exports only — add new functions to the proper `db/*.ts` module.
|
||||
5. **Database layer:** Operations go through `src/lib/db/` modules (120 domain-specific files, 160 migrations). `localDb.ts` is re-exports only — add new functions to the proper `db/*.ts` module.
|
||||
|
||||
6. **Tests** use Node.js built-in test runner + Vitest. Run `npm test`. Vitest for MCP/autoCombo (`npm run test:vitest`). Playwright for E2E (`npm run test:e2e`). Coverage gate: ratchet vs `quality-baseline.json`, absolute floor 60% statements/lines/functions/branches.
|
||||
|
||||
@@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
|
||||
|
||||
## v3.8.x Highlights
|
||||
|
||||
- **353-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
|
||||
- **354-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 110 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
|
||||
|
||||
@@ -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 353 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 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 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
|
||||
|
||||
## Overview
|
||||
|
||||
@@ -18,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
|
||||
|
||||
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
|
||||
- **Framework:** Next.js 16 (App Router) with TypeScript 6
|
||||
- **Database:** SQLite via better-sqlite3 (local, zero-config, 159 migrations)
|
||||
- **Database:** SQLite via better-sqlite3 (local, zero-config, 160 migrations)
|
||||
- **State management:** Zustand (client), SQLite (server persistence)
|
||||
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons
|
||||
- **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
|
||||
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
|
||||
## Key Features (v3.8.50)
|
||||
|
||||
### Core Proxy
|
||||
- **353 AI providers** with automatic format translation
|
||||
- **354 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
|
||||
@@ -438,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
|
||||
|
||||
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`.
|
||||
|
||||
5. **Database layer:** Operations go through `src/lib/db/` modules (120 domain-specific files, 159 migrations). `localDb.ts` is re-exports only — add new functions to the proper `db/*.ts` module.
|
||||
5. **Database layer:** Operations go through `src/lib/db/` modules (120 domain-specific files, 160 migrations). `localDb.ts` is re-exports only — add new functions to the proper `db/*.ts` module.
|
||||
|
||||
6. **Tests** use Node.js built-in test runner + Vitest. Run `npm test`. Vitest for MCP/autoCombo (`npm run test:vitest`). Playwright for E2E (`npm run test:e2e`). Coverage gate: ratchet vs `quality-baseline.json`, absolute floor 60% statements/lines/functions/branches.
|
||||
|
||||
@@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
|
||||
|
||||
## v3.8.x Highlights
|
||||
|
||||
- **353-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
|
||||
- **354-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 110 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
|
||||
|
||||
@@ -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 353 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 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 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
|
||||
|
||||
## Overview
|
||||
|
||||
@@ -18,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
|
||||
|
||||
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
|
||||
- **Framework:** Next.js 16 (App Router) with TypeScript 6
|
||||
- **Database:** SQLite via better-sqlite3 (local, zero-config, 159 migrations)
|
||||
- **Database:** SQLite via better-sqlite3 (local, zero-config, 160 migrations)
|
||||
- **State management:** Zustand (client), SQLite (server persistence)
|
||||
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons
|
||||
- **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
|
||||
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
|
||||
## Key Features (v3.8.50)
|
||||
|
||||
### Core Proxy
|
||||
- **353 AI providers** with automatic format translation
|
||||
- **354 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
|
||||
@@ -438,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
|
||||
|
||||
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`.
|
||||
|
||||
5. **Database layer:** Operations go through `src/lib/db/` modules (120 domain-specific files, 159 migrations). `localDb.ts` is re-exports only — add new functions to the proper `db/*.ts` module.
|
||||
5. **Database layer:** Operations go through `src/lib/db/` modules (120 domain-specific files, 160 migrations). `localDb.ts` is re-exports only — add new functions to the proper `db/*.ts` module.
|
||||
|
||||
6. **Tests** use Node.js built-in test runner + Vitest. Run `npm test`. Vitest for MCP/autoCombo (`npm run test:vitest`). Playwright for E2E (`npm run test:e2e`). Coverage gate: ratchet vs `quality-baseline.json`, absolute floor 60% statements/lines/functions/branches.
|
||||
|
||||
@@ -479,7 +479,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
|
||||
|
||||
## v3.8.x Highlights
|
||||
|
||||
- **353-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
|
||||
- **354-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 110 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
|
||||
|
||||