Compare commits

..

1 Commits

Author SHA1 Message Date
adevwithpurpose
ff6d465140 fix(dashboard): remap Kimi Code API-key save to admitted managed id (#10096)
The unified Kimi Code card's API-key branch posted provider: "kimi-coding"
to POST /api/providers. "kimi-coding" is an OAuth-primary managed id, not
an admitted API-key/dual-auth connection id, so the backend correctly
rejected it with 400 "Invalid provider" even though key validation passed.

Add resolveApiKeySaveProviderId() in useApiKeySave.ts to remap the posted
provider id to the dedicated, admitted managed API-key id
"kimi-coding-apikey" for the API-key save flow only. The OAuth flow
(handleOAuthSuccess in ProviderDetailPageClient.tsx) never calls this hook
and keeps posting "kimi-coding" unchanged.

Regression test: tests/unit/bug-10096-kimi-coding-apikey-save.test.ts
2026-08-14 18:38:39 -03:00
231 changed files with 1940 additions and 12903 deletions

View File

@@ -2652,9 +2652,9 @@ QUOTA_STORE_DRIVER=sqlite
# ═══════════════════════════════════════════════════════════════════════════════
# Optional add-on (feature flag RADAR_ENABLED, default off — see feature flag
# settings, not an env var) that overlays a signed, freshly-curated free-model
# catalog on top of the release baseline. The first four variables below are
# optional overrides for a self-hosted/forked feed or supporter-key flow. The
# fifth is an optional, default-free link to the owner's private operations panel. Used by:
# catalog on top of the release baseline. All four variables below are optional
# and only needed to point the client at a self-hosted/forked feed or
# supporter-key flow instead of the default OmniRoute Radar service. Used by:
# src/lib/radar/sync.ts, src/lib/radar/pinnedKeys.ts, src/lib/radar/links.ts.
# Base URL of the Radar feed service. Overrides the built-in default so forks
@@ -2675,11 +2675,6 @@ QUOTA_STORE_DRIVER=sqlite
# page). No pricing/value lives in this repo — only the link.
# RADAR_SUPPORTER_PLANS_URL=https://radar.omniroute.online/planos
# Owner-only link to the private Radar operations panel. There is deliberately
# no default: when unset or invalid, no "Radar Admin" navigation item exists.
# Use HTTPS for a tunnel/tailnet URL, or HTTP only for an SSH loopback forward.
# RADAR_ADMIN_URL=http://127.0.0.1:9351
# ═══════════════════════════════════════════════════════════════════════════════
# 27. RELEASE v3.8.50 ADDITIONS
# ═══════════════════════════════════════════════════════════════════════════════

View File

@@ -18,7 +18,7 @@ Vitest, the 60% coverage gate, and the production build all run in CI on this PR
- [ ] `npm run lint`
- [ ] Reconciled with the current active release base; focused checks rerun afterward
- [ ] Production-code changes include a new or updated automated test in this PR
- SonarQube is temporarily opt-in while the private project has no quota; it is not a PR gate.
- [ ] SonarQube PR analysis is green or any remaining issues are explicitly documented below
## Tests Added Or Updated

View File

@@ -998,10 +998,7 @@ jobs:
name: SonarQube
runs-on: ubuntu-latest
needs: test-coverage
# Temporarily opt-in: the private project currently has no Sonar quota.
# Re-enable without another code change by setting the repository Actions
# variable SONARQUBE_ENABLED=true after quota/project access is restored.
if: ${{ vars.SONARQUBE_ENABLED == 'true' && !cancelled() && needs.test-coverage.result == 'success' }}
if: ${{ !cancelled() && needs.test-coverage.result == 'success' }}
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
@@ -1400,7 +1397,7 @@ jobs:
echo "| i18n UI Coverage | $(status '${{ needs.i18n-ui-coverage.result }}') |" >> "$GITHUB_STEP_SUMMARY"
echo "| i18n Glossary (zh-CN, ko) | $(status '${{ needs.i18n-glossary-zhcn.result }}') |" >> "$GITHUB_STEP_SUMMARY"
echo "| PR Test Policy | $(status '${{ needs.pr-test-policy.result }}') |" >> "$GITHUB_STEP_SUMMARY"
echo "| SonarQube (opt-in; disabled without SONARQUBE_ENABLED=true) | $(status '${{ needs.sonarqube.result }}') |" >> "$GITHUB_STEP_SUMMARY"
echo "| SonarQube | $(status '${{ needs.sonarqube.result }}') |" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "## 🏗️ Build" >> "$GITHUB_STEP_SUMMARY"

View File

@@ -60,49 +60,13 @@ jobs:
build:
name: Build (advisory)
needs: changes
# FORK PRs ONLY. build.yml's `Fast Production Build` triggers on `push: branches: ["**"]`
# and runs `build:release` — a superset of this job — so for an own-origin branch this job
# was building the same tree twice. A fork contributor pushes to THEIR repo, so that push
# never fires here, and this is the only pre-merge build signal they get. Measured
# 2026-08-14: 72 of the last 100 PRs into release/** came from forks, so the fork case is
# the majority of the traffic, not the exception — this job earns its place, it just should
# not duplicate build.yml for the own-origin 28%.
if: ${{ github.event_name != 'pull_request' || ((github.event.pull_request.draft == false || startsWith(github.head_ref, 'mergify/merge-queue/')) && needs.changes.outputs.code == 'true' && github.event.pull_request.head.repo.full_name != github.repository) }}
# PINNED to hosted — this was the last job in THIS workflow still on the USE_VPS_RUNNER
# switch (ci.yml's Build, nightly-release-green and npm-publish keep it, so the variable
# stays meaningful), and with USE_VPS_RUNNER=true it produced NO signal at all here.
# Measured 2026-08-14 over the last 25
# quality.yml runs: not one Build (advisory) reached a conclusion. Every sample was either
# queued on the self-hosted pool (2 runners, `omniroute-113-6/7`, both permanently busy — one
# job sat queued 2h+ and was still unclaimed) or, when it did land, killed mid-build by this
# workflow's own `cancel-in-progress` concurrency. 6/6 sampled "failures" are exit 143 /
# "The runner has received a shutdown signal" at ~3.5 min into `npm run build` — zero OOM,
# zero build errors. So the job burned a scarce runner that the gates actually need while
# reporting a permanent red on every PR.
#
# Gap 19 left USE_VPS_RUNNER governing build-like jobs on the premise that "the build needs
# the .113's RAM". That premise no longer holds: `Fast Production Build` (build.yml) runs
# `build:release` — a SUPERSET of this job's `npm run build`, plus the CLI bundle — on plain
# ubuntu-latest and passed 24/25 of its last runs in ~15 min. What it has and this job did
# not is memory PROVISIONING: a 10 GB swapfile plus a 12 GB V8 heap. That matters because
# --max-old-space-size only bounds V8's JS heap, never Turbopack's native (Rust) allocation
# (#6409) — swap is what absorbs the native peak. Both are mirrored below.
runs-on: ubuntu-latest
if: ${{ github.event_name != 'pull_request' || ((github.event.pull_request.draft == false || startsWith(github.head_ref, 'mergify/merge-queue/')) && needs.changes.outputs.code == 'true') }}
# Dynamic runner — same fork-safe rule as ci.yml / fast-gates.
runs-on: ${{ (vars.USE_VPS_RUNNER == 'true' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository)) && fromJSON('["self-hosted","omni-release"]') || 'ubuntu-latest' }}
# #7307: advisory for the first week of release-PR runs; remove
# continue-on-error after the production-build signal is stable.
continue-on-error: true
steps:
# Mirrors build.yml: Turbopack's native peak is not bounded by --max-old-space-size, so
# the hosted runner needs swap headroom before the build starts.
- name: Expand virtual memory (10 GB swap)
run: |
sudo swapoff -a || true
sudo rm -f /mnt/swapfile /swapfile
sudo fallocate -l 10G /mnt/swapfile || sudo dd if=/dev/zero of=/mnt/swapfile bs=1M count=10240
sudo chmod 600 /mnt/swapfile
sudo mkswap /mnt/swapfile
sudo swapon /mnt/swapfile
free -h
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false
@@ -115,10 +79,6 @@ jobs:
- run: npm run build
env:
OMNIROUTE_USE_TURBOPACK: "1"
# Same heap build.yml proves sufficient. build-next-isolated.mjs defaults to 8192 and
# honours OMNIROUTE_BUILD_MEMORY_MB; NODE_OPTIONS is set for parity with build.yml.
NODE_OPTIONS: "--max-old-space-size=12288"
OMNIROUTE_BUILD_MEMORY_MB: "12288"
# No artifact upload here: the PR-to-release quality workflow has no
# downstream package/e2e jobs that consume the Next.js build output.

View File

@@ -48,20 +48,20 @@ Repository map and Reference Documentation sections below.
**OmniRoute** — unified AI proxy/router. One endpoint, 339 LLM providers, auto-fallback.
| Layer | Location | Purpose |
| ------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| API Routes | `src/app/api/v1/` | Next.js App Router — entry points |
| Handlers | `open-sse/handlers/` | Request processing (chat, embeddings, etc) |
| Executors | `open-sse/executors/` | Provider-specific HTTP dispatch |
| 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 (148 migrations) |
| Domain/Policy | `src/domain/` | Policy engine, cost rules, fallback logic |
| MCP Server | `open-sse/mcp-server/` | 109 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 |
| Skills | `src/lib/skills/` | Extensible skill framework |
| Memory | `src/lib/memory/` | Persistent conversational memory |
| Layer | Location | Purpose |
| ------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| API Routes | `src/app/api/v1/` | Next.js App Router — entry points |
| Handlers | `open-sse/handlers/` | Request processing (chat, embeddings, etc) |
| Executors | `open-sse/executors/` | Provider-specific HTTP dispatch |
| 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 (145 migrations) |
| Domain/Policy | `src/domain/` | Policy engine, cost rules, fallback logic |
| MCP Server | `open-sse/mcp-server/` | 105 tools (43 base + memory/skill/agentSkill/pool/notion/obsidian/gamification/plugin modules), 3 transports (stdio / SSE / Streamable HTTP), 31 scopes |
| A2A Server | `src/lib/a2a/` | JSON-RPC 2.0 agent protocol |
| Skills | `src/lib/skills/` | Extensible skill framework |
| Memory | `src/lib/memory/` | Persistent conversational memory |
Monorepo: `src/` (Next.js 16 app), `open-sse/` (streaming engine workspace), `electron/` (desktop app), `tests/`, `bin/` (CLI entry point).
@@ -679,7 +679,7 @@ the stale-enforcement added in Fase 6A.3.
causa-raiz de DOIS wipes (2026-08-08 e 2026-08-10: `git reset --hard` materializou o
symlink rastreado por cima do diretório real e o git apagou todo o conteúdo ignorado sem
aviso); (c) após qualquer escrita relevante, `git -C _tasks add -A && git -C _tasks commit
&& git -C _tasks push` — o push frequente é o backup real; (d) repetir esta proibição
&& git -C _tasks push` — o push frequente é o backup real; (d) repetir esta proibição
VERBATIM no prompt de todo subagente que toque git; (e) se `_tasks` aparecer como symlink
quebrado, NÃO commitar nada — restaurar do remote e avisar o operador. O gate
`check:tracked-artifacts` (pre-commit + CI) bloqueia `_tasks` rastreado em qualquer forma.

View File

@@ -210,7 +210,7 @@ curl http://localhost:20128/v1/chat/completions \
</div>
<img src="./docs/diagrams/promise-pillars.svg" width="100%" alt="The Promise — One endpoint. 339 providers. Never stop building — OmniRoute picks the cheapest one that works. Six pillars: Never hit limits (auto-fallback across 339 providers in milliseconds, zero downtime) · Save up to 95% tokens (RTK + Caveman stacked compression cuts 1595%, ~89% avg on tool-heavy sessions) · $0 to start (90+ free tiers, 40+ free forever — no card needed) · Every tool works (33 coding agents through one config) · One endpoint (OpenAI ↔ Claude ↔ Gemini ↔ Responses API at /v1) · Production-grade (circuit breakers, TLS stealth, MCP 109 tools, A2A, memory, guardrails, evals — 25,000+ tests)."/>
<img src="./docs/diagrams/promise-pillars.svg" width="100%" alt="The Promise — One endpoint. 339 providers. Never stop building — OmniRoute picks the cheapest one that works. Six pillars: Never hit limits (auto-fallback across 339 providers in milliseconds, zero downtime) · Save up to 95% tokens (RTK + Caveman stacked compression cuts 1595%, ~89% avg on tool-heavy sessions) · $0 to start (90+ free tiers, 40+ free forever — no card needed) · Every tool works (33 coding agents through one config) · One endpoint (OpenAI ↔ Claude ↔ Gemini ↔ Responses API at /v1) · Production-grade (circuit breakers, TLS stealth, MCP 105 tools, A2A, memory, guardrails, evals — 25,000+ tests)."/>
<br/>
<br/>
@@ -461,7 +461,7 @@ All **19** strategies — mix & match per combo step:
</div>
<img src="./docs/diagrams/comparison-table.svg" width="100%" alt="What sets OmniRoute apart — comparison table vs 9router, OpenRouter, CLIProxyAPI and LiteLLM across 13 capabilities. OmniRoute: 339 providers, 90+ free providers built-in, 19 routing strategies, 12-engine token compression, built-in MCP server with 109 tools, A2A agent protocol, persistent memory, guardrails, cloud agents, TLS fingerprint stealth, Desktop/Termux/PWA, 43 i18n UI locales, 100% MIT self-hosted. OmniRoute is the only one with the full set; competitors show a mix of checks, partials and crosses. Verified from each project&apos;s docs."/>
<img src="./docs/diagrams/comparison-table.svg" width="100%" alt="What sets OmniRoute apart — comparison table vs 9router, OpenRouter, CLIProxyAPI and LiteLLM across 13 capabilities. OmniRoute: 339 providers, 90+ free providers built-in, 19 routing strategies, 12-engine token compression, built-in MCP server with 105 tools, A2A agent protocol, persistent memory, guardrails, cloud agents, TLS fingerprint stealth, Desktop/Termux/PWA, 43 i18n UI locales, 100% MIT self-hosted. OmniRoute is the only one with the full set; competitors show a mix of checks, partials and crosses. Verified from each project&apos;s docs."/>
<sub>📊 Full methodology &amp; per-feature detail vs 9router, OpenRouter, CLIProxyAPI &amp; LiteLLM → [`docs/comparison/OMNIROUTE_VS_ALTERNATIVES.md`](docs/comparison/OMNIROUTE_VS_ALTERNATIVES.md)</sub>
@@ -513,25 +513,6 @@ Pix copia-e-cola:
<br/>
## 📡 OmniRoute Radar
The main free-tier headline remains **~1.53B tokens/month** from the documented,
pool-deduplicated catalog above. Temporary provider signup credits can separately lift the first
month to **~2.15B**. Radar is an optional, signed catalog overlay for people who want fresher
free-model availability between OmniRoute releases; the community catalog and every existing free
feature remain free.
Supporters can receive the live catalog and additional provider opportunities. Its separate,
mutable ceiling is **approximately 3B tokens/month at most**, depending on provider availability.
That ceiling is not a guarantee: providers can change quotas, eligibility, models, or regions at
any time.
Radar is opt-in and GET-only. The OmniRoute client does not upload prompts, traffic, provider
configuration, usage telemetry, or local announcement-dismiss state. Learn about eligibility and
the current catalog at **[radar.omniroute.online/planos](https://radar.omniroute.online/planos)**.
<br/>
<div align="center">
## ✨ What's New
@@ -767,7 +748,7 @@ Expose OmniRoute over **MCP**, **A2A**, a **REST API**, **webhooks** or a **remo
<table>
<tr><th align="left">Interface</th><th align="left">Endpoint / command</th><th align="left">Use it for</th></tr>
<tr><td align="left" nowrap>🧰 <b>MCP (stdio)</b></td><td align="left" nowrap><code>omniroute --mcp</code></td><td align="left">Plug into Claude Desktop, Cursor, any MCP client</td></tr>
<tr><td align="left" nowrap>🌊 <b>MCP (HTTP)</b></td><td align="left" nowrap><code>/api/mcp/stream</code></td><td align="left">Remote MCP — <b>109 tools</b>, 33 scopes, full audit trail</td></tr>
<tr><td align="left" nowrap>🌊 <b>MCP (HTTP)</b></td><td align="left" nowrap><code>/api/mcp/stream</code></td><td align="left">Remote MCP — <b>105 tools</b>, 31 scopes, full audit trail</td></tr>
<tr><td align="left" nowrap>📡 <b>MCP (SSE)</b></td><td align="left" nowrap><code>/api/mcp/sse</code></td><td align="left">Streaming MCP transport</td></tr>
<tr><td align="left" nowrap>🤝 <b>A2A</b></td><td align="left" nowrap><code>/.well-known/agent.json</code></td><td align="left">Agent-to-agent, <b>JSON-RPC 2.0</b> + SSE, 6 skills</td></tr>
<tr><td align="left" nowrap>🌐 <b>REST API</b></td><td align="left" nowrap><code>/v1/*</code></td><td align="left">OpenAI-compatible — chat, embeddings, images, audio, OCR</td></tr>
@@ -1080,7 +1061,7 @@ same process on one port, so there is no separate CLI-only package today.
<tr><td nowrap><b>Runtime</b></td><td>Node.js 22.x / 24.x LTS — <code>&gt;=22.22.2 &lt;23 || &gt;=24.0.0 &lt;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) — 117 domain modules, 148 migrations</td></tr>
<tr><td nowrap><b>Database</b></td><td>better-sqlite3 (SQLite, WAL journaling) + LowDB (JSON legacy) — 95 domain modules, 145 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>
@@ -1154,7 +1135,7 @@ same process on one port, so there is no separate CLI-only package today.
<tr><th align="left">Document</th><th align="left">Description</th></tr>
<tr><td nowrap><b><a href="docs/reference/API_REFERENCE.md">API Reference</a></b></td><td>All endpoints with examples</td></tr>
<tr><td nowrap><b><a href="docs/openapi.yaml">OpenAPI Spec</a></b></td><td>OpenAPI 3.0 specification</td></tr>
<tr><td nowrap><b><a href="open-sse/mcp-server/README.md">MCP Server</a></b></td><td>109 MCP tools, IDE configs, Python/TS/Go clients</td></tr>
<tr><td nowrap><b><a href="open-sse/mcp-server/README.md">MCP Server</a></b></td><td>105 MCP tools, IDE configs, Python/TS/Go clients</td></tr>
<tr><td nowrap><b><a href="docs/frameworks/MCP-SERVER.md">MCP Server Guide</a></b></td><td>MCP installation, transports, and tool reference</td></tr>
<tr><td nowrap><b><a href="src/lib/a2a/README.md">A2A Server</a></b></td><td>JSON-RPC 2.0 protocol, skills, streaming, task mgmt</td></tr>
<tr><td nowrap><b><a href="docs/frameworks/A2A-SERVER.md">A2A Server Guide</a></b></td><td>A2A agent card, tasks, skills, and streaming</td></tr>

View File

@@ -1,76 +0,0 @@
import { apiFetch } from "../api.mjs";
import { t } from "../i18n.mjs";
import { emit } from "../output.mjs";
const statusSchema = [
{ key: "feed", header: "Feed" },
{ key: "available", header: "Available" },
{ key: "version", header: "Version" },
{ key: "tier", header: "Tier" },
{ key: "fetchedAt", header: "Fetched" },
];
const syncSchema = [
{ key: "feed", header: "Feed" },
{ key: "status", header: "Status" },
{ key: "version", header: "Version" },
{ key: "reason", header: "Reason" },
];
function exitCodeFor(response) {
return Number.isInteger(response.exitCode) ? response.exitCode : response.status === 401 ? 4 : 1;
}
export async function runRadarStatusCommand(opts = {}) {
const response = await apiFetch("/api/radar/status", { acceptNotOk: true });
if (!response.ok) return exitCodeFor(response);
const data = await response.json();
if (opts.output === "json") {
emit(data, opts);
return 0;
}
const rows = Object.entries(data.feeds ?? {}).map(([feed, value]) => ({
feed,
...(value && typeof value === "object" ? value : { available: false }),
}));
emit(rows, opts, statusSchema);
return 0;
}
export async function runRadarSyncCommand(opts = {}) {
const response = await apiFetch("/api/radar/sync-all", {
method: "POST",
body: {},
acceptNotOk: true,
});
if (!response.ok) return exitCodeFor(response);
const data = await response.json();
if (opts.output === "json") {
emit(data, opts);
return 0;
}
const rows = Object.entries(data).map(([feed, value]) => ({
feed,
...(value && typeof value === "object" ? value : { status: "error" }),
}));
emit(rows, opts, syncSchema);
return 0;
}
export function registerRadar(program) {
const radar = program.command("radar").description(t("radar.description"));
radar
.command("status")
.description(t("radar.status"))
.action(async (_opts, command) => {
const code = await runRadarStatusCommand(command.optsWithGlobals());
if (code !== 0) process.exitCode = code;
});
radar
.command("sync")
.description(t("radar.sync"))
.action(async (_opts, command) => {
const code = await runRadarSyncCommand(command.optsWithGlobals());
if (code !== 0) process.exitCode = code;
});
}

View File

@@ -78,7 +78,6 @@ import { registerTokens } from "./tokens.mjs";
import { registerConfigure } from "./configure.mjs";
import { registerApiCommands } from "../api-commands/registry.mjs";
import { registerPlugin } from "./plugin.mjs";
import { registerRadar } from "./radar.mjs";
export function registerCommands(program) {
registerMemory(program);
@@ -162,5 +161,4 @@ export function registerCommands(program) {
registerConfigure(program);
registerApiCommands(program);
registerPlugin(program);
registerRadar(program);
}

View File

@@ -921,11 +921,6 @@
"model": "Filter by model"
}
},
"radar": {
"description": "Inspect and synchronize the local Radar catalog feeds",
"status": "Show local Radar settings and feed cache status",
"sync": "Synchronize catalog, referrals, offers, and Intel through the local server"
},
"resilience": {
"description": "Inspect and manage resilience mechanisms",
"status": {

View File

@@ -918,11 +918,6 @@
"model": "Filtrar por model"
}
},
"radar": {
"description": "Inspecionar e sincronizar os feeds locais do catálogo Radar",
"status": "Mostrar configurações locais e estado dos caches do Radar",
"sync": "Sincronizar catálogo, indicações, ofertas e Intel pelo servidor local"
},
"resilience": {
"description": "Inspecionar e gerenciar mecanismos de resiliência",
"status": {

View File

@@ -1 +0,0 @@
- **feat(radar):** Persist local model display-name/enabled overrides and hide/restore tombstones, with authenticated catalog controls and feed safety precedence ([#9830](https://github.com/diegosouzapw/OmniRoute/pull/9830))

View File

@@ -1 +0,0 @@
- **feat(radar):** add curated-family combo suggestions, a guided combo page, and the read-only Radar MCP catalog tool ([#9836](https://github.com/diegosouzapw/OmniRoute/pull/9836))

View File

@@ -1 +0,0 @@
- **feat(radar):** add a signed live offers feed and supporter offers dashboard ([#9912](https://github.com/diegosouzapw/OmniRoute/pull/9912))

View File

@@ -1 +0,0 @@
- **feat(radar):** add signed Intel insights, supporter recognition, and local Radar CLI commands ([#9923](https://github.com/diegosouzapw/OmniRoute/pull/9923))

View File

@@ -1 +0,0 @@
- **feat(radar):** add a localized public news feed and dismissible dashboard launch banner, with the Radar announcement staged inactive for a separately authorized launch ([#9926](https://github.com/diegosouzapw/OmniRoute/pull/9926))

View File

@@ -0,0 +1 @@
- fix(dashboard): remap unified Kimi Code card API-key save to the admitted `kimi-coding-apikey` connection id, fixing 400 "Invalid provider" on Save (#10096)

View File

@@ -1 +0,0 @@
- fix(ci): make `Build (advisory)` produce a signal again — pinned to a hosted runner with the swap/heap provisioning `Fast Production Build` proves sufficient, and scoped to fork PRs, which are the only ones `build.yml` cannot cover (72 of the last 100 PRs into `release/**`)

View File

@@ -27,7 +27,6 @@
"providers-bailian-coding-plan.spec.ts": 240,
"providers-management.spec.ts": 324,
"proxy-registry.smoke.spec.ts": 218,
"radar-guided-setup.spec.ts": 177,
"resilience-plan-alignment.spec.ts": 382,
"responsive.spec.ts": 21,
"search-tools-studio.spec.ts": 133,
@@ -37,4 +36,4 @@
"traffic-inspector.spec.ts": 212,
"translator-friendly.spec.ts": 115,
"visual-resilience-smoke.spec.ts": 20
}
}

View File

@@ -205,10 +205,10 @@ Runs on pull requests only.
Runs after `build`. Blocks merge on failure.
| Suite | Validates | Blocking |
| ---------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| `test:vitest` | MCP server (109 tools), autoCombo, cache — vitest runner | Yes |
| `test:vitest:ui` | UI component tests — vitest runner | **Blocking** — pre-existing failures are explicitly excluded in `vitest.config.ts`; new failures fail the job |
| Suite | Validates | Blocking |
| ---------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| `test:vitest` | MCP server (105 tools), autoCombo, cache — vitest runner | Yes |
| `test:vitest:ui` | UI component tests — vitest runner | **Blocking** — pre-existing failures are explicitly excluded in `vitest.config.ts`; new failures fail the job |
### Nightly workflows (scheduled, advisory)

View File

@@ -102,7 +102,7 @@ OmniRoute/
| **.gitleaks.toml** | gitleaks secret-scan ruleset |
| **.zizmor.yml** | zizmor GitHub-Actions security-lint config |
| **socket.yml** | Socket.dev supply-chain config |
| **news.json** | Localized v2 announcement feed; Radar launch item ships inactive |
| **news.json** | In-app release-notes feed (read by `src/shared/utils/releaseNotes.ts`) |
| **flake.nix** / **flake.lock** | Nix dev-shell definition + lock |
| **.env** | Local secrets (gitignored — generated from `.env.example`) |
@@ -182,7 +182,7 @@ src/
| `compliance/` | Audit log + provider audit — see `docs/security/COMPLIANCE.md` |
| `compression/` | Compression engine glue (engines live in `open-sse/services/compression/`) |
| `config/` | Runtime config helpers |
| `db/` | 95+ domain DB modules + 148 migrations (always go through here for SQLite) |
| `db/` | 95+ domain DB modules + 144 migrations (always go through here for SQLite) |
| `quota/` | Quota Sharing Engine: `dimensions.ts` (types/Zod), `types.ts` (QuotaStore interface), `sqliteQuotaStore.ts`, `redisQuotaStore.ts`, `storeFactory.ts`, `fairShare.ts`, `burnRate.ts`, `planResolver.ts`, `planRegistry.ts`, `saturationSignals.ts`, `enforce.ts`, `spendRecorder.ts` — see `docs/routing/QUOTA_SHARE.md` |
| `radar/` | Radar free-model catalog client: `feedSchema.ts`, `pinnedKeys.ts`, `verify.ts`, `sync.ts`, `applyFeed.ts`, `index.ts` (`getRadarCatalog()`) — see `docs/frameworks/RADAR.md` |
| `display/` | UI formatting helpers (cost, latency, etc.) |
@@ -196,7 +196,7 @@ src/
| `memory/vectorStore.ts` | sqlite-vec v0.1.9 wrapper — KNN brute-force + hybrid RRF (FTS5 + vector, k=60). Lazy-init, degrades gracefully when sqlite-vec unavailable. (plan 21) |
| `memory/reindex.ts` | `runReindexBatch()` — processes memories with `needs_reindex=1` in background; called by `POST /api/memory/reindex` and lazy-backfill path. (plan 21) |
| `monitoring/` | Health checks, metrics emission |
| `oauth/` | OAuth/import flows for 22 provider modules (agy, antigravity, claude, cline, codebuddy-cn, codex, cursor, devin-desktop, ghe-copilot, github, gitlab-duo, grok-cli-oauth, grok-cli, kilocode, kimi-coding, kiro, qoder, raycast, trae, xai-oauth, zed-hosted, zed) |
| `oauth/` | OAuth/import flows for 22 provider modules (agy, antigravity, claude, cline, codebuddy-cn, codex, cursor, devin-desktop, ghe-copilot, github, gitlab-duo, grok-cli-oauth, grok-cli, kilocode, kimi-coding, kiro, qoder, raycast, trae, xai-oauth, zed-hosted, zed) |
| `plugins/` | Plugin registry |
| `promptCache/` | Anthropic-style prompt cache breakpoints |
| `skills/` | Skills framework (built-in + marketplace + SkillsSH) — see `docs/frameworks/SKILLS.md` |
@@ -209,7 +209,7 @@ src/
| `cacheLayer.ts`, `idempotencyLayer.ts` | Request caching + idempotency |
| (~30 more top-level files) | Specialized helpers (logEnv, modelsDevSync, piiSanitizer, etc.) |
### `src/db/` — Database (117 modules + 148 migrations)
### `src/db/` — Database (117 modules + 144 migrations)
| Subdir | Purpose |
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -256,7 +256,6 @@ src/
| `utils/circuitBreaker.ts` | Provider circuit breaker (see `docs/architecture/RESILIENCE_GUIDE.md`) |
| `utils/apiAuth.ts` | API key validation, scope checking |
| `utils/fetchTimeout.ts` | Timeout/abort wrappers for upstream fetch |
| `utils/releaseNotes.ts` | Closed v2/legacy announcement parser, localization and ID dismissal |
---
@@ -271,7 +270,7 @@ open-sse/
├── translator/ # Format converters (9 request, 9 response, 9 helpers)
├── transformer/ # Responses API ↔ Chat Completions (TransformStream)
├── services/ # ~80+ service modules (combo, accountFallback, autoCombo, reasoningCache, claude code/chatgpt stealth, modelDeprecation, taskAwareRouter, workflowFSM, etc.)
├── mcp-server/ # MCP server (109 tools, 3 transports, 33 scopes)
├── mcp-server/ # MCP server (105 tools, 3 transports, 31 scopes)
├── config/ # Provider/model registries, header config, model aliases
├── utils/ # TLS client, proxy fetch/dispatcher, network helpers
├── index.ts # Workspace entry
@@ -407,7 +406,7 @@ open-sse/
| Doc | Purpose |
| -------------------------- | ------------------------------------------------------------------- |
| `MCP-SERVER.md` | MCP server: 109 tools, 3 transports, 33 scopes, REST endpoints |
| `MCP-SERVER.md` | MCP server: 105 tools, 3 transports, 31 scopes, REST endpoints |
| `A2A-SERVER.md` | A2A v0.3: JSON-RPC, 6 skills, REST helpers, agent card |
| `AGENT_PROTOCOLS_GUIDE.md` | Unified guide: A2A vs ACP vs Cloud Agents |
| `CLOUD_AGENT.md` | Codex Cloud / Devin / Jules orchestration |

View File

@@ -330,75 +330,32 @@ excludeMarkers, defaultRetryAfterMs}`), matched via `applyStatusRestatement()`.
Permanent errors (agentrouter's `无权访问模型` — no access to this model) are
NEVER restated: `excludeMarkers` vetoes the rule even when `textMarkers` hit,
so the error keeps its original status and nothing retries it forever. The
matching provider classification rule
(`agentrouter-model-access-denied` in `open-sse/config/providerErrorRules.ts`:
`reason: "auth_error"`, `scope: "model"`, a `6h` declared base cooldown) is
consulted by `checkFallbackError` (`open-sse/services/accountFallback.ts`)
*before* the generic apikey-category `FORBIDDEN` early-return, gated on
`honorsRuleLockScope(provider)` (#10334 — currently agentrouter-exclusive via
the `HONORS_RULE_LOCK_SCOPE_PROVIDERS` allowlist in
`providerErrorRules.ts`). The rule's declared 6h cooldown flows through as
`fallbackResult.baseCooldownMs`, but it still feeds the pre-existing
per-model-quota lockout path (`lockModelIfPerModelQuota()` /
`recordModelLockoutFailure()`, unchanged by #10334 except for the cooldown
source): it is clamped down to the operator's `mlSettings.maxCooldownMs`
(default `1_800_000ms` / 30min), like every other model lockout, and the
*persisted lockout reason* stays the pre-existing hardcoded `"forbidden"`,
not the rule's `"auth_error"` — only the cooldown duration is honored
end-to-end, not the reason string. The connection itself stays active;
sibling models on the same connection are unaffected.
so the error keeps its original status and nothing retries it forever. A
separate provider classification rule
(`agentrouter-model-access-denied` in `open-sse/config/providerErrorRules.ts`)
declares an `auth_error`/scope-`model` match for this text, but it does not
fire on the live production path today: the rule only matches `status ===
403`, and `checkFallbackError`'s apikey-category `FORBIDDEN` branch
(`open-sse/services/accountFallback.ts`) returns early for a plain 403
*before* the provider-rule lookup ever runs. In practice a `无权访问模型` 403
is handled the same way as the base apikey-provider 403 path (see Connection
Cooldown, §2), not as a 6h model lockout. The rule still exists as a
declarative classification consumable by future callers of `classifyError`
with context — wiring it into the production `checkFallbackError` path is
tracked as a follow-up, not yet done.
Restated quota errors (`额度不足`) reach a provider rule in production
(`agentrouter-user-quota-exhausted`: `reason: "quota_exhausted"`, `scope:
"connection"`, no declared cooldown of its own — the persistence layer's
scaled backoff default applies). Since #10334, `scope` on
`ProviderErrorRuleMatch` IS consumed end-to-end, but **only** for providers in
the `HONORS_RULE_LOCK_SCOPE_PROVIDERS` allowlist (`providerErrorRules.ts`
today only `"agentrouter"`, gated via `honorsRuleLockScope()`). For every
other provider `scope` remains informational, exactly as before #10334.
`checkFallbackError` surfaces the matched rule's scope as
`fallbackResult.ruleScope`; `isAgentrouterConnectionQuotaScope()`
(`src/sse/services/auth.ts`) is the shared guard that confirms a
`ruleScope` is genuinely safe to honor as a connection-wide, self-recovering
signal (scope `"connection"`, reason `quota_exhausted`, never `permanent`,
never `creditsExhausted` — a defense against a future rule pairing scope
`"connection"` with a permanent account state). Two consumers call it:
- **Persistence** (`markAccountUnavailable()`, `src/sse/services/auth.ts`):
instead of falling into the passthrough-provider **per-model** lockout
branch (agentrouter is `passthroughModels: true``hasPerModelQuota()`
returns `true`), it applies a **temporary connection cooldown**
`testStatus: "unavailable"` + `rateLimitedUntil`, never a terminal status
(`credits_exhausted`/`banned`/`expired`) — so the connection self-recovers
once the cooldown lapses instead of requiring a manual credential reset.
Skipped for connections with `disableCooling: true` (#2997): that opt-out
falls through to the per-model lockout instead (a documented trade-off —
see the code comment above the branch).
- **Same-request combo routing** (`applyComboTargetExhaustion()`,
`open-sse/services/combo/targetExhaustion.ts`): the same guard marks the
connection into the in-memory `exhaustedConnections` set, keyed
`${provider}:${connectionId}`. This only skips a remaining SAME-REQUEST
target that *itself already carries that exact `connectionId`* on its own
target object (`getExhaustedTargetSkipReason()`,
`open-sse/services/combo/comboPredicates.ts`, `if (provider &&
connectionId)` before the `exhaustedConnections` lookup) — a plain
model-list combo, where sibling targets carry no pinned `connectionId` of
their own and one is only resolved per-dispatch from the response's
`X-OmniRoute-Selected-Connection-Id` header, never hits that key match. For
that common case, the real protection against a remaining leg reusing the
just-exhausted account is NOT this Set — it is the persistence layer above
(the connection's `rateLimitedUntil` is now in the future) combined with
this same guard suppressing `transientRateLimitedProviders` for the
failure (see "Two-stage design" and the code comment on the
`isAgentrouterConnectionQuotaScope` branch in `targetExhaustion.ts`): with
that Set left unmarked, `combo.ts`'s `allowRateLimitedConnection` force-allow
(`open-sse/services/combo.ts:1005-1013`, `:2734-2738`) does NOT kick in for
the provider's remaining legs, so credential selection's `rateLimitedUntil`
filter (`src/sse/services/auth.ts:1238`) is honored normally and a
remaining leg either picks a different, still-eligible agentrouter
connection or fails with no credentials available — it does not force its
way back onto the connection this branch just cooled down.
Restated quota errors (`额度不足`) do reach a provider rule in production
(`agentrouter-user-quota-exhausted`, scope `"connection"`), but `scope` on
`ProviderErrorRuleMatch` is currently informational — the persistence path
(`checkFallbackError``combo.ts`) only consumes `reason` and `cooldownMs`,
never `scope`. What actually happens for agentrouter (`passthroughModels:
true``hasPerModelQuota()` returns `true`) is a **per-model** lockout via
`recordModelLockoutFailure()`: the connection itself is never cooled down for
this error (`combo.ts` skips `recordProviderCooldown` for 429 when
`hasPerModelQuota` is true), so other models on the same account keep being
tried — each one burns one call and its own lockout before combo routing
moves on. Honoring `scope` end-to-end (so a `"connection"` match actually
locks the connection) is tracked as a follow-up.
### Two-stage design: status restatement, then classification
@@ -423,15 +380,6 @@ allowlisted providers, the structured error otherwise. Adding a provider to
that the default path for every provider not on the list stays
byte-for-byte unchanged.
A rule's `scope` (`model` / `provider` / `connection`) is a separate opt-in
from `FULL_TEXT_RULE_PROVIDERS`: `checkFallbackError` only surfaces it as
`fallbackResult.ruleScope`, and downstream consumers only honor it as
anything other than an informational label, for providers in the
`HONORS_RULE_LOCK_SCOPE_PROVIDERS` allowlist in the same file (`gated via
honorsRuleLockScope()` — today only `"agentrouter"`). See "Restated quota
errors" above for what a `scope: "connection"` match actually does once a
provider is on that allowlist.
### Adding a new quota-misstating gateway
1. Register one rule array in `statusRestatementRegistry`
@@ -447,15 +395,7 @@ provider is on that allowlist.
`checkFallbackError` only ever hands the rule the structured
`{code, type}` error and a body-text rule will never match live traffic.
Rules that match purely on `status`/`headers` (like Opencode's or
Minimax's) do not need this opt-in. Separately, if the rule declares
`scope: "connection"` and the intent is an actual connection-wide cooldown
plus same-request combo skip (not just an informational label), add the
provider id to `HONORS_RULE_LOCK_SCOPE_PROVIDERS` in the same file — this
is what gates `isAgentrouterConnectionQuotaScope()`-style consumption in
`markAccountUnavailable()` (`src/sse/services/auth.ts`) and
`applyComboTargetExhaustion()`
(`open-sse/services/combo/targetExhaustion.ts`); without it, `scope`
still flows through `fallbackResult.ruleScope` but nothing acts on it.
Minimax's) do not need this opt-in.
3. Add unit tests mirroring `tests/unit/upstream-status-restatement.test.ts`
and `tests/unit/agentrouter-error-rules.test.ts` (including the
not-permanent / not-creditsExhausted guards, and — if the provider needs

View File

@@ -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: 339 providers, 90+ free providers built-in, 19 routing strategies, 12-engine token compression, a built-in MCP server with 109 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: 339 providers, 90+ free providers built-in, 19 routing strategies, 12-engine token compression, a built-in MCP server with 105 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>
@@ -57,7 +57,7 @@
</g>
<g opacity="0"><animate attributeName="opacity" values="0;1" dur="0.4s" begin="0.51s" fill="freeze"/>
<text x="44" y="364" font-size="14.5" fill="#c9d1d9">Built-in MCP server (own tools)</text>
<text x="440" y="364" text-anchor="middle" font-family="Inter, 'Segoe UI', Arial, Helvetica, system-ui, sans-serif" font-size="15" font-weight="800" fill="#7ee787">109</text>
<text x="440" y="364" text-anchor="middle" font-family="Inter, 'Segoe UI', Arial, Helvetica, system-ui, sans-serif" font-size="15" font-weight="800" fill="#7ee787">105</text>
<use href="#no" x="604" y="359"/>
<use href="#mid" x="760" y="359"/>
<use href="#no" x="916" y="359"/>

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -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, 339 providers — never stop building, OmniRoute picks the cheapest one that works. Six pillars. Never hit limits: auto-fallback across 339 providers in milliseconds, quota out means the next provider takes over with zero downtime. Save up to 95 percent of tokens: RTK plus Caveman stacked compression cuts 15 to 95 percent of eligible tokens, about 89 percent average on tool-heavy sessions. Zero dollars to start: 90+ providers with a free tier, 40+ free forever — Qoder, Pollinations, Cloudflare, SiliconFlow — no card needed. Every tool works: 33 coding agents including Claude Code, Codex, Cursor, Cline, Copilot and Antigravity through one config. One endpoint: OpenAI, Claude, Gemini and Responses API translation — point any tool at /v1 and it just works. Production-grade: circuit breakers, TLS stealth, MCP with 109 tools, A2A, memory, guardrails, evals — 25,000+ tests.">
<svg viewBox="0 0 1200 540" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="The OmniRoute promise: one endpoint, 339 providers — never stop building, OmniRoute picks the cheapest one that works. Six pillars. Never hit limits: auto-fallback across 339 providers in milliseconds, quota out means the next provider takes over with zero downtime. Save up to 95 percent of tokens: RTK plus Caveman stacked compression cuts 15 to 95 percent of eligible tokens, about 89 percent average on tool-heavy sessions. Zero dollars to start: 90+ providers with a free tier, 40+ free forever — Qoder, Pollinations, Cloudflare, SiliconFlow — no card needed. Every tool works: 33 coding agents including Claude Code, Codex, Cursor, Cline, Copilot and Antigravity through one config. One endpoint: OpenAI, Claude, Gemini and Responses API translation — point any tool at /v1 and it just works. Production-grade: circuit breakers, TLS stealth, MCP with 105 tools, A2A, memory, guardrails, evals — 25,000+ tests.">
<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">
@@ -125,7 +125,7 @@
<path d="M 7,11 L 10,14 L 15.4,8.2"/>
</g>
<text x="862" y="354" font-size="18" font-weight="800" fill="#7ee787">Production-grade</text>
<text x="826" y="388" font-size="13.5" fill="#a1a1aa">Circuit breakers, TLS stealth, MCP (109</text>
<text x="826" y="388" font-size="13.5" fill="#a1a1aa">Circuit breakers, TLS stealth, MCP (105</text>
<text x="826" y="410" font-size="13.5" fill="#a1a1aa">tools), A2A, memory, guardrails, evals —</text>
<text x="826" y="432" font-size="13.5" fill="#a1a1aa">25,000+ tests.</text>
</g>

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -1,14 +1,14 @@
---
title: "OmniRoute MCP Server Documentation"
version: 3.8.50
lastUpdated: 2026-08-08
version: 3.8.40
lastUpdated: 2026-06-28
---
# OmniRoute MCP Server Documentation
> Model Context Protocol server with 109 tools across routing, cache, compression, memory, skills, proxy, pool, Radar, and context source operations.
> Model Context Protocol server with 105 tools across routing, cache, compression, memory, skills, proxy, pool, and context source operations.
>
> Source of truth: `open-sse/mcp-server/server.ts` computes **109 unique tools** with `countUniqueMcpTools()`: 44 canonical definitions (including the six CCR lifecycle tools, the agent-skills trio, and `omniroute_radar_catalog`), plus memory (3), skills (4), GitHub skills (3), pool (6), gamification (8), plugins (8), Notion (6), Obsidian (22), local corpus (3), and two RTK-only compression tools.
> Source of truth: `open-sse/mcp-server/server.ts` computes **105 unique tools** with `countUniqueMcpTools()`: 42 canonical definitions (including the six CCR lifecycle tools and the agent-skills trio), plus memory (3), skills (4), GitHub skills (3), pool (6), gamification (8), plugins (8), Notion (6), Obsidian (22), and two RTK-only compression tools.
## Installation
@@ -64,7 +64,7 @@ Cursor, Cline, and compatible MCP client setup.
---
## Essential Tools (13) — Phase 1
## Essential Tools (8) — Phase 1
| Tool | Scopes | Description |
| :------------------------------ | :-------------------- | :------------------------------------------------------------ |
@@ -72,15 +72,16 @@ Cursor, Cline, and compatible MCP client setup.
| `omniroute_list_combos` | `read:combos` | All configured combos with strategies (optional metrics) |
| `omniroute_get_combo_metrics` | `read:combos` | Performance metrics for a specific combo |
| `omniroute_switch_combo` | `write:combos` | Activate or deactivate a combo |
| `omniroute_create_combo` | `write:combos` | Create a validated combo through the existing combo API |
| `omniroute_check_quota` | `read:quota` | Quota used/total, percent remaining, reset time, token health |
| `omniroute_route_request` | `execute:completions` | Send a chat completion through OmniRoute routing |
| `omniroute_cost_report` | `read:usage` | Cost report by period (session/day/week/month) |
| `omniroute_list_models_catalog` | `read:models` | Full model catalog with capabilities, status, pricing |
| `omniroute_radar_catalog` | `read:radar` | Local signed Radar catalog; optional provider/family filters |
| `omniroute_tool_search` | `read:tools` | Discover tools from the registered MCP catalog |
| `omniroute_web_search` | `execute:search` | Web search through the configured search providers |
| `omniroute_web_fetch` | `execute:search` | Fetch web content through the configured fetch providers |
## Phase 1 — Search
| Tool | Scopes | Description |
| :--------------------- | :--------------- | :--------------------------------------------------------------------------------------------------------------------------------- |
| `omniroute_web_search` | `execute:search` | Web search through OmniRoute search gateway (Serper/Brave/Perplexity/Exa/Tavily/Google PSE/Linkup/SearchAPI/SearXNG) with failover |
## Advanced Tools (11) — Phase 2
@@ -226,7 +227,7 @@ See [AGENT-SKILLS.md](./AGENT-SKILLS.md) for the full catalog and how external a
## Related Frameworks (v3.8.0)
The MCP tool inventory above (109 unique tools, computed by `countUniqueMcpTools()`) is intentionally
computed = 105, computed by `countUniqueMcpTools()`) is intentionally
scoped to runtime routing/cache/compression/memory/skills/proxy/context-source operations. Two adjacent
frameworks ship alongside the MCP server in v3.8.0 and are documented separately:
@@ -368,7 +369,7 @@ MCP tool, prompt, and resource registries can compress descriptions at registrat
Description compression shrinks each tool's metadata; **tool-cardinality reduction** goes one step further by reducing _how many_ tools are announced at all. Advertising fewer tools in the `tools/list` manifest cuts the per-request token cost the client's model pays for the tool catalog ("layer 5" compression). The implementation is a pure, stateless filter in `open-sse/mcp-server/toolCardinality.ts` (`reduceToolManifest`), wired into the registration loop in `createMcpServer()` (`open-sse/mcp-server/server.ts`).
**Opt-in, off by default.** The filter only runs when at least one of two environment variables is set; with neither set, all 109 tools are announced unchanged.
**Opt-in, off by default.** The filter only runs when at least one of two environment variables is set; with neither set, all 105 tools are announced unchanged.
| Variable | Mode |
| :--------------- | :-------------------------------------------------------------------------------------- |

View File

@@ -1,13 +1,13 @@
---
title: "Radar Free-Model Catalog"
version: 3.8.50
lastUpdated: 2026-08-13
lastUpdated: 2026-08-08
---
# Radar Free-Model Catalog
> **Source of truth:** `src/lib/radar/`, `src/lib/db/radar.ts`, `src/app/api/radar/`
> **Last updated:** 2026-08-13 — v3.8.50
> **Last updated:** 2026-08-08 — v3.8.50
Radar is an **optional add-on** that overlays a signed, freshly-curated free-model
catalog on top of the release baseline (`FREE_MODEL_BUDGETS` in
@@ -15,12 +15,11 @@ catalog on top of the release baseline (`FREE_MODEL_BUDGETS` in
faster than release cadence — providers add, shrink, or discontinue free quotas between
releases, and the baseline catalog can only be refreshed when a new version ships.
**Nothing that is free today stops being free because of the remote feed.** Radar never
paywalls a baseline entry; it only refreshes limits/status fields at read time and can
layer in newly-discovered free models between releases. An operator can still hide a
model locally, and can restore it from the same dashboard. The baseline catalog itself
is never mutated on disk — see
[Read-time overlay merge rules](#read-time-overlay-merge-rules) below.
**Nothing that is free today stops being free.** Radar never removes or paywalls a
baseline entry; it only refreshes limits/status fields at read time and can layer in
newly-discovered free models between releases. The baseline catalog itself is never
mutated on disk — see [Read-time overlay merge rules](#read-time-overlay-merge-rules)
below.
---
@@ -30,39 +29,14 @@ The following status distinguishes what this OSS release implements from later R
workstreams. It is a code-level status, not a promise that a particular hosted deployment
or external integration is currently available.
| Area | Status in this release |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Signed catalog client | Implemented behind `RADAR_ENABLED`, with separate opt-in, Ed25519 verification, local encrypted settings/cache, persistent display/enabled overrides, reversible tombstones, scheduler, and dashboard. |
| Contributor activation | The dashboard links to the server-hosted GitHub claim flow and accepts an existing `omr_…` key. Contributor eligibility is resolved by the private service; the OSS client contains no GitHub token or issuance logic. |
| Supporter-key activation | Implemented. The raw key is validated, encrypted at rest, masked on reads, and sent only by server-side sync. Changing or clearing the key invalidates all four entitlement-sensitive feed caches. |
| Referral links | Implemented as a separately signed, hourly-refreshed feed. Fixed links are available to the community tier immediately; limited campaigns remain live-tier data. |
| Supporter offers | Implemented as a separate signed, live-only feed and dashboard page. The client revalidates the closed benefit schema, preserves the last good cache, filters expired entries, and labels partner offers explicitly. |
| Intel and supporter recognition | Implemented as a strict signed live-only feed with Radar-owned ELO, factual catalog freshness/trend, a verified local supporter badge, dashboard page, and local-only CLI status/sync commands. |
| Payments and transactional email | Not implemented in the OSS client. Purchase, donation, receipt review, recovery, and mail delivery belong to the private service; hosted availability still depends on its supervised deploy and provider configuration. |
| Research-agent workstream | Not part of this client release. Curated feed contents remain server-side data; no autonomous research agent runs in an OmniRoute installation. |
---
## Public announcement reader
The generic announcement reader is separate from the Radar feature flag. The dashboard Home and
Changelog viewer fetch the repository's public `news.json` through a plain `GET` to
`NEWS_JSON_URL` (`src/shared/utils/releaseNotes.ts`). They send no Radar setting, prompt, provider
configuration, usage record, or local dismissal state.
`news.json` uses the closed v2 schema implemented by `parseNewsPayload()`:
- `schemaVersion: 2` and a bounded `items[]` collection;
- stable, unique announcement `id` values;
- explicit `active` and ISO `publishedAt` fields;
- required English copy with optional localized copy;
- optional credential-free HTTPS links and an allowlisted icon;
- newest-active-first selection, locale fallback to English, and per-ID local dismissal.
The parser temporarily accepts the former singular `{ active, title, message, ... }` shape so
older forks can migrate without a broken Changelog view. Invalid feeds are inert. The Radar launch
entry ships with `active: false`; changing it to `true` is a separate post-merge, post-deploy
release action and does not change `RADAR_ENABLED` or the independent feed-sync opt-in.
| Area | Status in this release |
| -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Signed catalog client | Implemented behind `RADAR_ENABLED`, with separate opt-in, Ed25519 verification, local encrypted settings/cache, non-destructive overlay, scheduler, and dashboard. |
| Contributor activation | The dashboard links to the server-hosted GitHub claim flow and accepts an existing `omr_…` key. Contributor eligibility is resolved by the private service; the OSS client contains no GitHub token or issuance logic. |
| Supporter-key activation | Implemented. The raw key is validated, encrypted at rest, masked on reads, and sent only by the server-side sync. Changing or clearing the key invalidates both entitlement-sensitive feed caches. |
| Referral links | Implemented as a separately signed, hourly-refreshed feed. Fixed links are available to the community tier immediately; limited campaigns remain live-tier data. |
| Payments and transactional email | Not implemented in the OSS client. Purchase, donation, receipt review, and mail delivery belong to the private service and its later operational workstream. |
| Research-agent workstream | Not part of this client release. Curated feed contents remain server-side data; no autonomous research agent runs in an OmniRoute installation. |
---
@@ -74,16 +48,15 @@ Radar is gated end-to-end by the `RADAR_ENABLED` feature flag
**When the flag is off, the surface does not exist:**
- All `/api/radar/*` endpoints, including local model-state reads and writes,
- `GET /api/radar/catalog`, `POST /api/radar/sync`, `POST /api/radar/settings` all
return `404` before touching any Radar module.
- The dashboard screens (`/dashboard/radar`, `/dashboard/radar/setup`,
`/dashboard/radar/combos`, `/dashboard/radar/offers`, `/dashboard/radar/intel`) render
- The dashboard screens (`/dashboard/radar`, `/dashboard/radar/setup`) render
`notFound()`.
- `getRadarCatalog()` (`src/lib/radar/index.ts`) returns the untouched baseline —
same entry count, same values, every entry tagged `origin: "baseline"` — and never
reads the feed cache.
- No Radar network call is ever made; each sync module returns `{ status: "disabled" }`
before touching `fetch`.
- No network call is ever made; `syncRadar()` (`src/lib/radar/sync.ts`) returns
`{ status: "disabled" }` at step 1 without touching `fetch`.
This is a strict superset gate: flipping the flag on unlocks the _screens_, nothing
more. It does not upload data, does not start a background sync, and does not change
@@ -105,17 +78,14 @@ Opt-in false → { status: "opt_out" } — no network call
When both are on, the sync path is:
1. `GET <feed base URL>/v1/catalog/latest` with `x-omniroute-radar-schema: 2` and an optional
`Authorization: Bearer <supporter key>` header (see below). Servers default to the separately
signed v1 transition artifact when the schema header is absent, so older installed clients keep
receiving updates.
1. `GET <feed base URL>/v1/catalog/latest` with an optional `Authorization: Bearer
<supporter key>` header (see below).
2. Nothing about the request, the operator, or their traffic is uploaded — it is a
plain, unauthenticated-by-default GET. OmniRoute never posts usage data, provider
configuration, or model traffic to the feed service.
3. The response is verified, validated, and cached locally (see
[Security model](#security-model)). Radar has exactly four server-side network paths:
`syncRadar()` for the catalog, `syncRadarReferrals()` for referrals, and
`syncRadarOffers()` / `syncRadarIntel()` for supporter-only offers and Intel.
[Security model](#security-model)). Radar has exactly two server-side network paths:
`syncRadar()` for the catalog and `syncRadarReferrals()` for the standalone referrals feed.
The **supporter key** is an optional Bearer token (`radar_settings.supporter_key`)
that lets the feed service decide which tier to serve (see
@@ -125,7 +95,7 @@ that lets the feed service decide which tier to serve (see
helpers (`src/lib/db/encryption.ts`) used for provider credentials.
- Set via `POST /api/radar/settings` (`{ supporterKey: "omr_" + 40 hex chars }`) and
**never echoed back** — the response returns a masked form (`omr_****abcd`).
- Changing or clearing it atomically invalidates the catalog, referrals, offers, and Intel caches. The
- Changing or clearing it atomically invalidates both the catalog and referrals caches. The
next sync/read resolves the new entitlement server-side; saving a key does not itself make
a network request or consume a single-use activation key.
- Sent to the feed service as a Bearer token on the sync GET — nothing else about the
@@ -158,29 +128,6 @@ client component never reads `process.env` itself.
| `RADAR_CONTRIBUTOR_CLAIM_URL` | Overrides the contributor-claim URL (default `https://radar.omniroute.online/auth/github`). |
| `RADAR_SUPPORTER_PLANS_URL` | Overrides the supporter-plans URL (default `https://radar.omniroute.online/planos`). |
### Recovering a lost supporter key
The hosted service's recovery entry point is `https://radar.omniroute.online/recover`; it is also
linked from the plans page. Recovery remains entirely outside the OSS client because the local
installation never receives the purchaser/contributor e-mail and cannot reconstruct a raw key from
its encrypted settings.
1. Submit the e-mail associated with the key. The service returns the same accepted page whether a
recoverable license exists or not, so the form does not enumerate accounts.
2. If eligible, the delivery worker sends a short-lived, one-use link. Opening it immediately moves
the token into a transient encrypted `HttpOnly`/`Secure` cookie and redirects to the clean
`/recover` URL; the page contains no token, e-mail, old key, or replacement key.
3. Confirm the revocation. The private service revokes the prior key, creates the replacement with
the same plan/expiration, and queues it for e-mail in one transaction. The replacement is never
returned to the browser.
4. Paste the replacement into `/dashboard/radar`. The old key must now degrade to `community`; the
replacement must produce a verified `live` sync. Reopening the same recovery link must fail with
a generic invalid/expired response.
The hosted recovery route and mail worker can be present in code while still unavailable in a given
deployment. Do not call the flow production-ready until the server has been deployed, the delivery
provider has been configured with a controlled recipient, and the full one-use link has been tested.
Once a visitor has a key (`omr_` + 40 hex chars), the activation screen
(`src/app/(dashboard)/dashboard/radar/page.tsx`) has a paste-key input as the primary
path: pasting a key and submitting sends `POST /api/radar/settings`
@@ -194,57 +141,6 @@ paste a new one — the raw key is never redisplayed. The two claim/plans button
remain the way to _obtain_ a key in the first place; this input is where an operator
who already has one activates it.
### End-to-end activation and guided setup
The private feed service and this OSS client have a deliberately narrow boundary: the service
issues and validates the supporter key, while the local OmniRoute installation encrypts the key,
syncs signed artifacts server-side, and guides provider setup. The assisted validation order is:
1. Obtain a newly issued or recovered key from the contributor claim, plans/checkout, recovery
journey, or an authorized private server operator. Do not paste the raw key into logs,
screenshots, issue comments, or command-line arguments.
2. Enable the `RADAR_ENABLED` feature flag on the local OmniRoute installation. This exposes the UI
but remains network-inert until the separate opt-in is saved.
3. Open `/dashboard/radar`, paste the key, and activate. The browser sends one local
`POST /api/radar/settings` with `{ optIn: true, supporterKey }`; the key is encrypted locally and
the response contains only `omr_****<last4>`.
4. Let the activation screen run its catalog sync, or select **Sync now**. Confirm that the page
reports `live`, a feed version, and a fetch time. For an authenticated local diagnostic,
`GET /api/radar/status` reports opt-in/key presence and the four cache states without returning
the key. `POST /api/radar/sync-all` can refresh catalog, referrals, offers, and Intel explicitly.
5. Open `/dashboard/radar/setup?provider=<provider>`. Follow the provider-owned credential URL,
select **Add API key**, save through the real provider form, return to the guide, and run
**Test connection**. The guide uses the normal `/api/providers` and
`/api/providers/<connection-id>/test` routes; it does not create a parallel Radar credential.
6. Open `/dashboard/radar/combos` after at least two compatible provider connections are active.
Review the suggested family and create the combo through the existing combo API. Offers and
Intel remain separate live-only signed caches and can be checked on their dedicated Radar pages.
7. Reload `/dashboard/radar` and the setup page. The opt-in, masked-key state, verified cache, saved
provider connection, and test action must survive the reload. Capture evidence only after the
raw key and provider credential are no longer visible.
Saving a key is not itself proof of live entitlement. The proof is the combination of the private
service's `GET /v1/license/check` result, the OSS catalog's served `live` tier, a verified signed
cache, and the real provider connection/test flow. An invalid, expired, or revoked key safely
degrades the catalog to `community`; it must not be reported as a successful live-key validation.
### Private admin-panel link
`RADAR_ADMIN_URL` optionally adds **Radar Admin ↗** immediately after the user-facing
Radar item in the Costs sidebar section. It has deliberately no default: when the variable is
unset or invalid, the static sidebar, command palette, and sidebar-customization screen contain no
admin item and no private URL.
The value is resolved server-side and relayed through the management-authenticated
`GET /api/settings` response only to an authenticated dashboard session, or to the trusted
loopback owner during a local no-login bootstrap. CLI, internal-service, and manage-scope API-key
authentication do not receive it. The browser validates the response again before materializing
the external link, which opens with `noopener noreferrer`.
Use a credential-free HTTPS tunnel/tailnet URL. Plain HTTP is accepted only for a loopback SSH
forward such as `http://127.0.0.1:9351`; other schemes, embedded credentials, malformed URLs, and
remote HTTP destinations fail closed and leave navigation inert.
---
## Security model
@@ -375,54 +271,6 @@ Four rules, in order of precedence:
entry (`tombstones` set), the feed re-adding that `provider:modelId` in a later
version does not bring it back.
The editable fields and tombstones are persisted in
`radar_local_model_state` (migration `153_radar_local_model_state.sql`). The public DB
adapter (`src/lib/db/radar.ts`) converts those rows into the `localOverrides` map and
`tombstones` set used by `applyFeed()`; production `getRadarCatalog()` loads that state
after the flag, cache, and schema gates pass. Only `displayName` and `enabled` are
operator-editable. Provider/model identity, feed provenance, quota, capabilities, ToS,
and setup data cannot be written through this surface.
The dashboard exposes four local actions:
- **Edit** changes the local display name and enabled state.
- **Reset local changes** clears both editable fields without changing a tombstone.
- **Hide** creates a tombstone, so later feed updates cannot recreate the row.
- **Restore** removes the tombstone; any separately-saved override remains in effect.
A feed `enabled: false` remains the safety exception: it wins over a stale local
`enabled: true`, keeps the merged entry disabled, and records `disabledBy: "radar"`.
Catalog publications use `schemaVersion: 2`. `contextWindow` and each of `tools`, `vision`, and
`thinking` are independently `number | null` / `boolean | null`: `null` means unknown, while
`false` means a D16-confirmed official provider source explicitly says the capability is absent.
Internal OmniRoute registry/model-spec flags are never promoted directly to feed facts. The client
still accepts v1 snapshots; because the old builder used `false` as an absence placeholder, v1 `false` is
normalized to unknown while v1 `true` remains factual. Unknown schema versions fail closed and the
last valid cache remains available. Every v2 model with a non-null context/capability must carry a
credential-free HTTPS `metadataEvidenceUrls[]`; otherwise schema validation fails and the cache is
not replaced. The catalog table renders all three states as ``, ``, and `?`.
### Guided combos and MCP access
Confirmed `familyId` values survive the read-time overlay and drive the pure
`buildRadarComboSuggestions()` module (`src/lib/radar/comboSuggestions.ts`). A family is suggested
only when at least two distinct providers have active connections and expose the exact curated model
ID. Disabled models, inactive providers, missing model IDs, singleton families, and ambiguous
alias/prefix matches fail closed. Suggestions use the existing `priority` strategy, ordering the
largest recurring monthly budget first; the UI creates them only through `POST /api/combos`.
The guided UI lives at `/dashboard/radar/combos`. It reads only the local
`GET /api/radar/catalog` and `GET /api/combos/builder/options` endpoints. It never triggers Radar sync,
reads provider credentials, or writes directly to the combo database.
MCP clients can read the same local projection with `omniroute_radar_catalog` (`read:radar`). The
optional `provider`, `familyId`, and `enabledOnly` filters are evaluated after one local
`GET /api/radar/catalog` read. Its closed output includes catalog metadata plus provider/model,
display name, `familyId`, quota, capabilities, enabled state, origin, and `disabledBy`; setup URLs,
steps, connections, e-mail addresses, keys, and referral data are never returned. This tool is
read-only and never invokes `/api/radar/sync`.
### Provenance markers
Every merged entry carries an `origin` field the UI renders as a badge:
@@ -436,41 +284,30 @@ Every merged entry carries an `origin` field the UI renders as a badge:
## Local surfaces — never a feed proxy
The local Radar route families below back the UI under `src/app/api/radar/`:
Five local routes back the UI, all under `src/app/api/radar/`:
| Route | Method | Purpose |
| ------------------------------ | ------ | --------------------------------------------------------------------------------------------------------------------- |
| `/api/radar/catalog` | GET | Returns the merged catalog (`getRadarCatalog()`) from the local cache. |
| `/api/radar/sync` | POST | Triggers `syncRadar()` server-side; returns the resulting status. |
| `/api/radar/settings` | GET | Returns `{ optIn, hasSupporterKey, supporterKeyMasked }` — never the raw key. |
| `/api/radar/settings` | POST | Sets opt-in and/or the (encrypted) supporter key. |
| `/api/radar/referrals` | GET | Returns `{ fixed, campaigns, tier }` from the local cache — see [Referral links](#referral-links-free-credits) below. |
| `/api/radar/offers` | GET | Returns active offers from the verified local live cache; never returns the supporter key. |
| `/api/radar/offers/sync` | POST | Triggers the server-side, live-key-only `syncRadarOffers()` pipeline. |
| `/api/radar/intel` | GET | Returns verified local live Intel plus a supporter-recognition boolean; never an identity or key. |
| `/api/radar/intel/sync` | POST | Triggers the server-side, live-key-only `syncRadarIntel()` pipeline. |
| `/api/radar/status` | GET | Returns read-only local settings/cache status for catalog, referrals, offers, and Intel, without secrets. |
| `/api/radar/sync-all` | POST | Runs all four server-side sync modules and returns a separate status for each feed. |
| `/api/radar/local-model-state` | GET | Lists persisted overrides and tombstones for edit/restore controls. |
| `/api/radar/local-model-state` | PATCH | Sets or clears the validated `displayName`/`enabled` override fields. |
| `/api/radar/local-model-state` | PUT | Creates or removes a tombstone with `{ provider, modelId, tombstoned }`. |
| `/api/radar/local-model-state` | DELETE | Clears editable override fields while preserving any tombstone. |
| Route | Method | Purpose |
| ---------------------- | ------ | --------------------------------------------------------------------------------------------------------------------- |
| `/api/radar/catalog` | GET | Returns the merged catalog (`getRadarCatalog()`) from the local cache. |
| `/api/radar/sync` | POST | Triggers `syncRadar()` server-side; returns the resulting status. |
| `/api/radar/settings` | GET | Returns `{ optIn, hasSupporterKey, supporterKeyMasked }` — never the raw key. |
| `/api/radar/settings` | POST | Sets opt-in and/or the (encrypted) supporter key. |
| `/api/radar/referrals` | GET | Returns `{ fixed, campaigns, tier }` from the local cache — see [Referral links](#referral-links-free-credits) below. |
**Hard rule: these routes never proxy the feed service.** The browser only ever talks
to the local OmniRoute server. The four modules that touch the Radar service are
`src/lib/radar/sync.ts` (catalog), `src/lib/radar/referralsSync.ts` (referrals), and
`src/lib/radar/offersSync.ts` (offers) plus `src/lib/radar/intelSync.ts` (Intel); all run
server-side, never client-side. This keeps
the feed URL and any supporter key out of client-facing network traffic entirely.
to the local OmniRoute server. The two modules that touch the Radar service are
`src/lib/radar/sync.ts` (catalog) and `src/lib/radar/referralsSync.ts` (referrals); both
always run server-side, never client-side. This keeps the feed URL and any supporter key
out of client-facing network traffic entirely.
All Radar endpoints return `404` when `RADAR_ENABLED` is off (see
All five routes return `404` when `RADAR_ENABLED` is off (see
[Flag](#flag-radar_enabled-default-off) above), and route error responses through
`buildErrorBody()`/`sanitizeErrorMessage()` per the repo-wide error-sanitization rule
(`docs/security/ERROR_SANITIZATION.md`).
### Authentication
All Radar endpoints require authentication via `isAuthenticated()`
All five routes require authentication via `isAuthenticated()`
(`src/shared/utils/apiAuth.ts`) — a dashboard session cookie or a management-scoped
API key, the same gate that protects the rest of `/api/settings/*`. The flag-off
`404` check always runs **before** the auth check, so an install with `RADAR_ENABLED`
@@ -481,58 +318,6 @@ auth state — only the masked form and a `hasSupporterKey` boolean.
---
## Supporter offers
Offers use their own signed artifact, `GET /v1/offers/latest`, and never share the catalog or
referrals cache. The server endpoint requires a valid live supporter Bearer key; there is no
community fallback. `syncRadarOffers()` therefore stops before the network when the feature flag is
off, the operator has not opted in, or no supporter key is configured.
After a successful GET, the client verifies the Ed25519 signature over the exact response bytes,
validates `RadarOffersFeedSchema`, requires both the signed body and
`x-omniroute-feed-tier` header to say `live`, enforces a strictly newer dotted version, and only then
atomically replaces `radar_offers_cache` (migration `144_radar_offers_cache.sql`). The same 10 MB
header-plus-stream cap used by the other feeds applies. Signature, schema, tier, replay, size, HTTP,
and network failures all preserve the last verified cache.
The closed offer shape supports three comparable benefit types: percentage in basis points, credit
in minor currency units, or trial days. A partner offer must include a same-kind public baseline and
its benefit must be strictly greater; official offers have no partner baseline. URLs must be
credential-free HTTPS. `getRadarOffers()` defensively revalidates the cached payload and filters
expired entries on every local read; `/dashboard/radar/offers` filters expiry again before rendering,
uses Portuguese text when available with English fallback, and labels partner offers explicitly.
The browser calls only local routes: it reads the masked settings snapshot, asks
`POST /api/radar/offers/sync` to refresh server-side, then reads `GET /api/radar/offers`. Without a
key it shows the existing contributor/support links instead of attempting a feed request. External
offer links open in a new tab with `noopener noreferrer`. No `radar_offers` MCP tool is exposed in
this release.
---
## Radar Intel, supporter badge, and CLI
Intel is a signed artifact at `GET /v1/intel/latest`. The closed `RadarIntelFeedSchema` accepts
only Radar-owned ELO rankings derived by the private curator from confirmed comparisons and factual
catalog age/count deltas derived from signed catalog snapshots. The methodology is fixed at initial
rating 1000 and K=32. An empty ranking is valid when no comparison has been confirmed; the client
never synthesizes one.
`syncRadarIntel()` applies the same server-side Bearer, 30-second timeout, 10 MiB streamed cap,
exact-byte Ed25519 verification, strict schema, `live` body/header requirement, version floor, and
last-good-cache preservation as offers. After a verified live snapshot is persisted, the client
derives `radar:<sha256(supporter key)>`, stores only that one-way identity, and emits the dedicated
`radar_supporter` recognition event. Its `radar-supporter` badge is idempotent and awards zero XP;
it never updates leaderboards or reuses `token_share`. `/dashboard/radar/intel` renders the badge
only from verified local cache metadata.
The CLI exposes `omniroute radar status` and `omniroute radar sync`. Both communicate only with the
local OmniRoute API. `status` performs a read-only `GET /api/radar/status`; `sync` sends one
`POST /api/radar/sync-all` and prints a result per feed. Neither command reads, accepts, or prints
the supporter key, and neither contacts the Radar service directly.
---
## Referral links (free credits)
Referral links are served from a **standalone, always-current** feed —
@@ -688,9 +473,8 @@ service without touching client code:
1. Serve a `GET /v1/catalog/latest` endpoint returning a JSON body that satisfies
`RadarFeedSchema` (`src/lib/radar/feedSchema.ts`) — top-level `feed:
"omniroute-radar"`, `schemaVersion: 2`, `version`, `tier`, `providers`, `models`,
`quirks`, and `totals`. Honor `x-omniroute-radar-schema: 2`; a transition-compatible server
should default requests without it to a separately signed v1 artifact.
"omniroute-radar"`, `schemaVersion: 1`, `version`, `tier`, `providers`, `models`,
`quirks`, and `totals`.
2. Sign the exact response bytes with an Ed25519 key pair and return the base64
signature in the `x-omniroute-feed-signature` response header.
3. Set `RADAR_FEED_URL` to the new base URL and `RADAR_FEED_PUBKEY` to the matching
@@ -714,24 +498,11 @@ instead of failing the rest of the page. To also offer referral links, serve
(`src/lib/radar/referralsFeedSchema.ts`) and sign it with the same Ed25519 key pair as
the catalog feed.
Supporter offers are another optional artifact. To serve them, implement
`GET /v1/offers/latest` with the closed `RadarOffersFeedSchema`
(`src/lib/radar/offersFeedSchema.ts`), require live entitlement, return
`x-omniroute-feed-tier: live`, and sign the exact bytes with the same key. A fork that omits this
endpoint keeps the catalog/referrals behavior unchanged; offer refresh fails non-destructively and
the last verified local offer cache remains available.
Intel is optional in the same way. A self-hoster can serve `GET /v1/intel/latest` using
`RadarIntelFeedSchema` (`src/lib/radar/intelFeedSchema.ts`), require live entitlement, return
`x-omniroute-feed-tier: live`, and sign the exact bytes with the shared Ed25519 key. Omitting the
endpoint leaves catalog, referrals, and offers unchanged; Intel refresh preserves any last verified
local snapshot.
---
## Related docs
- [`docs/security/ERROR_SANITIZATION.md`](../security/ERROR_SANITIZATION.md) — the
error-response pattern the `/api/radar/*` routes follow.
error-response pattern the five `/api/radar/*` routes follow.
- [`docs/reference/ENVIRONMENT.md`](../reference/ENVIRONMENT.md#27-radar-feed-self-hosting)
— `RADAR_FEED_URL` / `RADAR_FEED_PUBKEY` reference.

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,7 +4,10 @@
---
> 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 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -18,7 +21,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -106,7 +109,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -128,7 +131,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -211,11 +214,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -266,7 +269,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -349,9 +352,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -394,7 +397,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -438,7 +441,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -482,7 +485,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -65,7 +65,6 @@ directly from anywhere — CI can only stage; only the owner's 2FA releases.
as the default reflex (minutes, reversible); `npm unpublish` only inside the 72h/no-dependents
window and never as the first move. Docker: never rewrite a version tag — rollback is
repointing `latest` to the last good digest.
## Hotfix Fast-Lane (label `hotfix`)
A PR labeled `hotfix` skips the heavy CI matrix (9-shard E2E, coverage ratchet,
@@ -277,22 +276,6 @@ Deploy skills use the light rsync flow — no `npm pack`, no `npm i -g`:
- [ ] Open milestone for next version
- [ ] If critical: pin discussion or post in `news.json` for in-app banner
### Radar public-launch gate
The Radar announcement is intentionally committed with `active: false`. Activation is a separate
change after every item below is evidenced:
- [ ] All stacked Radar PRs are merged and the release-tip CI is green
- [ ] Deploy and smoke the OSS Radar routes with `RADAR_ENABLED` still off by default
- [ ] Smoke `GET /planos`, `/termos`, `/privacidade`, and `/reembolso` on the named Radar host
- [ ] Record operator identity/contact/address and owner-approved legal review in the private service
- [ ] Exercise Stripe Checkout and the signed webhook in test mode only
- [ ] Exercise one encrypted transactional-email delivery with the approved sender/domain
- [ ] Prove backup restore and one supervised, budget-capped research run
- [ ] Approve the BRL/PIX review policy before accepting donation evidence
- [ ] Enable public Checkout only after the preceding gates, then activate the new `news.json` ID
- [ ] Verify the Home banner uses localized copy and a new ID reappears after an older ID is dismissed
## Embedded Services smoke (v3.8.4+)
Before shipping any release that includes embedded services changes, verify:

View File

@@ -32,7 +32,7 @@ different endpoint families, so all four products remain separate provider IDs.
| Provider family | `global-sg` | `china-beijing` | Wire format |
| ----------------------- | ------------------------------------------------------------------------ | -------------------------------------------------------------------- | ----------- |
| `alibaba` | `https://dashscope-intl.aliyuncs.com/compatible-mode/v1` | `https://dashscope.aliyuncs.com/compatible-mode/v1` | OpenAI |
| `bailian-coding-plan` | `https://token-plan.ap-southeast-1.maas.aliyuncs.com/apps/anthropic/v1` | `https://token-plan.cn-beijing.maas.aliyuncs.com/apps/anthropic/v1` | Anthropic |
| `bailian-coding-plan` | `https://coding-intl.dashscope.aliyuncs.com/apps/anthropic/v1` | `https://coding.dashscope.aliyuncs.com/apps/anthropic/v1` | Anthropic |
| `qwen-cloud` | `https://dashscope-intl.aliyuncs.com/compatible-mode/v1` | `https://dashscope.aliyuncs.com/compatible-mode/v1` | OpenAI |
| `qwen-cloud-token-plan` | `https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1` | `https://token-plan.cn-beijing.maas.aliyuncs.com/compatible-mode/v1` | OpenAI |

View File

@@ -1352,24 +1352,17 @@ that should be able to run the docs translator.
Optional add-on gated by the RADAR_ENABLED feature flag (default off — a feature
flag toggled via Settings/DB, not an env var; see
[docs/frameworks/RADAR.md](../frameworks/RADAR.md#flag-radar_enabled-default-off)).
The first four variables below are optional overrides for a self-hosted or forked feed and
supporter-key flows. The fifth, `RADAR_ADMIN_URL`, is a separate default-free link to the owner's
private operations panel. See [docs/frameworks/RADAR.md](../frameworks/RADAR.md) for the full
module doc and its
[end-to-end activation and guided-setup sequence](../frameworks/RADAR.md#end-to-end-activation-and-guided-setup).
The generic Home/Changelog announcement reader is not configured by an environment
variable and does not depend on the RADAR_ENABLED feature flag. It reads the public repository
`news.json` URL declared in `src/shared/utils/releaseNotes.ts` by
GET only; dismissal IDs remain in browser local storage.
The four variables below are optional overrides used only to point the client at a
self-hosted or forked feed / supporter-key flow instead of the default OmniRoute
Radar service. See [docs/frameworks/RADAR.md](../frameworks/RADAR.md) for the full
module doc.
| Variable | Default | Source File | Description |
| -------------------------------- | --------------------------------------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------ |
| `RADAR_FEED_URL` | `https://radar.omniroute.online` | `src/lib/radar/{sync,referralsSync,offersSync,intelSync}.ts` | Base URL shared by the separately signed catalog, referrals, supporter-offers, and Intel feeds. Override to point at a self-hosted or forked service. |
| `RADAR_FEED_URL` | `https://radar.omniroute.online` | `src/lib/radar/sync.ts` | Base URL of the Radar feed service. Override to point at a self-hosted or forked feed. |
| `RADAR_FEED_PUBKEY` | _(pinned default key)_ | `src/lib/radar/pinnedKeys.ts` | Ed25519 public key (base64-DER SPKI or PEM) used to verify feed signatures from a custom feed. |
| `RADAR_CONTRIBUTOR_CLAIM_URL` | `https://radar.omniroute.online/auth/github` | `src/lib/radar/links.ts` | URL the "I'm a contributor" dashboard button opens (GitHub OAuth supporter-key claim flow). |
| `RADAR_SUPPORTER_PLANS_URL` | `https://radar.omniroute.online/planos` | `src/lib/radar/links.ts` | URL the "Support the project" dashboard button opens (payment/plans page). |
| `RADAR_ADMIN_URL` | _(unset)_ | `src/lib/radar/links.ts` | Owner-only private operations-panel link. HTTPS is required except for an HTTP loopback SSH forward; unset or invalid values create no navigation item. |
---

24
llm.txt
View File

@@ -1,6 +1,6 @@
# OmniRoute
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (109 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 339 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (105 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -14,7 +14,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, 148 migrations)
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 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
@@ -102,7 +102,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ ├── db/ # SQLite database layer (99 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management
@@ -124,7 +124,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ │ └── migrations/ # 117 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -207,11 +207,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes)
│ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler
@@ -262,7 +262,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md
│ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (109 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md
│ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.md
│ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -345,9 +345,9 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, 6 skills: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities)
- **ACP** — Agent Communication Protocol registry and manager
### MCP Server (109 Tools)
### MCP Server (105 Tools)
109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`.
@@ -390,7 +390,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 SQL migrations.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 99 `src/lib/db/` modules with 117 SQL migrations.
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
@@ -434,7 +434,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 (117 domain-specific files, 148 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 (117 domain-specific files, 145 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.
@@ -478,7 +478,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add
- **19 routing strategies** — including `fusion` (parallel panel + judge synthesis), `pipeline`, `reset-aware`, `reset-window`, `headroom`, and `context-relay`
- **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -1,43 +1,8 @@
{
"schemaVersion": 2,
"items": [
{
"id": "radar-launch-2026-08",
"active": false,
"publishedAt": "2026-08-09T00:00:00.000Z",
"text": {
"en": {
"title": "OmniRoute Radar",
"message": "An opt-in, GET-only free-model catalog overlay with no telemetry from the OmniRoute client.",
"linkLabel": "Learn about Radar"
},
"pt-BR": {
"title": "OmniRoute Radar",
"message": "Um catálogo opcional de modelos gratuitos, somente GET e sem telemetria enviada pelo cliente OmniRoute.",
"linkLabel": "Conheça o Radar"
}
},
"link": "https://radar.omniroute.online/planos",
"icon": "radar"
},
{
"id": "tomni-launch-2026-07",
"active": false,
"publishedAt": "2026-07-01T00:00:00.000Z",
"text": {
"en": {
"title": "New in the Omniverse",
"message": "tOmni is an interactive multi-agent terminal focused on developer productivity.",
"linkLabel": "Meet tOmni"
},
"pt-BR": {
"title": "Novidade no Omniverse",
"message": "O tOmni é um terminal interativo para múltiplos agentes, focado na produtividade de desenvolvedores.",
"linkLabel": "Conhecer o tOmni"
}
},
"link": "https://github.com/diegosouzapw/tOmni",
"icon": "campaign"
}
]
"active": false,
"title": "Novidade no Omniverse",
"message": "Está lançado hoje o tOmni, o terminal interativo múltiplo para Agentes de AI! Experimente a nova interface focada em produtividade para desenvolvedores.",
"link": "https://github.com/diegosouzapw/tOmni",
"linkLabel": "Conhecer o tOmni",
"icon": "campaign"
}

View File

@@ -30,15 +30,13 @@ export type ProviderErrorRule = {
export type ProviderErrorRuleMatch = {
reason: ConfiguredErrorReason;
/**
* Intended lock scope. #10334: this field is CONSUMED end-to-end only for
* providers in `HONORS_RULE_LOCK_SCOPE_PROVIDERS` (agentrouter-exclusive
* today, gated by `honorsRuleLockScope()`) — for those, `checkFallbackError`
* surfaces it as `ruleScope` on its return value for the persistence layer
* to honor instead of re-deriving scope from `hasPerModelQuota()`. For
* every other provider it remains INFORMATIONAL: `getProviderErrorRuleMatch`
* callers still read only `reason`/`cooldownMs`, and the actual lock scope
* is decided independently by each call site. Widening the allowlist is
* tracked as a follow-up — see `docs/architecture/RESILIENCE_GUIDE.md` §7.
* Intended lock scope. NOTE: this field is currently INFORMATIONAL — no
* consumer of `getProviderErrorRuleMatch` (checkFallbackError, combo.ts)
* reads `scope` today; only `reason` and `cooldownMs` are consulted. The
* actual lock scope applied at runtime is decided independently by each
* call site (e.g. `hasPerModelQuota()` deciding model- vs connection-level
* lockout). Honoring this field end-to-end is tracked as a follow-up —
* see `docs/architecture/RESILIENCE_GUIDE.md` §7.
*/
scope: "model" | "provider" | "connection";
/** Optional explicit cooldown; falls back to the existing per-reason defaults. */
@@ -190,29 +188,31 @@ function buildOpenrouterRules(): ProviderErrorRule[] {
// agentrouter.org misstates temporary quota exhaustion as 403/400 with a
// Chinese body. upstreamStatusRestatement.ts rewrites the status to 429
// BEFORE classification, so rules here accept both the raw 403/400 and the
// restated 429 (text is the real discriminator either way). Both the raw 403
// path AND the restated 429 path reach these rules in production:
// checkFallbackError's `honorsRuleLockScope("agentrouter")` pre-check
// (#10334) consults these rules BEFORE the generic apikey-category FORBIDDEN
// branch, and the restated 429 reaches them via the existing provider-rule
// lookup in the configured-rule branch. Both paths use resolveRuleMatchBody,
// the only mechanism in checkFallbackError that hands agentrouter's rules the
// full error text instead of just {code, type}.
// restated 429 (text is the real discriminator either way). In production,
// the raw 403 path is what actually matters here: checkFallbackError's
// apikey-category FORBIDDEN branch (~line 1699) returns EARLY for a plain
// 403, before these rules are ever consulted — these rules fire on the
// RESTATED 429 (chatCore's upstreamStatusRestatement hook runs first) via
// resolveRuleMatchBody, which is the only path in checkFallbackError that
// hands these rules the full error text instead of just {code, type}.
// - "额度不足": account-wide temporary quota → quota_exhausted, scope
// "connection" (mirror of the Opencode account-wide rationale above).
// `scope` on ProviderErrorRuleMatch is CONSUMED for agentrouter (#10334,
// exclusive allowlist via `honorsRuleLockScope`): checkFallbackError
// surfaces it as `ruleScope` on its return value. Whether the persistence
// layer (markAccountUnavailable / combo target exhaustion) actually
// switches from `hasPerModelQuota()`-derived scope to honoring `ruleScope`
// is Tasks 2/3 of #10334 — this task only surfaces the field.
// NOTE: `scope` on ProviderErrorRuleMatch is currently informational —
// checkFallbackError/combo.ts only consume `reason` and `cooldownMs`, not
// `scope`. For agentrouter specifically (passthroughModels: true →
// hasPerModelQuota() is true), this quota_exhausted match actually
// resolves to a PER-MODEL lockout (recordModelLockoutFailure), not a
// connection-wide lockother models on the same account keep being
// tried by combo routing (each burning one call) until they lock out
// individually. Honoring `scope` end-to-end is tracked as a follow-up.
// - "无权访问模型": declares auth_error/scope "model" (intent: lock only the
// model so the connection keeps serving the rest — Model Lockout tier).
// This rule now fires on the production 403 path (#10334): the
// `honorsRuleLockScope` pre-check matches it and returns its declared
// reason/cooldown/scope before the generic apikey-FORBIDDEN early-return
// ever runs. A live `无权访问模型` 403 therefore no longer falls through to
// the base apikey-provider 403 handling.
// This rule does NOT fire on the production path today: it only matches
// `status === 403`, but checkFallbackError's apikey FORBIDDEN branch
// returns early for a plain 403 before this rule is ever consulted (see
// the note above). A live `无权访问模型` 403 is handled like the base
// apikey-provider 403 today. Wiring this rule into that path is tracked
// as a follow-up.
function buildAgentrouterRules(): ProviderErrorRule[] {
const AGENTROUTER_ERROR_STATUSES = new Set([400, 403, 429]);
return [
@@ -231,15 +231,8 @@ function buildAgentrouterRules(): ProviderErrorRule[] {
if (status !== 403) return null;
const text = JSON.stringify(body ?? "").toLowerCase();
if (!text.includes("无权访问模型")) return null;
// Declares a 6h cooldown, but the effective cooldown is NOT 6h: the
// model-lockout persistence layer (recordModelLockoutFailure, called from
// markAccountUnavailable) clamps every base cooldown — this one included —
// to the configured model-lockout maxCooldownMs, which defaults to
// 1_800_000ms / 30min (src/lib/resilience/modelLockoutSettings.ts,
// DEFAULT_MODEL_LOCKOUT_SETTINGS.maxCooldownMs). So in practice this is
// "locked for ~30min by default (up to 6h if an operator raises the model-
// lockout cap in settings)", not "until the operator fixes the key's model
// grants" — it is a recoverable window, not a real fix-driven unlock.
// 6h: effectively "until the operator fixes the key's model grants",
// without being an unrecoverable terminal state.
return { reason: "auth_error", scope: "model", cooldownMs: 6 * 60 * 60 * 1000 };
},
},
@@ -262,21 +255,6 @@ export const providerRuleRegistry = new Map<string, ProviderErrorRule[]>([
["agentrouter", buildAgentrouterRules()],
]);
/**
* Providers whose ProviderErrorRuleMatch.scope is actually CONSUMED at the
* persistence layer (markAccountUnavailable / combo target exhaustion) to pick
* connection-vs-model lock scope. EXCLUSIVE allowlist by owner decision
* (2026-08-14, issue #10334) — deliberately SEPARATE from
* FULL_TEXT_RULE_PROVIDERS: that set controls what body a rule matches against
* (input), this one controls whether the matched scope changes caller behavior
* (output). A provider could need one without the other.
*/
const HONORS_RULE_LOCK_SCOPE_PROVIDERS = new Set(["agentrouter"]);
export function honorsRuleLockScope(provider: string | null | undefined): boolean {
return !!provider && HONORS_RULE_LOCK_SCOPE_PROVIDERS.has(provider.toLowerCase());
}
/**
* Providers whose rules match on the FULL upstream error text.
* checkFallbackError's rule lookup normally passes only the structured

View File

@@ -1,6 +1,6 @@
# OmniRoute MCP Server
> **Model Context Protocol server** that exposes OmniRoute's gateway intelligence as **109 tools** for AI agents.
> **Model Context Protocol server** that exposes OmniRoute's gateway intelligence as **107 tools** for AI agents.
>
> **Source of truth for the full tool catalog and REST surface:** [`docs/frameworks/MCP-SERVER.md`](../../docs/frameworks/MCP-SERVER.md). This README focuses on architecture, configuration, and integration examples; the catalog below is a summary subset.
@@ -20,7 +20,7 @@ The MCP Server allows any AI agent (Claude Desktop, Cursor, VS Code Copilot, cus
┌──────────────────────────────────────────────────────────────────┐
│ OmniRoute MCP Server │
│ ┌──────────────┐ ┌─────────────────┐ ┌────────────────────┐ │
│ │ Scope │ │ 109 MCP Tools │ │ Audit Logger │ │
│ │ Scope │ │ 107 MCP Tools │ │ Audit Logger │ │
│ │ Enforcement │──│ (core + memory │──│ (SHA-256/SQLite) │ │
│ │ │ │ + skills + …) │ │ │ │
│ └──────────────┘ └────────┬────────┘ └────────────────────┘ │
@@ -120,23 +120,18 @@ omniroute --mcp
## Tool Reference
### Phase 1: Essential Tools (13)
### Phase 1: Essential Tools (8)
| # | Tool | Scopes | Description |
| --- | ------------------------------- | --------------------- | -------------------------------------------------------------------------- |
| 1 | `omniroute_tool_search` | `read:tools` | Discover tools from the registered MCP catalog |
| 2 | `omniroute_get_health` | `read:health` | Gateway health, uptime, memory, circuit breakers, rate limits, cache stats |
| 3 | `omniroute_list_combos` | `read:combos` | List all combos (model chains) with strategies and optional metrics |
| 4 | `omniroute_get_combo_metrics` | `read:combos` | Performance metrics for a specific combo |
| 5 | `omniroute_switch_combo` | `write:combos` | Activate or deactivate a combo for routing |
| 6 | `omniroute_create_combo` | `write:combos` | Create a validated combo through the existing combo API |
| 7 | `omniroute_check_quota` | `read:quota` | Remaining API quota per provider with token health status |
| 8 | `omniroute_route_request` | `execute:completions` | Send a chat completion through intelligent routing |
| 9 | `omniroute_cost_report` | `read:usage` | Cost report by period (session/day/week/month) with per-provider breakdown |
| 10 | `omniroute_list_models_catalog` | `read:models` | List all available models across providers with capabilities and pricing |
| 11 | `omniroute_radar_catalog` | `read:radar` | Read the local signed Radar catalog with provider/family filters |
| 12 | `omniroute_web_search` | `execute:search` | Search the web through configured search providers |
| 13 | `omniroute_web_fetch` | `execute:search` | Fetch web content through configured fetch providers |
| 1 | `omniroute_get_health` | `read:health` | Gateway health, uptime, memory, circuit breakers, rate limits, cache stats |
| 2 | `omniroute_list_combos` | `read:combos` | List all combos (model chains) with strategies and optional metrics |
| 3 | `omniroute_get_combo_metrics` | `read:combos` | Performance metrics for a specific combo |
| 4 | `omniroute_switch_combo` | `write:combos` | Activate or deactivate a combo for routing |
| 5 | `omniroute_check_quota` | `read:quota` | Remaining API quota per provider with token health status |
| 6 | `omniroute_route_request` | `execute:completions` | Send a chat completion through intelligent routing |
| 7 | `omniroute_cost_report` | `read:usage` | Cost report by period (session/day/week/month) with per-provider breakdown |
| 8 | `omniroute_list_models_catalog` | `read:models` | List all available models across providers with capabilities and pricing |
### Phase 2: Advanced Tools (8)

View File

@@ -1,7 +1,7 @@
/**
* Unit tests for MCP Essential Tools (Phase 1)
*
* Tests the essential tool handlers via the tool handler functions.
* Tests all 10 essential tool handlers via the tool handler functions.
* The omniroute_web_search tests use InMemoryTransport + Client to exercise
* the actual registered handler (not mockFetch directly).
*/
@@ -22,10 +22,10 @@ describe("MCP Essential Tools", () => {
});
describe("Tool schema validation", () => {
it("should have exactly 13 essential tools (including Radar catalog)", () => {
// 12 -> 13: F3 shipped omniroute_radar_catalog as a phase-1 read-only tool.
it("should have exactly 12 essential tools (includes web_search + web_fetch + tool_search)", () => {
// 11 -> 12: #8925 shipped omniroute_create_combo as a phase-1 tool.
const schemas = MCP_ESSENTIAL_TOOLS;
expect(schemas).toHaveLength(13);
expect(schemas).toHaveLength(12);
});
it("all tools should have omniroute_ prefix", () => {

View File

@@ -1,151 +0,0 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
import { MCP_SCOPE_LIST, MCP_TOOL_SCOPES } from "../../../src/shared/constants/mcpScopes.ts";
import { evaluateToolScopes } from "../scopeEnforcement.ts";
import { getMcpRadarCatalog } from "../radarCatalog.ts";
import { MCP_ESSENTIAL_TOOLS, MCP_TOOL_MAP } from "../schemas/tools.ts";
import { createMcpServer } from "../server.ts";
vi.mock("../audit.ts", () => ({
logToolCall: vi.fn().mockResolvedValue(undefined),
}));
const catalog = {
entries: [
{
provider: "groq",
modelId: "llama",
displayName: "Llama on Groq",
familyId: "llama-family",
monthlyTokens: 200,
creditTokens: 0,
freeType: "recurring-daily",
poolKey: null,
tos: "ok",
enabled: true,
origin: "radar",
capabilities: { tools: true, vision: false, thinking: false },
limits: { rpm: 30, rpd: null, tpm: null, tpd: null },
setup: { keyUrl: "https://secret.example/key", steps: ["do not expose"] },
},
{
provider: "cerebras",
modelId: "llama",
displayName: "Llama on Cerebras",
familyId: "llama-family",
monthlyTokens: 300,
creditTokens: 0,
freeType: "recurring-daily",
poolKey: null,
tos: "ok",
enabled: false,
disabledBy: "radar",
origin: "radar",
capabilities: { tools: true, vision: false, thinking: true },
limits: { rpm: null, rpd: 100, tpm: null, tpd: null },
},
],
meta: { version: "2026.08.08.1", tier: "community", fetchedAt: "2026-08-08T20:00:00Z" },
};
describe("omniroute_radar_catalog", () => {
it("is a phase-1 read-only registry tool with the dedicated Radar scope", () => {
const definition = MCP_TOOL_MAP.omniroute_radar_catalog;
expect(definition).toBeDefined();
expect(definition.phase).toBe(1);
expect(definition.scopes).toEqual(["read:radar"]);
expect(definition.auditLevel).toBe("none");
expect(definition.sourceEndpoints).toEqual(["/api/radar/catalog"]);
expect(MCP_ESSENTIAL_TOOLS).toContain(definition);
expect(MCP_SCOPE_LIST).toContain("read:radar");
expect(MCP_TOOL_SCOPES.omniroute_radar_catalog).toEqual(["read:radar"]);
});
it("reads only the local catalog and returns a closed filtered projection", async () => {
const fetchJson = vi.fn().mockResolvedValue(catalog);
const result = await getMcpRadarCatalog(
{ provider: "groq", familyId: "llama-family", enabledOnly: true },
{ fetchJson }
);
expect(fetchJson).toHaveBeenCalledOnce();
expect(fetchJson).toHaveBeenCalledWith("/api/radar/catalog");
expect(result.models).toHaveLength(1);
expect(result.models[0]).toEqual({
provider: "groq",
modelId: "llama",
displayName: "Llama on Groq",
familyId: "llama-family",
quota: {
monthlyTokens: 200,
creditTokens: 0,
freeType: "recurring-daily",
limits: { rpm: 30, rpd: null, tpm: null, tpd: null },
},
capabilities: { tools: true, vision: false, thinking: false },
enabled: true,
origin: "radar",
disabledBy: null,
});
expect(JSON.stringify(result)).not.toContain("secret.example");
expect(JSON.stringify(result)).not.toContain("setup");
});
it("defaults enabledOnly to true and includes disabled models only when explicitly requested", async () => {
const fetchJson = vi.fn().mockResolvedValue(catalog);
expect((await getMcpRadarCatalog({}, { fetchJson })).models).toHaveLength(1);
expect((await getMcpRadarCatalog({ enabledOnly: false }, { fetchJson })).models).toHaveLength(
2
);
});
it("allows read:radar and read:* but denies a missing scope when enforcement is active", () => {
expect(evaluateToolScopes("omniroute_radar_catalog", ["read:radar"], true).allowed).toBe(true);
expect(evaluateToolScopes("omniroute_radar_catalog", ["read:*"], true).allowed).toBe(true);
expect(evaluateToolScopes("omniroute_radar_catalog", [], true)).toMatchObject({
allowed: false,
reason: "missing_scopes",
missing: ["read:radar"],
});
});
});
describe("omniroute_radar_catalog MCP dispatch", () => {
const mockFetch = vi.fn();
let client: Client;
beforeEach(async () => {
mockFetch.mockReset();
vi.stubGlobal("fetch", mockFetch);
const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
const server = createMcpServer();
await server.connect(serverTransport);
client = new Client({ name: "radar-catalog-test", version: "1.0.0" });
await client.connect(clientTransport);
});
afterEach(async () => {
await client.close();
vi.unstubAllGlobals();
});
it("registers and dispatches a real read without sync or write", async () => {
mockFetch.mockResolvedValueOnce({ ok: true, json: async () => catalog });
const listed = await client.listTools();
expect(listed.tools.some((tool) => tool.name === "omniroute_radar_catalog")).toBe(true);
const result = await client.callTool({
name: "omniroute_radar_catalog",
arguments: { enabledOnly: false },
});
expect(result.isError).toBeFalsy();
expect(mockFetch).toHaveBeenCalledOnce();
expect(mockFetch.mock.calls[0][0]).toContain("/api/radar/catalog");
expect(mockFetch.mock.calls[0][1]).not.toMatchObject({ method: "POST" });
const body = JSON.parse((result.content[0] as { text: string }).text);
expect(body.models).toHaveLength(2);
});
});

View File

@@ -1,170 +0,0 @@
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { logToolCall } from "./audit.ts";
import { radarCatalogInput, radarCatalogOutput } from "./schemas/radarCatalog.ts";
import type { McpToolExtraLike } from "./scopeEnforcement.ts";
import type { TextToolResult } from "./toolResult.ts";
import { sanitizeErrorMessage } from "../utils/error.ts";
type JsonRecord = Record<string, unknown>;
type ScopeEnforcer = (
toolName: string,
handler: (args: unknown, extra?: McpToolExtraLike) => Promise<TextToolResult>,
toolScopes?: readonly string[]
) => (args: unknown, extra?: McpToolExtraLike) => Promise<TextToolResult>;
export interface McpRadarCatalogArgs {
provider?: string;
familyId?: string;
enabledOnly?: boolean;
}
interface McpRadarCatalogDeps {
fetchJson?: (path: string) => Promise<unknown>;
}
function record(value: unknown): JsonRecord {
return value !== null && typeof value === "object" && !Array.isArray(value)
? (value as JsonRecord)
: {};
}
function text(value: unknown, fallback = ""): string {
return typeof value === "string" ? value : fallback;
}
function number(value: unknown): number {
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : 0;
}
function nullableNumber(value: unknown): number | null {
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : null;
}
function normalizeMeta(
value: unknown
): { version: string; tier: string; fetchedAt: string } | null {
const meta = record(value);
if (
typeof meta.version !== "string" ||
typeof meta.tier !== "string" ||
typeof meta.fetchedAt !== "string"
) {
return null;
}
return { version: meta.version, tier: meta.tier, fetchedAt: meta.fetchedAt };
}
function normalizeEntry(value: unknown) {
const entry = record(value);
const provider = text(entry.provider).trim();
const modelId = text(entry.modelId).trim();
if (!provider || !modelId) return null;
const capabilities = record(entry.capabilities);
const limits = record(entry.limits);
const origin =
entry.origin === "radar" || entry.origin === "local" ? entry.origin : ("baseline" as const);
return {
provider,
modelId,
displayName: text(entry.displayName, modelId),
familyId: typeof entry.familyId === "string" ? entry.familyId : null,
quota: {
monthlyTokens: number(entry.monthlyTokens),
creditTokens: number(entry.creditTokens),
freeType: text(entry.freeType, "unknown"),
limits:
Object.keys(limits).length > 0
? {
rpm: nullableNumber(limits.rpm),
rpd: nullableNumber(limits.rpd),
tpm: nullableNumber(limits.tpm),
tpd: nullableNumber(limits.tpd),
}
: null,
},
capabilities:
Object.keys(capabilities).length > 0
? {
tools: capabilities.tools === true,
vision: capabilities.vision === true,
thinking: capabilities.thinking === true,
}
: null,
enabled: entry.enabled !== false,
origin,
disabledBy: entry.disabledBy === "radar" ? ("radar" as const) : null,
};
}
function compareEntries(
left: NonNullable<ReturnType<typeof normalizeEntry>>,
right: NonNullable<ReturnType<typeof normalizeEntry>>
): number {
return left.provider.localeCompare(right.provider) || left.modelId.localeCompare(right.modelId);
}
/** Read and project the local Radar catalog without exposing setup or secret-bearing state. */
export async function getMcpRadarCatalog(
args: McpRadarCatalogArgs,
deps: McpRadarCatalogDeps = {}
) {
const fetchJson =
deps.fetchJson ??
((path: string) => import("./server.ts").then((module) => module.omniRouteFetch(path)));
const raw = record(await fetchJson("/api/radar/catalog"));
const providerFilter = args.provider?.trim().toLowerCase();
const familyFilter = args.familyId?.trim().toLowerCase();
const enabledOnly = args.enabledOnly !== false;
const entries = Array.isArray(raw.entries) ? raw.entries : [];
const models = entries
.map(normalizeEntry)
.filter((entry): entry is NonNullable<typeof entry> => entry !== null)
.filter((entry) => !enabledOnly || entry.enabled)
.filter((entry) => !providerFilter || entry.provider.toLowerCase() === providerFilter)
.filter((entry) => !familyFilter || entry.familyId?.toLowerCase() === familyFilter)
.sort(compareEntries);
return { meta: normalizeMeta(raw.meta), models };
}
async function handleRadarCatalog(args: {
provider?: string;
familyId?: string;
enabledOnly: boolean;
}): Promise<TextToolResult> {
const start = Date.now();
try {
const result = radarCatalogOutput.parse(await getMcpRadarCatalog(args));
await logToolCall(
"omniroute_radar_catalog",
args,
{ modelCount: result.models.length },
Date.now() - start,
true
);
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
} catch (error) {
const message = sanitizeErrorMessage(error) || "Failed to read Radar catalog";
await logToolCall("omniroute_radar_catalog", args, null, Date.now() - start, false, message);
return { content: [{ type: "text", text: `Error: ${message}` }], isError: true };
}
}
export function registerRadarCatalogTool(
server: McpServer,
withScopeEnforcement: ScopeEnforcer
): void {
server.registerTool(
"omniroute_radar_catalog",
{
description: "Reads the local signed Radar catalog with optional provider and family filters",
inputSchema: radarCatalogInput,
},
withScopeEnforcement("omniroute_radar_catalog", (args) =>
handleRadarCatalog(radarCatalogInput.parse(args))
)
);
}

View File

@@ -91,8 +91,6 @@ export {
ccrStatsTool,
} from "./tools.ts";
export { radarCatalogInput, radarCatalogOutput, radarCatalogTool } from "./radarCatalog.ts";
// A2A schemas
export {
AgentCardSchema,

View File

@@ -1,65 +0,0 @@
import { z } from "zod";
import type { McpToolDefinition } from "./toolDefinition.ts";
export const radarCatalogInput = z.object({
provider: z.string().trim().min(1).max(100).optional().describe("Filter by provider id"),
familyId: z.string().trim().min(1).max(120).optional().describe("Filter by curated family id"),
enabledOnly: z.boolean().default(true).describe("Exclude models disabled by the Radar feed"),
});
const radarLimitOutput = z.object({
rpm: z.number().nullable(),
rpd: z.number().nullable(),
tpm: z.number().nullable(),
tpd: z.number().nullable(),
});
export const radarCatalogOutput = z.object({
meta: z
.object({
version: z.string(),
tier: z.string(),
fetchedAt: z.string(),
})
.nullable(),
models: z.array(
z.object({
provider: z.string(),
modelId: z.string(),
displayName: z.string(),
familyId: z.string().nullable(),
quota: z.object({
monthlyTokens: z.number(),
creditTokens: z.number(),
freeType: z.string(),
limits: radarLimitOutput.nullable(),
}),
capabilities: z
.object({
tools: z.boolean(),
vision: z.boolean(),
thinking: z.boolean(),
})
.nullable(),
enabled: z.boolean(),
origin: z.enum(["baseline", "radar", "local"]),
disabledBy: z.literal("radar").nullable(),
})
),
});
export const radarCatalogTool: McpToolDefinition<
typeof radarCatalogInput,
typeof radarCatalogOutput
> = {
name: "omniroute_radar_catalog",
description:
"Reads the local signed Radar catalog with optional provider and curated-family filters. Never syncs or writes data.",
inputSchema: radarCatalogInput,
outputSchema: radarCatalogOutput,
scopes: ["read:radar"],
auditLevel: "none",
phase: 1,
sourceEndpoints: ["/api/radar/catalog"],
};

View File

@@ -1,5 +1,5 @@
/**
* MCP Tool Schemas — Contracts for the canonical OmniRoute MCP tools.
* MCP Tool Schemas — Contracts for all 23 core and advanced OmniRoute MCP tools.
*
* Defines input/output Zod schemas, descriptions, scopes, and audit levels
* for both essential (Phase 1) and advanced (Phase 2) MCP tools.
@@ -13,11 +13,11 @@ import { z } from "zod";
import { toolSearchTool } from "./toolSearch.ts";
import { pickFastestModelTool } from "./pickFastestModel.ts";
import { CCR_MCP_TOOLS } from "./ccrTools.ts";
import { radarCatalogTool } from "./radarCatalog.ts";
import {
AUTO_ROUTING_STRATEGY_VALUES,
ROUTING_STRATEGY_VALUES,
} from "../../../src/shared/constants/routingStrategies.ts";
// ============ Shared Types ============
// AuditLevel + McpToolDefinition live in the leaf ./toolDefinition.ts so that
// toolSearch.ts can import the type without forming a tools.ts ↔ toolSearch.ts cycle.
@@ -26,7 +26,8 @@ export type { AuditLevel, McpToolDefinition } from "./toolDefinition.ts";
import type { McpToolDefinition } from "./toolDefinition.ts";
export { pickFastestModelInput, pickFastestModelOutput } from "./pickFastestModel.ts";
export * from "./ccrTools.ts";
// ============ Phase 1: Essential Tools ============
// ============ Phase 1: Essential Tools (8) ============
// --- Tool 1: omniroute_get_health ---
export const getHealthInput = z.object({}).describe("No parameters required");
@@ -439,7 +440,7 @@ export const listModelsCatalogTool: McpToolDefinition<
sourceEndpoints: ["/api/models/catalog", "/v1/models"],
};
// --- Tool 10: omniroute_web_search ---
// --- Tool 9: omniroute_web_search ---
export const webSearchInput = z.object({
query: z
.string()
@@ -1518,7 +1519,6 @@ export const MCP_TOOLS = [
routeRequestTool,
costReportTool,
listModelsCatalogTool,
radarCatalogTool,
webSearchTool,
webFetchTool,
simulateRouteTool,

View File

@@ -93,8 +93,6 @@ import { normalizeQuotaResponse } from "../../src/shared/contracts/quota.ts";
import { resolveOmniRouteBaseUrl } from "../../src/shared/utils/resolveOmniRouteBaseUrl.ts";
import { sanitizeErrorMessage } from "../utils/error.ts";
import { getMcpModelsCatalog } from "./catalog.ts";
import { registerRadarCatalogTool } from "./radarCatalog.ts";
import type { TextToolResult } from "./toolResult.ts";
export { getMcpModelsCatalog } from "./catalog.ts";
const OMNIROUTE_BASE_URL = resolveOmniRouteBaseUrl();
@@ -148,6 +146,11 @@ function readMcpAccessibilityConfig(): McpAccessibilityConfig {
}
}
type TextToolResult = {
content: Array<{ type: "text"; text: string }>;
isError?: boolean;
};
function toRecord(value: unknown): JsonRecord {
return value && typeof value === "object" && !Array.isArray(value) ? (value as JsonRecord) : {};
}
@@ -839,8 +842,6 @@ export function createMcpServer(): McpServer {
)
);
registerRadarCatalogTool(server, withScopeEnforcement);
server.registerTool(
"omniroute_simulate_route",
{

View File

@@ -1,4 +0,0 @@
export type TextToolResult = {
content: Array<{ type: "text"; text: string }>;
isError?: boolean;
};

View File

@@ -15,11 +15,7 @@ import {
serviceSupervisorCooldown,
isNimFunctionDegraded,
} from "../config/errorConfig.ts";
import {
getProviderErrorRuleMatch,
resolveRuleMatchBody,
honorsRuleLockScope,
} from "../config/providerErrorRules.ts";
import { getProviderErrorRuleMatch, resolveRuleMatchBody } from "../config/providerErrorRules.ts";
import * as rot from "./rotationConfig.ts";
import { getPassthroughProviders, getProviderCategory } from "../config/providerRegistry.ts";
import {
@@ -1462,11 +1458,6 @@ export function checkFallbackError(
/** #6061: the provider-configured cooldown (ms) before backoff scaling, surfaced so the
* caller can persist an explicit reset window instead of the engine's scaled cooldown. */
configuredCooldownMs?: number;
/** #10334 — the matched ProviderErrorRule's declared lock scope, surfaced so the
* persistence layer can honor it instead of re-deriving scope from
* hasPerModelQuota(). Populated ONLY when honorsRuleLockScope(provider) is true;
* always undefined for every other provider, so existing consumers are unaffected. */
ruleScope?: "model" | "provider" | "connection";
} {
// #10360: an executor-result contract violation is OUR bug, not the provider's.
// Retrying reproduces it verbatim, and cooling the connection down (or tripping
@@ -1721,36 +1712,6 @@ export function checkFallbackError(
return { shouldFallback: false, cooldownMs: 0, reason: RateLimitReason.UNKNOWN };
}
// #10334 — agentrouter EXCLUSIVE: consult the provider rules BEFORE the
// apikey-FORBIDDEN early-return below, so a recognized 403 body (e.g.
// "无权访问模型") carries the rule's declared reason/cooldown/scope instead of
// the generic short auth cooldown. Gated on honorsRuleLockScope — for any
// other provider this block is a no-op and the early-return stays identical.
if (status === HTTP_STATUS.FORBIDDEN && provider && honorsRuleLockScope(provider)) {
const forbiddenMatch = getProviderErrorRuleMatch(
provider,
status,
headers,
resolveRuleMatchBody(provider, structuredError ?? null, errorStr)
);
if (forbiddenMatch) {
const scaled = getScaledBaseCooldown(
forbiddenMatch.reason as RateLimitReasonValue,
backoffLevel
);
const ruleCooldownMs = forbiddenMatch.cooldownMs;
return {
shouldFallback: true,
cooldownMs: ruleCooldownMs ?? scaled.cooldownMs,
baseCooldownMs: ruleCooldownMs ?? scaled.baseCooldownMs,
configuredCooldownMs: ruleCooldownMs,
newBackoffLevel: ruleCooldownMs !== undefined ? 0 : scaled.newBackoffLevel,
reason: forbiddenMatch.reason,
ruleScope: forbiddenMatch.scope,
};
}
}
if (
status === HTTP_STATUS.FORBIDDEN &&
provider &&
@@ -1803,8 +1764,6 @@ export function checkFallbackError(
providerMatch?.cooldownMs !== undefined && providerMatch.cooldownMs > 0
? providerMatch.cooldownMs
: undefined;
const ruleScope =
providerMatch && honorsRuleLockScope(provider) ? providerMatch.scope : undefined;
const fallback = buildRetryableFallback(reason);
if (providerCooldownMs !== undefined) {
return {
@@ -1812,10 +1771,9 @@ export function checkFallbackError(
cooldownMs: providerCooldownMs,
baseCooldownMs: providerCooldownMs,
configuredCooldownMs: providerCooldownMs,
ruleScope,
};
}
return { ...fallback, ruleScope };
return fallback;
}
// #6842: non-backoff configured rules (e.g. status_402) previously never
// consulted providerRuleRegistry, so a provider-specific rule (like
@@ -1831,15 +1789,12 @@ export function checkFallbackError(
)
: null;
const cooldownMs = providerMatch?.cooldownMs ?? configuredRule.cooldownMs ?? 0;
const ruleScope =
providerMatch && honorsRuleLockScope(provider) ? providerMatch.scope : undefined;
return {
shouldFallback: true,
cooldownMs,
baseCooldownMs: cooldownMs,
configuredCooldownMs: cooldownMs,
reason: providerMatch?.reason ?? configuredRule.reason ?? RateLimitReason.UNKNOWN,
ruleScope,
};
}

View File

@@ -27,10 +27,6 @@ import {
import { RateLimitReason } from "../../config/constants.ts";
import { isProviderCircuitOpenResult, isRequestScopedUpstreamFailure } from "./comboPredicates.ts";
import { isCloudflareFingerprintRejection } from "../errorClassifier.ts";
// #10334 — agentrouter-exclusive predicate shared with the persistence layer
// (markAccountUnavailable) so the same-request combo skip and the persisted
// connection cooldown agree on exactly which fallbackResult shapes qualify.
import { isAgentrouterConnectionQuotaScope } from "@/sse/services/auth";
import type { ComboLogger, ResolvedComboTarget } from "./types.ts";
// Connection-level failure statuses: the provider connection itself is likely bad (upstream
@@ -64,13 +60,7 @@ export type ComboExhaustionSets = {
export type ApplyComboTargetExhaustionOptions = {
result: { status: number; headers?: Headers | null };
fallbackResult: Parameters<typeof isProviderExhaustedReason>[0] & {
/** #10334 — agentrouter-exclusive; see isAgentrouterConnectionQuotaScope
* (src/sse/services/auth.ts). Populated only for providers in
* HONORS_RULE_LOCK_SCOPE_PROVIDERS (today: agentrouter only). */
ruleScope?: "model" | "provider" | "connection";
permanent?: boolean;
};
fallbackResult: Parameters<typeof isProviderExhaustedReason>[0];
errorText: string;
rawModel: string;
isTokenLimitBreach: boolean;
@@ -96,56 +86,6 @@ export function applyComboTargetExhaustion(
const { result, sets, log, tag, errorText, structuredError } = opts;
const provider = target.provider;
// #10334: agentrouter-exclusive account-wide quota exhaustion ("额度不足")
// must skip remaining SAME-CONNECTION targets within THIS request too, not
// just via the persisted cooldown markAccountUnavailable applies for
// whichever leg runs next. agentrouter is a passthroughModels provider
// (hasPerModelQuota() === true), so without this branch the classification
// below would fall straight through isProviderQuotaExhausted's
// !hasPerModelQuota() guard, and — for the restated-429 case —
// markConnectionLevelExhaustion's connection-level guard (429 is not in
// CONNECTION_LEVEL_ERROR_STATUSES), marking nothing: combo would keep
// burning one upstream call per remaining model of the same exhausted
// account. isAgentrouterConnectionQuotaScope is the same guard
// markAccountUnavailable uses, so both consumers agree on exactly which
// fallbackResult shapes qualify (never a permanent/credits-exhausted
// result, even one carrying ruleScope "connection").
//
// Runs BEFORE the auth-level (401/403) branch below. This is deliberate,
// not incidental: the "额度不足" rule matches statuses {400, 403, 429}
// (buildAgentrouterRules, providerErrorRules.ts), and Task 1's FORBIDDEN
// pre-check (accountFallback.ts ~1729-1751) surfaces `ruleScope:
// "connection"` for a RAW 403 carrying that body too — so this branch can
// also fire on a 403, not just the restated 429. That is safe: for a 403
// this branch and markAuthLevelExhaustion below write the SAME set with
// the SAME `${provider}:${connId}` key and both return `true` — they are
// set-equivalent for agentrouter on that status. The Cloudflare-1010 and
// Alibaba free-tier EXEMPTIONS further down in the 401/403 branch cannot
// apply here regardless of ordering: 1010 is a CDN fingerprint rejection
// agentrouter's own text never carries, and the Alibaba exemption is
// gated on isAlibabaModelStudioProvider(provider), which agentrouter is
// not.
//
// Unlike the connection-level/auth-level branches, this path deliberately
// does NOT fall through to markTransientOrConnectionLevel, so
// sets.transientRateLimitedProviders is NEVER populated for this failure.
// That is required, not just incidental: combo.ts (both dispatchers, see
// the `allowRateLimitedConnection` reads keyed off
// transientRateLimitedProviders) uses that set to force-allow reusing a
// rate-limited CONNECTION for the provider's remaining legs — i.e. it
// bypasses the very `rateLimitedUntil` filter this branch (and Task 2's
// markAccountUnavailable) just set. Marking it here would silently
// re-open the account this branch just cooled down. One secondary
// consequence: a SIBLING agentrouter connection that is merely
// rate-limited (not the one this branch exhausted) will also no longer be
// force-allowed for a later leg on the same provider — a remaining leg
// can now resolve to "no credentials available" instead of retrying a
// rate-limited sibling account, which is the intended, safer outcome.
if (isAgentrouterConnectionQuotaScope(provider, opts.fallbackResult)) {
markAgentrouterConnectionQuotaExhaustion(target, { sets, log, tag });
return true;
}
// #8133/#8137: auth-level failures (401/403) mean that connection's credentials are bad.
// Split out to keep applyComboTargetExhaustion under the complexity ceiling.
// Cloudflare 1010 (a 403 carrying error_code 1010 / browser_signature_banned) is NOT an
@@ -319,35 +259,6 @@ function markAuthLevelExhaustion(
}
}
/**
* #10334: agentrouter-exclusive connection-scope account quota exhaustion. Mirrors
* markAuthLevelExhaustion's connectionId-present/absent split — when the target carries a
* connectionId, only that connection's account is exhausted (sibling agentrouter connections
* for the same user may still have quota); fall back to whole-provider exhaustion only when no
* connectionId is available.
*/
function markAgentrouterConnectionQuotaExhaustion(
target: ResolvedComboTarget,
opts: Pick<ApplyComboTargetExhaustionOptions, "sets" | "log" | "tag">
): void {
const { sets, log, tag } = opts;
const provider = target.provider;
const connId = target.connectionId ?? undefined;
if (connId) {
sets.exhaustedConnections.add(`${provider}:${connId}`);
log.info(
tag,
`Provider ${provider} connection ${connId} account quota exhausted (rule scope=connection) — marking for skip on remaining targets (#10334)`
);
} else {
sets.exhaustedProviders.add(provider as string);
log.info(
tag,
`Provider ${provider} account quota exhausted (rule scope=connection, no connectionId) — marking for skip on remaining targets (#10334)`
);
}
}
/**
* #1731v2: connection-level errors (408/5xx, excluding the OmniRoute circuit-open signal) suggest
* the provider connection itself is bad → skip remaining same-connection (or same-provider, when

View File

@@ -158,7 +158,6 @@ function readCodeFacts() {
'import {pluginTools} from "./open-sse/mcp-server/tools/pluginTools.ts";',
'import {notionTools} from "./open-sse/mcp-server/tools/notionTools.ts";',
'import {obsidianTools} from "./open-sse/mcp-server/tools/obsidianTools.ts";',
'import {localCorpusTools} from "./open-sse/mcp-server/tools/localCorpusTools.ts";',
'import {compressionTools} from "./open-sse/mcp-server/tools/compressionTools.ts";',
// Live provider total — the SAME collections gen-provider-reference.ts unions, so the
// doc-vs-live check below cannot drift from the generator's definition of "provider".
@@ -170,7 +169,7 @@ function readCodeFacts() {
"const pids=new Set();",
"for(const c of provCols)for(const p of Object.values(c||{}))if(p&&p.id)pids.add(p.id);",
"const cols={MCP_TOOLS,memoryTools,skillTools,agentSkillTools,githubSkillTools,poolTools,",
"gamificationTools,pluginTools,notionTools,obsidianTools,localCorpusTools,compressionTools};",
"gamificationTools,pluginTools,notionTools,obsidianTools,compressionTools};",
"const sc=new Set();",
"for(const col of Object.values(cols))for(const t of Object.values(col))",
"for(const x of (t?.scopes||[]))sc.add(x);",
@@ -453,7 +452,7 @@ export function buildChecks() {
// total ("33 tools (25 CLI Code's …)") are not the MCP aggregate
// per-module rows read "… tool definitions (N tools" / "… management tools
// (N tools" — the word tool(s)/definitions sits right before the paren. The
// aggregate ("MCP Server (109 tools", "all 109 tools") never does.
// aggregate ("MCP Server (104 tools", "all 104 tools") never does.
skipBefore: /(tools?|definitions?)\s*\(\s*$/i,
skipAfter: /^\s*\(\d+ CLI/,
},

View File

@@ -43,14 +43,15 @@ export const KNOWN_DUPLICATE_VERSIONS = new Set([
// ---------------------------------------------------------------------------
// ALLOWLIST 2 — gaps de sequência CONHECIDOS.
// Fonte: auditoria do disco (src/lib/db/migrations/). Além dos slots legados,
// As migrations Radar 144145 e a migration 143 já aterrissaram. O job registry
// foi promovido de 139 para 146 pela tabela RENAMED_MIGRATION_COMPATIBILITY. A
// 144145 seguem reservados pelas migrations Radar que já existem na série
// empilhada; a migration 143 já aterrissou. O job registry foi promovido de 139
// para 146 pela tabela RENAMED_MIGRATION_COMPATIBILITY. A
// 147149 estão reservadas por migrations atualmente em trânsito nos PRs #8228,
// #9313, #10047 e #10066; esta branch usa 150 para evitar essas colisões conhecidas.
// O stale-enforcement exige que cada reserva seja removida quando os arquivos
// correspondentes aterrissarem na release.
// ---------------------------------------------------------------------------
export const KNOWN_GAPS = new Set(["026", "055", "121", "148", "149"]); // 121: número queimado no ciclo v3.8.47 — 122 (#6909) mergeou antes e 121 nunca aterrissou (validação e2e 2026-07-12)
export const KNOWN_GAPS = new Set(["026", "055", "121", "144", "145", "148", "149"]); // 121: número queimado no ciclo v3.8.47 — 122 (#6909) mergeou antes e 121 nunca aterrissou (validação e2e 2026-07-12)
function pad3(n) {
return String(n).padStart(3, "0");

View File

@@ -22,6 +22,7 @@ import { HomeProviderTopologySection } from "./HomeProviderTopologySection";
import { shouldShowProviderTopologyOnHome } from "./homeAppearance";
const ProviderQuotaWidget = dynamic(() => import("../home/ProviderQuotaWidget"), { ssr: false });
import type { NewsAnnouncement } from "@/shared/utils/releaseNotes";
type UpdateStep = {
step: string;
@@ -36,6 +37,7 @@ type VersionInfo = {
channel: string;
autoUpdateSupported: boolean;
autoUpdateError?: string | null;
news?: NewsAnnouncement | null;
};
type HomePageClientProps = {
@@ -1045,6 +1047,37 @@ export default function HomePageClient({ machineId }: HomePageClientProps) {
</div>
)}
</div>
{/* News Notification Banner */}
{versionInfo?.news && (
<div className="flex min-h-[64px] items-center justify-between rounded-lg border border-border bg-surface px-5 py-4">
<div className="flex min-w-0 items-center gap-4">
<div className="flex size-10 shrink-0 items-center justify-center rounded-lg bg-bg text-text-muted">
<span className="material-symbols-outlined text-[22px] text-primary">
{versionInfo.news.icon || "campaign"}
</span>
</div>
<div className="min-w-0">
<p className="text-sm font-semibold text-text-main">{versionInfo.news.title}</p>
<p className="mt-0.5 max-w-[560px] text-xs leading-relaxed text-text-muted">
{versionInfo.news.message}
</p>
</div>
</div>
{versionInfo.news.link && (
<a
href={versionInfo.news.link}
target="_blank"
rel="noopener noreferrer"
className="ml-4 inline-flex shrink-0 items-center gap-1.5 rounded-lg border border-border bg-bg px-4 py-2 text-xs font-semibold text-text-main transition-colors hover:border-primary/30 hover:text-primary"
>
{versionInfo.news.linkLabel || t("readMore")}
<span className="material-symbols-outlined text-[14px]">arrow_forward</span>
</a>
)}
</div>
)}
</div>
)}

View File

@@ -1,119 +0,0 @@
"use client";
import { useEffect, useState, useSyncExternalStore } from "react";
import { useLocale, useTranslations } from "next-intl";
import {
NEWS_DISMISS_EVENT,
NEWS_DISMISS_STORAGE_NAME,
fetchNewsPayload,
parseDismissedNewsIds,
selectActiveNews,
serializeDismissedNewsIds,
} from "@/shared/utils/releaseNotes";
function subscribeToDismissals(callback: () => void) {
window.addEventListener("storage", callback);
window.addEventListener(NEWS_DISMISS_EVENT, callback);
return () => {
window.removeEventListener("storage", callback);
window.removeEventListener(NEWS_DISMISS_EVENT, callback);
};
}
function readDismissedIds(): string {
try {
return localStorage.getItem(NEWS_DISMISS_STORAGE_NAME) ?? "";
} catch {
return "";
}
}
function getServerDismissedIds(): string {
return "";
}
/**
* Generic, fail-silent reader for the public announcement feed. Fetching the
* static JSON is GET-only and does not send product state or telemetry.
*/
export default function NewsBanner() {
const locale = useLocale();
const t = useTranslations("common");
const [payload, setPayload] = useState<unknown>(null);
const dismissedSnapshot = useSyncExternalStore(
subscribeToDismissals,
readDismissedIds,
getServerDismissedIds
);
const dismissedIds = parseDismissedNewsIds(dismissedSnapshot);
const announcement = selectActiveNews(payload, locale, dismissedIds);
useEffect(() => {
const controller = new AbortController();
void fetchNewsPayload(fetch, controller.signal).then((value) => {
if (value !== null) setPayload(value);
});
return () => controller.abort();
}, []);
if (!announcement) return null;
const dismiss = () => {
dismissedIds.add(announcement.id);
try {
localStorage.setItem(NEWS_DISMISS_STORAGE_NAME, serializeDismissedNewsIds(dismissedIds));
} catch {
// Storage is optional; the next announcement fetch remains functional.
}
window.dispatchEvent(new Event(NEWS_DISMISS_EVENT));
};
return (
<div
role="complementary"
aria-label={announcement.title}
className="mb-4 flex flex-col gap-3 rounded-lg border border-primary/30 bg-primary/5 px-4 py-3 sm:flex-row sm:items-center sm:justify-between"
>
<div className="flex min-w-0 items-start gap-3">
<div className="flex size-9 shrink-0 items-center justify-center rounded-lg bg-primary/10">
<span className="material-symbols-outlined text-[22px] text-primary" aria-hidden="true">
{announcement.icon}
</span>
</div>
<div className="min-w-0">
<p className="text-sm font-semibold text-text-main">{announcement.title}</p>
<p className="mt-0.5 text-xs leading-relaxed text-text-muted">{announcement.message}</p>
</div>
</div>
<div className="flex shrink-0 items-center gap-3 self-end sm:self-auto">
{announcement.link && (
<a
href={announcement.link}
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-1.5 whitespace-nowrap rounded-lg bg-primary px-3 py-1.5 text-xs font-semibold text-white transition-colors hover:brightness-110"
>
{announcement.linkLabel ?? announcement.title}
<span className="material-symbols-outlined text-[14px]" aria-hidden="true">
open_in_new
</span>
</a>
)}
<button
type="button"
onClick={dismiss}
aria-label={t("dismissNotification")}
className="text-text-muted transition-colors hover:text-text-main"
>
<span className="material-symbols-outlined text-[18px]" aria-hidden="true">
close
</span>
</button>
</div>
</div>
);
}

View File

@@ -1,39 +1,39 @@
"use client";
import { useEffect, useState } from "react";
import { useLocale, useTranslations } from "next-intl";
import { useState, useEffect } from "react";
import { useTranslations } from "next-intl";
import { Button } from "@/shared/components";
import {
fetchNewsPayload,
listActiveNews,
NEWS_JSON_URL,
parseActiveNewsPayload,
type NewsAnnouncement,
} from "@/shared/utils/releaseNotes";
export default function NewsViewer() {
const locale = useLocale();
const t = useTranslations("changelogPage");
const [news, setNews] = useState<NewsAnnouncement[]>([]);
const [news, setNews] = useState<NewsAnnouncement | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(false);
useEffect(() => {
const controller = new AbortController();
void fetchNewsPayload(fetch, controller.signal)
.then((payload) => {
if (payload === null) {
if (!controller.signal.aborted) setError(true);
return;
async function fetchNews() {
try {
const res = await fetch(NEWS_JSON_URL, { cache: "no-store" });
if (res.ok) {
const data = await res.json();
setNews(parseActiveNewsPayload(data));
} else {
setError(true);
}
setNews(listActiveNews(payload, locale));
})
.finally(() => {
if (!controller.signal.aborted) setLoading(false);
});
return () => controller.abort();
}, [locale]);
} catch (err) {
console.error("Failed to fetch news:", err);
setError(true);
} finally {
setLoading(false);
}
}
fetchNews();
}, []);
if (loading) {
return (
@@ -48,7 +48,7 @@ export default function NewsViewer() {
if (error) {
return (
<div className="flex flex-col items-center justify-center py-20 text-text-muted">
<span className="material-symbols-outlined mb-4 text-[48px] text-red-500/50">
<span className="material-symbols-outlined text-[48px] text-red-500/50 mb-4">
error_outline
</span>
<p>{t("announcementsLoadFailed")}</p>
@@ -56,10 +56,10 @@ export default function NewsViewer() {
);
}
if (news.length === 0) {
if (!news || !news.active) {
return (
<div className="flex flex-col items-center justify-center py-20 text-text-muted">
<span className="material-symbols-outlined mb-4 text-[48px] opacity-50">
<span className="material-symbols-outlined text-[48px] opacity-50 mb-4">
notifications_off
</span>
<p>{t("noAnnouncements")}</p>
@@ -68,37 +68,30 @@ export default function NewsViewer() {
}
return (
<div className="space-y-8 p-8">
{news.map((announcement) => (
<article
key={announcement.id}
className="flex flex-col gap-6 border-l-4 border-primary pl-5 md:flex-row md:items-center md:pl-6"
>
<div className="flex size-14 shrink-0 items-center justify-center rounded-lg bg-primary/10">
<span className="material-symbols-outlined text-[30px] text-primary">
{announcement.icon}
</span>
</div>
<div className="p-8">
<div className="flex flex-col gap-6 border-l-4 border-primary pl-5 md:flex-row md:items-center md:pl-6">
<div className="size-14 rounded-lg bg-primary/10 flex items-center justify-center shrink-0">
<span className="material-symbols-outlined text-[30px] text-primary">
{news.icon || "campaign"}
</span>
</div>
<div className="flex-1">
<h2 className="mb-2 text-xl font-bold text-text-main">{announcement.title}</h2>
<p className="max-w-2xl text-sm leading-relaxed text-text-muted">
{announcement.message}
</p>
</div>
<div className="flex-1">
<h2 className="text-xl font-bold text-text-main mb-2">{news.title}</h2>
<p className="text-sm text-text-muted leading-relaxed max-w-2xl">{news.message}</p>
</div>
{announcement.link && (
<div className="shrink-0 md:ml-auto">
<a href={announcement.link} target="_blank" rel="noopener noreferrer">
<Button variant="primary" className="gap-2">
{announcement.linkLabel ?? t("learnMore")}
<span className="material-symbols-outlined text-[18px]">arrow_forward</span>
</Button>
</a>
</div>
)}
</article>
))}
{news.link && (
<div className="shrink-0 md:ml-auto">
<a href={news.link} target="_blank" rel="noopener noreferrer">
<Button variant="primary" className="gap-2">
{news.linkLabel || t("learnMore")}
<span className="material-symbols-outlined text-[18px]">arrow_forward</span>
</Button>
</a>
</div>
)}
</div>
</div>
);
}

View File

@@ -2,7 +2,7 @@
// Issue #3501 strangler-fig decomposition — Phase 1t (final push)
import { useState, useEffect, useCallback, useMemo } from "react";
import { useParams, useSearchParams } from "next/navigation";
import { useParams } from "next/navigation";
import Link from "next/link";
import { useTranslations } from "next-intl";
import { Card, Button, CardSkeleton } from "@/shared/components";
@@ -68,7 +68,6 @@ import AnonymousFallbackToggle from "./components/AnonymousFallbackToggle";
export default function ProviderDetailPageClient() {
const params = useParams();
const searchParams = useSearchParams();
const providerId = params.id as string;
// ── UI-only modal state (not owned by hooks) ─────────────────────────────
@@ -358,10 +357,6 @@ export default function ProviderDetailPageClient() {
setShowAddApiKeyModal(true);
}, [providerId]);
useEffect(() => {
if (searchParams.get("action") === "add-api-key") gateConnectionFlow(openApiKeyAddFlow);
}, [searchParams, gateConnectionFlow, openApiKeyAddFlow]);
const openPrimaryAddFlow = useCallback(() => {
if (providerId === "kimi-coding") return setShowKimiAuthMethodModal(true);
if (isOAuth) {

View File

@@ -32,6 +32,19 @@ type UseApiKeySaveParams = {
t: ProviderMessageTranslator;
};
// Issue #10096: the unified Kimi Code dashboard card shares one page/providerId
// ("kimi-coding") between OAuth and API-key auth. "kimi-coding" is an
// OAuth-primary managed id and is NOT an admitted API-key/dual-auth connection
// id (see isManagedProviderConnectionId in src/lib/providers/catalog.ts), so
// posting it here 400s with "Invalid provider". The dedicated managed
// API-key id "kimi-coding-apikey" IS admitted — remap only the POST payload
// so the saved connection lands under the correct managed id. The OAuth flow
// (handleOAuthSuccess in ProviderDetailPageClient.tsx) does not go through
// this hook, so it keeps posting "kimi-coding" unchanged.
export function resolveApiKeySaveProviderId(providerId: string): string {
return providerId === "kimi-coding" ? "kimi-coding-apikey" : providerId;
}
export function useApiKeySave({
providerId,
fetchConnections,
@@ -48,7 +61,10 @@ export function useApiKeySave({
const res = await fetch("/api/providers", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ provider: providerId, ...formData }),
body: JSON.stringify({
provider: resolveApiKeySaveProviderId(providerId),
...formData,
}),
});
if (res.ok) {
const connectionData = await res.json();

View File

@@ -1,381 +0,0 @@
"use client";
import { useCallback, useEffect, useMemo, useState } from "react";
import Link from "next/link";
import { useTranslations } from "next-intl";
import { Card } from "@/shared/components";
export interface RadarMergedEntry {
provider: string;
modelId: string;
displayName: string;
monthlyTokens: number;
creditTokens: number;
freeType: string;
poolKey: string | null;
tos: string;
trainsOnPrompts?: boolean;
enabled?: boolean;
origin: "baseline" | "radar" | "local";
disabledBy?: "radar";
contextWindow?: number | null;
capabilities?: {
tools: boolean | null;
vision: boolean | null;
thinking: boolean | null;
};
metadataEvidenceUrls?: string[];
budget?: { kind: string; tokensPerMonth?: number; poolId?: string };
limits?: { rpm: number | null; rpd: number | null; tpm: number | null; tpd: number | null };
setup?: { keyUrl: string | null; steps: string[] } | null;
}
interface RadarLocalModelState {
provider: string;
modelId: string;
displayName: string | null;
enabled: boolean | null;
tombstoned: boolean;
updatedAt: string;
}
interface RadarCatalogTableProps {
entries: RadarMergedEntry[];
refreshCatalog: () => Promise<void>;
onError: (message: string) => void;
}
function formatTokens(value: number): string {
if (value === 0) return "rate-only";
if (value >= 1_000_000) return `${(value / 1_000_000).toFixed(1)}M`;
if (value >= 1_000) return `${(value / 1_000).toFixed(0)}K`;
return String(value);
}
function budgetLabel(entry: RadarMergedEntry): string {
if (entry.budget?.kind === "shared_pool") {
return `shared (${formatTokens(entry.budget.tokensPerMonth ?? entry.monthlyTokens)}/mo)`;
}
if (entry.budget?.kind === "rate_only" || entry.monthlyTokens === 0) return "rate-only";
return `${formatTokens(entry.monthlyTokens)}/mo`;
}
function capabilityBadge(label: string, value: boolean | null | undefined, trueClass: string) {
const state = value === true ? "✓" : value === false ? "✕" : "?";
const stateClass =
value === true
? trueClass
: value === false
? "bg-red-500/10 text-red-400"
: "bg-gray-500/10 text-gray-400";
return (
<span className={`text-[10px] px-1.5 py-0.5 rounded ${stateClass}`}>
{label} {state}
</span>
);
}
export function RadarCatalogTable({ entries, refreshCatalog, onError }: RadarCatalogTableProps) {
const t = useTranslations("radarPage");
const [states, setStates] = useState<RadarLocalModelState[]>([]);
const [editingKey, setEditingKey] = useState<string | null>(null);
const [displayName, setDisplayName] = useState("");
const [enabled, setEnabled] = useState(true);
const [saving, setSaving] = useState(false);
const loadState = useCallback(async () => {
try {
const response = await fetch("/api/radar/local-model-state");
if (!response.ok) return;
const payload = await response.json();
setStates(Array.isArray(payload.states) ? payload.states : []);
} catch {
onError(t("errorLoading"));
}
}, [onError, t]);
useEffect(() => {
void loadState();
}, [loadState]);
const stateByKey = useMemo(
() => new Map(states.map((state) => [`${state.provider}:${state.modelId}`, state])),
[states]
);
const hiddenModels = useMemo(() => states.filter((state) => state.tombstoned), [states]);
const applyResponse = useCallback(async (response: Response) => {
if (!response.ok) throw new Error("save_failed");
const payload = await response.json();
setStates(Array.isArray(payload.states) ? payload.states : []);
}, []);
const mutate = useCallback(
async (operation: () => Promise<Response>) => {
setSaving(true);
onError("");
try {
await applyResponse(await operation());
setEditingKey(null);
await refreshCatalog();
} catch {
onError(t("localStateSaveFailed"));
} finally {
setSaving(false);
}
},
[applyResponse, onError, refreshCatalog, t]
);
const beginEdit = useCallback((entry: RadarMergedEntry) => {
setEditingKey(`${entry.provider}:${entry.modelId}`);
setDisplayName(entry.displayName);
setEnabled(entry.enabled !== false);
}, []);
const saveOverride = useCallback(
(entry: RadarMergedEntry) =>
mutate(() =>
fetch("/api/radar/local-model-state", {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
provider: entry.provider,
modelId: entry.modelId,
displayName,
enabled,
}),
})
),
[displayName, enabled, mutate]
);
const resetOverride = useCallback(
(entry: Pick<RadarMergedEntry, "provider" | "modelId">) => {
const query = new URLSearchParams({ provider: entry.provider, modelId: entry.modelId });
return mutate(() =>
fetch(`/api/radar/local-model-state?${query.toString()}`, { method: "DELETE" })
);
},
[mutate]
);
const setTombstone = useCallback(
(provider: string, modelId: string, tombstoned: boolean) =>
mutate(() =>
fetch("/api/radar/local-model-state", {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ provider, modelId, tombstoned }),
})
),
[mutate]
);
return (
<>
<Card>
<div className="overflow-x-auto">
<table className="w-full">
<thead>
<tr className="text-left text-sm text-text-muted border-b border-border">
<th className="pb-3 font-medium">{t("colProvider")}</th>
<th className="pb-3 font-medium">{t("colModel")}</th>
<th className="pb-3 font-medium">{t("colQuota")}</th>
<th className="pb-3 font-medium">{t("colContext")}</th>
<th className="pb-3 font-medium">{t("colCapabilities")}</th>
<th className="pb-3 font-medium">{t("colTos")}</th>
<th className="pb-3 font-medium text-right">{t("colActions")}</th>
</tr>
</thead>
<tbody>
{entries.map((entry) => {
const key = `${entry.provider}:${entry.modelId}`;
const localState = stateByKey.get(key);
const hasOverride =
localState && (localState.displayName !== null || localState.enabled !== null);
return (
<tr
key={key}
className={`border-b border-border/50 last:border-b-0 ${
entry.enabled === false ? "opacity-50" : ""
}`}
>
<td className="py-3">
<div className="flex items-center gap-2">
<span className="font-medium">{entry.provider}</span>
{entry.origin === "radar" && (
<span className="text-[10px] px-1.5 py-0.5 rounded bg-violet-500/10 text-violet-400 font-medium">
{t("newBadge")}
</span>
)}
{entry.origin === "local" && (
<span className="text-[10px] px-1.5 py-0.5 rounded bg-blue-500/10 text-blue-400 font-medium">
{t("localBadge")}
</span>
)}
{entry.setup?.keyUrl && (
<Link
href={`/dashboard/radar/setup?provider=${encodeURIComponent(entry.provider)}`}
className="text-xs text-violet-400 hover:underline"
title={t("setupGuide")}
>
</Link>
)}
</div>
{entry.enabled === false && entry.disabledBy === "radar" && (
<p className="text-xs text-red-400 mt-0.5">{t("disabledByFeed")}</p>
)}
</td>
<td className="py-3 text-text-muted text-sm font-mono max-w-[240px]">
{editingKey === key ? (
<input
type="text"
value={displayName}
onChange={(event) => setDisplayName(event.target.value)}
aria-label={t("modelDisplayName")}
maxLength={160}
className="w-full min-w-[180px] px-2 py-1 rounded border border-border bg-transparent text-text-main focus:outline-none focus:ring-2 focus:ring-violet-500"
/>
) : (
<span className="block truncate">{entry.displayName}</span>
)}
</td>
<td className="py-3 text-sm">{budgetLabel(entry)}</td>
<td className="py-3 text-sm text-text-muted">
{entry.contextWindow ? `${(entry.contextWindow / 1000).toFixed(0)}K` : "—"}
</td>
<td className="py-3">
<div className="flex flex-wrap gap-1">
{capabilityBadge(
t("capTools"),
entry.capabilities?.tools,
"bg-blue-500/10 text-blue-400"
)}
{capabilityBadge(
t("capVision"),
entry.capabilities?.vision,
"bg-purple-500/10 text-purple-400"
)}
{capabilityBadge(
t("capThinking"),
entry.capabilities?.thinking,
"bg-amber-500/10 text-amber-400"
)}
</div>
</td>
<td className="py-3">
<span
className={`text-xs px-2 py-1 rounded ${
entry.tos === "ok"
? "bg-green-500/10 text-green-400"
: entry.tos === "caution"
? "bg-yellow-500/10 text-yellow-400"
: entry.tos === "avoid"
? "bg-red-500/10 text-red-400"
: "bg-gray-500/10 text-gray-400"
}`}
>
{entry.tos}
</span>
</td>
<td className="py-3 pl-3">
{editingKey === key ? (
<div className="flex flex-wrap items-center justify-end gap-2">
<label className="inline-flex items-center gap-1 text-xs text-text-muted">
<input
type="checkbox"
checked={enabled}
disabled={entry.disabledBy === "radar"}
onChange={(event) => setEnabled(event.target.checked)}
/>
{t("modelEnabled")}
</label>
<button
type="button"
disabled={saving || displayName.trim().length === 0}
onClick={() => void saveOverride(entry)}
className="text-xs text-violet-400 hover:underline disabled:opacity-50"
>
{t("saveModel")}
</button>
<button
type="button"
disabled={saving}
onClick={() => setEditingKey(null)}
className="text-xs text-text-muted hover:text-text-main disabled:opacity-50"
>
{t("cancelEdit")}
</button>
</div>
) : (
<div className="flex flex-wrap items-center justify-end gap-2">
<button
type="button"
disabled={saving}
onClick={() => beginEdit(entry)}
className="text-xs text-violet-400 hover:underline disabled:opacity-50"
>
{t("editModel")}
</button>
{hasOverride && (
<button
type="button"
disabled={saving}
onClick={() => void resetOverride(entry)}
className="text-xs text-text-muted hover:text-text-main disabled:opacity-50"
>
{t("resetModel")}
</button>
)}
<button
type="button"
disabled={saving}
onClick={() => void setTombstone(entry.provider, entry.modelId, true)}
className="text-xs text-red-400 hover:underline disabled:opacity-50"
>
{t("hideModel")}
</button>
</div>
)}
</td>
</tr>
);
})}
</tbody>
</table>
</div>
</Card>
{hiddenModels.length > 0 && (
<Card>
<div className="flex flex-col gap-3">
<h3 className="text-sm font-semibold">{t("hiddenModelsTitle")}</h3>
{hiddenModels.map((state) => (
<div
key={`${state.provider}:${state.modelId}:hidden`}
className="flex flex-wrap items-center justify-between gap-3 border-b border-border/50 pb-3 last:border-b-0 last:pb-0"
>
<div>
<span className="font-medium">{state.provider}</span>
<span className="ml-2 text-sm font-mono text-text-muted">
{state.displayName ?? state.modelId}
</span>
</div>
<button
type="button"
disabled={saving}
onClick={() => void setTombstone(state.provider, state.modelId, false)}
className="text-sm text-violet-400 hover:underline disabled:opacity-50"
>
{t("restoreModel")}
</button>
</div>
))}
</div>
</Card>
)}
</>
);
}

View File

@@ -1,201 +0,0 @@
"use client";
import { useCallback, useEffect, useMemo, useState } from "react";
import { useTranslations } from "next-intl";
import Link from "next/link";
import { notFound } from "next/navigation";
import type { ComboBuilderOptionsPayload } from "@/lib/combos/builderOptions";
import type { MergedEntry } from "@/lib/radar/applyFeed";
import {
buildRadarComboSuggestions,
type RadarComboSuggestion,
} from "@/lib/radar/comboSuggestions";
import { Card } from "@/shared/components";
interface RadarCatalogPayload {
entries?: MergedEntry[];
meta?: unknown;
}
function comboNames(payload: ComboBuilderOptionsPayload): Set<string> {
return new Set(payload.comboRefs.map((combo) => combo.name));
}
export default function RadarCombosPage() {
const t = useTranslations("radarCombosPage");
const [entries, setEntries] = useState<MergedEntry[]>([]);
const [providers, setProviders] = useState<ComboBuilderOptionsPayload["providers"]>([]);
const [existingNames, setExistingNames] = useState<Set<string>>(new Set());
const [createdNames, setCreatedNames] = useState<Set<string>>(new Set());
const [hasCatalog, setHasCatalog] = useState(false);
const [flagOff, setFlagOff] = useState(false);
const [loading, setLoading] = useState(true);
const [creatingName, setCreatingName] = useState<string | null>(null);
const [error, setError] = useState("");
useEffect(() => {
async function load() {
try {
const [catalogResponse, optionsResponse] = await Promise.all([
fetch("/api/radar/catalog"),
fetch("/api/combos/builder/options"),
]);
if (catalogResponse.status === 404) {
setFlagOff(true);
return;
}
if (!catalogResponse.ok || !optionsResponse.ok) throw new Error("load_failed");
const catalog = (await catalogResponse.json()) as RadarCatalogPayload;
const options = (await optionsResponse.json()) as ComboBuilderOptionsPayload;
if (!Array.isArray(catalog.entries) || !Array.isArray(options.providers)) {
throw new Error("invalid_shape");
}
setEntries(catalog.entries);
setProviders(options.providers);
setExistingNames(comboNames(options));
setHasCatalog(catalog.meta != null);
} catch {
setError(t("loadFailed"));
} finally {
setLoading(false);
}
}
void load();
}, [t]);
const suggestions = useMemo(
() => buildRadarComboSuggestions({ entries, providers, existingComboNames: existingNames }),
[entries, providers, existingNames]
);
const refreshExistingName = useCallback(async (name: string): Promise<boolean> => {
try {
const response = await fetch("/api/combos/builder/options");
if (!response.ok) return false;
const options = (await response.json()) as ComboBuilderOptionsPayload;
if (!Array.isArray(options.comboRefs)) return false;
const names = comboNames(options);
if (![...names].some((candidate) => candidate.toLowerCase() === name.toLowerCase())) {
return false;
}
setExistingNames(names);
return true;
} catch {
return false;
}
}, []);
const createSuggestion = useCallback(
async (suggestion: RadarComboSuggestion) => {
setCreatingName(suggestion.name);
setError("");
try {
const response = await fetch("/api/combos", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(suggestion.payload),
});
if (!response.ok) {
if (response.status === 400 && (await refreshExistingName(suggestion.name))) return;
throw new Error("create_failed");
}
setExistingNames((current) => new Set([...current, suggestion.name]));
setCreatedNames((current) => new Set([...current, suggestion.name]));
} catch {
setError(t("createFailed"));
} finally {
setCreatingName(null);
}
},
[refreshExistingName, t]
);
if (flagOff) notFound();
return (
<div className="flex flex-col gap-6">
<div className="flex flex-col gap-3">
<Link
href="/dashboard/radar"
className="text-sm text-text-muted hover:text-text-main transition-colors w-fit"
>
{t("backToRadar")}
</Link>
<div>
<h1 className="text-2xl font-bold">{t("title")}</h1>
<p className="text-sm text-text-muted mt-1">{t("subtitle")}</p>
</div>
</div>
{error && <div className="p-3 rounded-lg bg-red-500/10 text-red-400 text-sm">{error}</div>}
{loading ? (
<div className="flex items-center justify-center min-h-[200px] text-text-muted">
{t("loading")}
</div>
) : !hasCatalog ? (
<Card>
<p className="text-center text-text-muted py-8">{t("catalogRequired")}</p>
</Card>
) : suggestions.length === 0 ? (
<Card>
<p className="text-center text-text-muted py-8">{t("noSuggestions")}</p>
</Card>
) : (
<div className="grid gap-4">
{suggestions.map((suggestion) => {
const creating = creatingName === suggestion.name;
const created = createdNames.has(suggestion.name);
return (
<Card key={suggestion.familyId}>
<div className="flex flex-col gap-4">
<div className="flex flex-col gap-1">
<span className="text-xs uppercase tracking-wide text-text-muted">
{t("familyLabel")}
</span>
<h2 className="text-lg font-semibold font-mono">{suggestion.familyId}</h2>
<p className="text-sm text-text-muted">{t("strategyReason")}</p>
</div>
<div className="flex flex-col gap-2">
<span className="text-sm font-medium">{t("modelsLabel")}</span>
{suggestion.models.map((model) => (
<div
key={`${model.providerId}:${model.modelId}`}
className="flex flex-wrap items-center justify-between gap-2 rounded-lg border border-border px-3 py-2"
>
<span className="font-medium">{model.providerName}</span>
<span className="font-mono text-sm text-text-muted">
{model.qualifiedModel}
</span>
</div>
))}
</div>
<button
type="button"
onClick={() => void createSuggestion(suggestion)}
disabled={creating || suggestion.alreadyExists}
className="self-start px-4 py-2 text-sm font-medium rounded-lg bg-violet-500 text-white hover:bg-violet-600 transition-colors disabled:opacity-50"
>
{created
? t("created")
: suggestion.alreadyExists
? t("alreadyCreated")
: creating
? t("generating")
: t("generateButton")}
</button>
</div>
</Card>
);
})}
</div>
)}
</div>
);
}

View File

@@ -1,197 +0,0 @@
"use client";
import { useCallback, useEffect, useState } from "react";
import Link from "next/link";
import { notFound } from "next/navigation";
import { useTranslations } from "next-intl";
import type { RadarIntelFeed } from "@/lib/radar/intelFeedSchema";
import { Card } from "@/shared/components";
interface IntelMeta {
version: string;
tier: "live";
fetchedAt: string;
supporterVerified: true;
}
export default function RadarIntelPage() {
const t = useTranslations("radarIntelPage");
const [intel, setIntel] = useState<RadarIntelFeed | null>(null);
const [meta, setMeta] = useState<IntelMeta | null>(null);
const [loading, setLoading] = useState(true);
const [syncing, setSyncing] = useState(false);
const [flagOff, setFlagOff] = useState(false);
const [error, setError] = useState("");
const load = useCallback(async () => {
const response = await fetch("/api/radar/intel");
if (response.status === 404) {
setFlagOff(true);
return;
}
if (!response.ok) throw new Error("intel_load_failed");
const body = (await response.json()) as {
intel?: RadarIntelFeed | null;
meta?: IntelMeta | null;
};
setIntel(body.intel ?? null);
setMeta(body.meta ?? null);
}, []);
const sync = useCallback(async () => {
setSyncing(true);
setError("");
try {
const response = await fetch("/api/radar/intel/sync", { method: "POST" });
if (response.status === 404) {
setFlagOff(true);
return;
}
if (!response.ok) throw new Error("intel_sync_failed");
const status = (await response.json()) as { status?: string };
if (
["error", "invalid_signature", "invalid_schema", "wrong_tier", "too_large"].includes(
status.status ?? ""
)
) {
setError(t("loadFailed"));
}
await load();
} catch {
setError(t("loadFailed"));
await load().catch(() => undefined);
} finally {
setSyncing(false);
}
}, [load, t]);
useEffect(() => {
load()
.catch(() => setError(t("loadFailed")))
.finally(() => setLoading(false));
}, [load, t]);
if (flagOff) notFound();
return (
<div className="flex flex-col gap-6">
<div className="flex flex-wrap items-start justify-between gap-3">
<div>
<Link
href="/dashboard/radar"
className="text-sm text-text-muted hover:text-text-main transition-colors"
>
{t("backToRadar")}
</Link>
<h1 className="mt-3 text-2xl font-bold">{t("title")}</h1>
<p className="mt-1 text-sm text-text-muted">{t("subtitle")}</p>
</div>
<div className="flex items-center gap-2">
{meta?.supporterVerified === true && (
<span
data-badge-id="radar-supporter"
className="rounded-full border border-violet-500 px-3 py-1 text-sm text-violet-300"
>
{t("supporterBadge")}
</span>
)}
<button
type="button"
onClick={() => void sync()}
disabled={syncing}
className="rounded-lg border border-violet-500 px-4 py-2 text-sm font-medium text-violet-400 disabled:opacity-50"
>
{syncing ? t("syncing") : t("refresh")}
</button>
</div>
</div>
{error && <div className="rounded-lg bg-red-500/10 p-3 text-sm text-red-400">{error}</div>}
{loading ? (
<div className="flex min-h-48 items-center justify-center text-text-muted">
{t("loading")}
</div>
) : !intel || !meta ? (
<Card>
<p className="py-8 text-center text-text-muted">{t("empty")}</p>
</Card>
) : (
<>
<div className="grid gap-4 md:grid-cols-3">
<Card>
<p className="text-xs uppercase tracking-wide text-text-muted">{t("methodology")}</p>
<p className="mt-2 font-semibold">
{t("eloMethod", {
initial: intel.methodology.initialRating,
factor: intel.methodology.kFactor,
})}
</p>
</Card>
<Card>
<p className="text-xs uppercase tracking-wide text-text-muted">{t("freshness")}</p>
<p className="mt-2 font-semibold">
{t(`freshnessValues.${intel.catalog.freshness}`)}
</p>
<p className="mt-1 text-sm text-text-muted">
{t("ageDays", { days: intel.catalog.ageDays })}
</p>
</Card>
<Card>
<p className="text-xs uppercase tracking-wide text-text-muted">{t("trend")}</p>
<p className="mt-2 font-semibold">{t(`trendValues.${intel.catalog.trend}`)}</p>
<p className="mt-1 text-sm text-text-muted">
{t("modelDelta", {
current: intel.catalog.models.current,
added: intel.catalog.models.added,
removed: intel.catalog.models.removed,
})}
</p>
</Card>
</div>
<Card>
<div className="mb-4 flex items-center justify-between gap-3">
<h2 className="text-lg font-semibold">{t("ranking")}</h2>
<span className="text-xs text-text-muted">{meta.version}</span>
</div>
{intel.rankings.length === 0 ? (
<p className="py-6 text-center text-text-muted">{t("noRankings")}</p>
) : (
<div className="overflow-x-auto">
<table className="w-full text-left text-sm">
<thead className="text-text-muted">
<tr>
<th className="pb-3">#</th>
<th className="pb-3">{t("model")}</th>
<th className="pb-3">{t("category")}</th>
<th className="pb-3 text-right">{t("rating")}</th>
<th className="pb-3 text-right">{t("matches")}</th>
</tr>
</thead>
<tbody>
{intel.rankings.map((ranking) => (
<tr
key={`${ranking.category}:${ranking.provider}:${ranking.modelId}`}
className="border-t border-border"
>
<td className="py-3">{ranking.rank}</td>
<td className="py-3 font-mono">
{ranking.provider}/{ranking.modelId}
</td>
<td className="py-3">{ranking.category}</td>
<td className="py-3 text-right">{ranking.rating}</td>
<td className="py-3 text-right">{ranking.matches}</td>
</tr>
))}
</tbody>
</table>
</div>
)}
</Card>
</>
)}
</div>
);
}

View File

@@ -1,273 +0,0 @@
"use client";
import { useCallback, useEffect, useMemo, useState } from "react";
import Link from "next/link";
import { notFound } from "next/navigation";
import { useLocale, useTranslations } from "next-intl";
import {
filterActiveRadarOffers,
localizeRadarOfferText,
type RadarOffer,
type RadarOfferBenefit,
} from "@/lib/radar/offersFeedSchema";
import { Card } from "@/shared/components";
interface OffersMeta {
version: string;
tier: "live";
fetchedAt: string;
}
interface SettingsPayload {
hasSupporterKey?: boolean;
contributorClaimUrl?: string;
supporterPlansUrl?: string;
}
export default function RadarOffersPage() {
const t = useTranslations("radarOffersPage");
const locale = useLocale();
const [offers, setOffers] = useState<RadarOffer[]>([]);
const [meta, setMeta] = useState<OffersMeta | null>(null);
const [hasSupporterKey, setHasSupporterKey] = useState(false);
const [contributorClaimUrl, setContributorClaimUrl] = useState<string | null>(null);
const [supporterPlansUrl, setSupporterPlansUrl] = useState<string | null>(null);
const [loading, setLoading] = useState(true);
const [refreshing, setRefreshing] = useState(false);
const [flagOff, setFlagOff] = useState(false);
const [error, setError] = useState("");
const loadOffers = useCallback(async () => {
const response = await fetch("/api/radar/offers");
if (response.status === 404) {
setFlagOff(true);
return;
}
if (!response.ok) throw new Error("offers_load_failed");
const body = (await response.json()) as { offers?: RadarOffer[]; meta?: OffersMeta | null };
setOffers(Array.isArray(body.offers) ? body.offers : []);
setMeta(body.meta ?? null);
}, []);
const syncAndLoad = useCallback(async () => {
setRefreshing(true);
setError("");
try {
const response = await fetch("/api/radar/offers/sync", { method: "POST" });
if (response.status === 404) {
setFlagOff(true);
return;
}
if (!response.ok) throw new Error("offers_sync_failed");
const status = (await response.json()) as { status?: string; reason?: string };
if (status.status === "no_key") {
setHasSupporterKey(false);
return;
}
if (
status.status === "error" ||
status.status === "invalid_signature" ||
status.status === "invalid_schema" ||
status.status === "wrong_tier" ||
status.status === "too_large"
) {
setError(t("loadFailed"));
}
// Preserve availability: even when refresh fails, render the last
// verified local cache rather than clearing it.
await loadOffers();
} catch {
setError(t("loadFailed"));
try {
await loadOffers();
} catch {
// The primary error already explains the failed local read.
}
} finally {
setRefreshing(false);
}
}, [loadOffers, t]);
useEffect(() => {
async function load(): Promise<void> {
try {
const response = await fetch("/api/radar/settings");
if (response.status === 404) {
setFlagOff(true);
return;
}
if (!response.ok) throw new Error("settings_load_failed");
const settings = (await response.json()) as SettingsPayload;
const hasKey = settings.hasSupporterKey === true;
setHasSupporterKey(hasKey);
setContributorClaimUrl(
typeof settings.contributorClaimUrl === "string" ? settings.contributorClaimUrl : null
);
setSupporterPlansUrl(
typeof settings.supporterPlansUrl === "string" ? settings.supporterPlansUrl : null
);
if (hasKey) await syncAndLoad();
} catch {
setError(t("loadFailed"));
} finally {
setLoading(false);
}
}
void load();
}, [syncAndLoad, t]);
const activeOffers = useMemo(() => filterActiveRadarOffers(offers, new Date()), [offers]);
const formatBenefit = useCallback(
(benefit: RadarOfferBenefit): string => {
if (benefit.kind === "percent_off") {
return `${new Intl.NumberFormat(locale, { maximumFractionDigits: 2 }).format(
benefit.basisPoints / 100
)}%`;
}
if (benefit.kind === "credit") {
return new Intl.NumberFormat(locale, {
style: "currency",
currency: benefit.currency,
}).format(benefit.amountMinor / 100);
}
return t("trialDays", { days: benefit.days });
},
[locale, t]
);
if (flagOff) notFound();
return (
<div className="flex flex-col gap-6">
<div className="flex flex-col gap-3">
<Link
href="/dashboard/radar"
className="text-sm text-text-muted hover:text-text-main transition-colors w-fit"
>
{t("backToRadar")}
</Link>
<div className="flex flex-wrap items-start justify-between gap-3">
<div>
<h1 className="text-2xl font-bold">{t("title")}</h1>
<p className="text-sm text-text-muted mt-1">{t("subtitle")}</p>
</div>
{hasSupporterKey && (
<button
type="button"
onClick={() => void syncAndLoad()}
disabled={refreshing}
className="px-4 py-2 text-sm font-medium rounded-lg border border-violet-500 text-violet-400 hover:bg-violet-500/10 transition-colors disabled:opacity-50"
>
{refreshing ? t("refreshing") : t("refresh")}
</button>
)}
</div>
</div>
{error && <div className="p-3 rounded-lg bg-red-500/10 text-red-400 text-sm">{error}</div>}
{loading ? (
<div className="flex min-h-48 items-center justify-center text-text-muted">
{t("loading")}
</div>
) : !hasSupporterKey ? (
<Card>
<div className="flex flex-col items-center gap-4 py-8 text-center">
<span className="material-symbols-outlined text-4xl text-violet-400">redeem</span>
<h2 className="text-xl font-semibold">{t("keyRequiredTitle")}</h2>
<p className="max-w-xl text-text-muted">{t("keyRequiredDescription")}</p>
<div className="flex flex-col sm:flex-row gap-3">
{contributorClaimUrl && (
<a
href={contributorClaimUrl}
target="_blank"
rel="noopener noreferrer"
className="px-4 py-2 rounded-lg border border-violet-500 text-violet-400 hover:bg-violet-500/10"
>
{t("contributorButton")}
</a>
)}
{supporterPlansUrl && (
<a
href={supporterPlansUrl}
target="_blank"
rel="noopener noreferrer"
className="px-4 py-2 rounded-lg bg-violet-500 text-white hover:bg-violet-600"
>
{t("supporterButton")}
</a>
)}
</div>
</div>
</Card>
) : activeOffers.length === 0 ? (
<Card>
<p className="py-8 text-center text-text-muted">{t("empty")}</p>
</Card>
) : (
<div className="grid gap-4 md:grid-cols-2 xl:grid-cols-3">
{activeOffers.map((offer) => (
<Card key={`${offer.provider}:${offer.id}`}>
<div className="flex h-full flex-col gap-4">
<div className="flex items-start justify-between gap-3">
<div>
<p className="text-xs uppercase tracking-wide text-text-muted">
{offer.provider}
</p>
<h2 className="text-lg font-semibold">
{localizeRadarOfferText(offer.title, locale)}
</h2>
</div>
<span
className={`rounded-full px-2 py-1 text-xs font-medium ${
offer.partner
? "bg-violet-500/15 text-violet-300"
: "bg-green-500/15 text-green-300"
}`}
>
{offer.partner ? t("partnerBadge") : t("officialBadge")}
</span>
</div>
<p className="text-2xl font-bold text-violet-300">{formatBenefit(offer.benefit)}</p>
<p className="text-sm text-text-muted">
{localizeRadarOfferText(offer.description, locale)}
</p>
<div className="text-sm">
<span className="font-medium">{t("conditionsLabel")}</span>{" "}
<span className="text-text-muted">
{localizeRadarOfferText(offer.conditions, locale)}
</span>
</div>
<p className="text-xs text-text-muted">
{offer.validUntil
? t("validUntil", {
date: new Date(offer.validUntil).toLocaleDateString(locale),
})
: t("noExpiry")}
</p>
<a
href={offer.url}
target="_blank"
rel="noopener noreferrer"
className="mt-auto inline-flex w-fit items-center gap-1 text-sm font-medium text-violet-400 hover:underline"
>
{t("openOffer")}
<span className="material-symbols-outlined text-sm">open_in_new</span>
</a>
</div>
</Card>
))}
</div>
)}
{meta && (
<p className="text-xs text-text-muted">
{meta.version} · {new Date(meta.fetchedAt).toLocaleString(locale)}
</p>
)}
</div>
);
}

View File

@@ -2,12 +2,11 @@
import { useState, useEffect, useCallback, useRef } from "react";
import { useTranslations } from "next-intl";
import Link from "next/link";
import { notFound } from "next/navigation";
import Link from "next/link";
import { Card } from "@/shared/components";
import { shouldAutoSyncOnOpen } from "@/lib/radar/autoSync";
import { isValidSupporterKeyFormat } from "@/lib/radar/supporterKey";
import { RadarCatalogTable, type RadarMergedEntry } from "./RadarCatalogTable";
// ---------------------------------------------------------------------------
// Types
@@ -19,6 +18,27 @@ interface RadarMeta {
fetchedAt: string;
}
interface RadarMergedEntry {
provider: string;
modelId: string;
displayName: string;
monthlyTokens: number;
creditTokens: number;
freeType: string;
poolKey: string | null;
tos: string;
trainsOnPrompts?: boolean;
enabled?: boolean;
origin: "baseline" | "radar" | "local";
disabledBy?: "radar";
// Extended feed fields (present when origin=radar)
contextWindow?: number | null;
capabilities?: { tools: boolean; vision: boolean; thinking: boolean };
budget?: { kind: string; tokensPerMonth?: number; poolId?: string };
limits?: { rpm: number | null; rpd: number | null; tpm: number | null; tpd: number | null };
setup?: { keyUrl: string | null; steps: string[] } | null;
}
type PageState = "flag_off" | "optin_pending" | "empty" | "populated";
/** D28 — referral links / free credits. Client-side mirror of RadarReferral. */
@@ -47,7 +67,7 @@ type RadarTabId = "catalog" | "referrals";
export function resolveRadarPageState(
flagOn: boolean,
optedIn: boolean,
hasEntries: boolean
hasEntries: boolean,
): PageState {
if (!flagOn) return "flag_off";
if (!optedIn) return "optin_pending";
@@ -70,6 +90,23 @@ function relativeTime(isoDate: string): string {
return `${days}d ago`;
}
/** Format token count as human-readable. */
function formatTokens(n: number): string {
if (n === 0) return "rate-only";
if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;
if (n >= 1_000) return `${(n / 1_000).toFixed(0)}K`;
return String(n);
}
/** Budget display string. */
function budgetLabel(entry: RadarMergedEntry): string {
if (entry.budget?.kind === "shared_pool") {
return `shared (${formatTokens(entry.budget.tokensPerMonth ?? entry.monthlyTokens)}/mo)`;
}
if (entry.budget?.kind === "rate_only" || entry.monthlyTokens === 0) return "rate-only";
return `${formatTokens(entry.monthlyTokens)}/mo`;
}
// ---------------------------------------------------------------------------
// Page Component
// ---------------------------------------------------------------------------
@@ -107,34 +144,31 @@ export default function RadarPage() {
const [hasSupporterKey, setHasSupporterKey] = useState(false);
const [supporterKeyMasked, setSupporterKeyMasked] = useState<string | null>(null);
const [showKeyForm, setShowKeyForm] = useState(false);
// Fetch catalog
const fetchCatalog = useCallback(
async (showLoading = true) => {
if (showLoading) setLoading(true);
setError("");
try {
const res = await fetch("/api/radar/catalog");
if (res.status === 404) {
// Flag off — treat as not found
setOptIn(false);
setEntries([]);
setMeta(null);
if (showLoading) setLoading(false);
return;
}
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
setEntries(data.entries || []);
setMeta(data.meta || null);
} catch (err) {
setError(err instanceof Error ? err.message : t("errorLoading"));
} finally {
if (showLoading) setLoading(false);
const fetchCatalog = useCallback(async () => {
setLoading(true);
setError("");
try {
const res = await fetch("/api/radar/catalog");
if (res.status === 404) {
// Flag off — treat as not found
setOptIn(false);
setEntries([]);
setMeta(null);
setLoading(false);
return;
}
},
[t]
);
const refreshCatalogSilently = useCallback(() => fetchCatalog(false), [fetchCatalog]);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
setEntries(data.entries || []);
setMeta(data.meta || null);
} catch (err) {
setError(err instanceof Error ? err.message : t("errorLoading"));
} finally {
setLoading(false);
}
}, [t]);
// D28 — fetch the referral links section ("Pegue seus créditos grátis").
// Best-effort: flag off => 404, no cache => empty shape; either way this
@@ -170,7 +204,7 @@ export default function RadarPage() {
setOptIn(settingsData.optIn === true);
setHasSupporterKey(settingsData.hasSupporterKey === true);
setSupporterKeyMasked(
typeof settingsData.supporterKeyMasked === "string" ? settingsData.supporterKeyMasked : null
typeof settingsData.supporterKeyMasked === "string" ? settingsData.supporterKeyMasked : null,
);
// F4/T7 — best-effort: keep whatever we already had if the field is
// absent (older cached response shape), never fall back to a literal.
@@ -300,7 +334,7 @@ export default function RadarPage() {
const pageState = resolveRadarPageState(
optIn !== false, // if we got a 404, optIn=false => flag off
optIn === true,
meta !== null
entries.length > 0 && meta !== null,
);
// Flag off — render not-found
@@ -316,41 +350,15 @@ export default function RadarPage() {
<h1 className="text-2xl font-bold">{t("title")}</h1>
<p className="text-sm text-text-muted mt-1">{t("subtitle")}</p>
</div>
<div className="flex items-center gap-2">
{(pageState === "empty" || pageState === "populated") && (
<Link
href="/dashboard/radar/intel"
className="px-4 py-2 text-sm font-medium rounded-lg border border-border text-text-main hover:border-violet-500 hover:text-violet-400 transition-colors"
>
{t("intel")}
</Link>
)}
{(pageState === "empty" || pageState === "populated") && (
<Link
href="/dashboard/radar/offers"
className="px-4 py-2 text-sm font-medium rounded-lg border border-border text-text-main hover:border-violet-500 hover:text-violet-400 transition-colors"
>
{t("offers")}
</Link>
)}
{(pageState === "empty" || pageState === "populated") && (
<Link
href="/dashboard/radar/combos"
className="px-4 py-2 text-sm font-medium rounded-lg border border-border text-text-main hover:border-violet-500 hover:text-violet-400 transition-colors"
>
{t("guidedCombos")}
</Link>
)}
{pageState === "populated" && (
<button
onClick={handleSync}
disabled={syncing}
className="px-4 py-2 text-sm font-medium rounded-lg border border-violet-500 text-violet-400 hover:bg-violet-500/10 transition-colors disabled:opacity-50"
>
{syncing ? t("syncing") : t("syncNow")}
</button>
)}
</div>
{pageState === "populated" && (
<button
onClick={handleSync}
disabled={syncing}
className="px-4 py-2 text-sm font-medium rounded-lg border border-violet-500 text-violet-400 hover:bg-violet-500/10 transition-colors disabled:opacity-50"
>
{syncing ? t("syncing") : t("syncNow")}
</button>
)}
</div>
{/* Feed freshness header */}
@@ -371,7 +379,9 @@ export default function RadarPage() {
</div>
)}
{error && <div className="p-3 rounded-lg bg-red-500/10 text-red-400 text-sm">{error}</div>}
{error && (
<div className="p-3 rounded-lg bg-red-500/10 text-red-400 text-sm">{error}</div>
)}
{loading ? (
<div className="flex items-center justify-center min-h-[200px]">
@@ -615,11 +625,98 @@ export default function RadarPage() {
{/* Populated catalog table */}
{pageState === "populated" && activeTab === "catalog" && (
<RadarCatalogTable
entries={entries}
refreshCatalog={refreshCatalogSilently}
onError={setError}
/>
<Card>
<div className="overflow-x-auto">
<table className="w-full">
<thead>
<tr className="text-left text-sm text-text-muted border-b border-border">
<th className="pb-3 font-medium">{t("colProvider")}</th>
<th className="pb-3 font-medium">{t("colModel")}</th>
<th className="pb-3 font-medium">{t("colQuota")}</th>
<th className="pb-3 font-medium">{t("colContext")}</th>
<th className="pb-3 font-medium">{t("colCapabilities")}</th>
<th className="pb-3 font-medium">{t("colTos")}</th>
</tr>
</thead>
<tbody>
{entries.map((entry) => (
<tr
key={`${entry.provider}:${entry.modelId}`}
className={`border-b border-border/50 last:border-b-0 ${
entry.enabled === false ? "opacity-50" : ""
}`}
>
<td className="py-3">
<div className="flex items-center gap-2">
<span className="font-medium">{entry.provider}</span>
{entry.origin === "radar" && (
<span className="text-[10px] px-1.5 py-0.5 rounded bg-violet-500/10 text-violet-400 font-medium">
{t("newBadge")}
</span>
)}
{entry.setup?.keyUrl && (
<Link
href={`/dashboard/radar/setup?provider=${encodeURIComponent(entry.provider)}`}
className="text-xs text-violet-400 hover:underline"
title={t("setupGuide")}
>
</Link>
)}
</div>
{entry.enabled === false && entry.disabledBy === "radar" && (
<p className="text-xs text-red-400 mt-0.5">{t("disabledByFeed")}</p>
)}
</td>
<td className="py-3 text-text-muted text-sm font-mono truncate max-w-[200px]">
{entry.displayName}
</td>
<td className="py-3 text-sm">{budgetLabel(entry)}</td>
<td className="py-3 text-sm text-text-muted">
{entry.contextWindow
? `${(entry.contextWindow / 1000).toFixed(0)}K`
: "—"}
</td>
<td className="py-3">
<div className="flex gap-1">
{entry.capabilities?.tools && (
<span className="text-[10px] px-1.5 py-0.5 rounded bg-blue-500/10 text-blue-400">
{t("capTools")}
</span>
)}
{entry.capabilities?.vision && (
<span className="text-[10px] px-1.5 py-0.5 rounded bg-purple-500/10 text-purple-400">
{t("capVision")}
</span>
)}
{entry.capabilities?.thinking && (
<span className="text-[10px] px-1.5 py-0.5 rounded bg-amber-500/10 text-amber-400">
{t("capThinking")}
</span>
)}
</div>
</td>
<td className="py-3">
<span
className={`text-xs px-2 py-1 rounded ${
entry.tos === "ok"
? "bg-green-500/10 text-green-400"
: entry.tos === "caution"
? "bg-yellow-500/10 text-yellow-400"
: entry.tos === "avoid"
? "bg-red-500/10 text-red-400"
: "bg-gray-500/10 text-gray-400"
}`}
>
{entry.tos}
</span>
</td>
</tr>
))}
</tbody>
</table>
</div>
</Card>
)}
</>
)}

View File

@@ -8,7 +8,6 @@ import { Card } from "@/shared/components";
import {
firstProviderConnectionId,
providerConnectionsRequestUrl,
providerSetupConnectionUrl,
type RadarSetupConnection,
} from "@/lib/radar/setupConnections";
import type { RadarLocalizedText } from "@/lib/radar/feedSchema";
@@ -133,13 +132,13 @@ export default function RadarSetupPage() {
headers: { "Content-Type": "application/json" },
body: JSON.stringify({}),
});
const data = await res.json().catch(() => null);
if (res.ok && data?.valid === true) {
if (res.ok) {
setTestResult({ ok: true, message: t("testSuccess") });
} else {
const data = await res.json().catch(() => null);
setTestResult({
ok: false,
message: t("testFailed"),
message: data?.error?.message || t("testFailed"),
});
}
} catch {
@@ -237,6 +236,14 @@ export default function RadarSetupPage() {
<Card>
<div className="text-center py-8 text-text-muted">
<p>{t("noGuide")}</p>
<a
href={`https://${provider}.com`}
target="_blank"
rel="noopener noreferrer"
className="text-violet-400 hover:underline mt-2 inline-block"
>
{t("visitDocs")}
</a>
</div>
</Card>
)}
@@ -269,7 +276,7 @@ export default function RadarSetupPage() {
<h2 className="font-semibold">{t("addConnection")}</h2>
<p className="text-sm text-text-muted">{t("addConnectionDescription")}</p>
<Link
href={providerSetupConnectionUrl(provider)}
href={`/dashboard/providers?add=${encodeURIComponent(provider)}`}
className="text-violet-400 hover:underline text-sm"
>
{t("addConnectionLink")}

View File

@@ -185,7 +185,7 @@ export default function ResilienceConnectionsClient() {
color: "var(--color-warning)",
}}
>
{t("degraded.message", {
{t("degraded", {
sources: data.meta.degraded.map((s) => t(`degraded.source.${s}`)).join(", "),
})}
</div>

View File

@@ -37,7 +37,6 @@ import {
applyItemOrder,
normalizeHiddenSidebarItems,
HIDEABLE_SIDEBAR_ITEM_IDS,
resolveRuntimeSidebarSections,
type HideableSidebarItemId,
type SidebarItemId,
type SidebarSectionId,
@@ -266,9 +265,7 @@ function ItemRow({ item, hiddenSet, onToggleItem, getLabel }: ItemRowProps) {
<span className="material-symbols-outlined text-[16px] text-text-muted/50 shrink-0">
{item.icon}
</span>
<p className="font-medium truncate">
{getLabel(item.i18nKey, item.labelFallback ?? item.id)}
</p>
<p className="font-medium truncate">{getLabel(item.i18nKey, item.id)}</p>
</div>
{isProtected ? (
<span
@@ -330,8 +327,8 @@ function GroupRow({
</span>
</button>
<span className="text-xs text-text-muted/40">
{group.items.filter((i) => !isHideableSidebarItemId(i.id) || !hiddenSet.has(i.id)).length}
/{group.items.length}
{group.items.filter((i) => !isHideableSidebarItemId(i.id) || !hiddenSet.has(i.id)).length}/
{group.items.length}
</span>
{canToggleSeparator && (
<div className="flex items-center gap-2 border-l border-border/60 pl-3">
@@ -352,9 +349,7 @@ function GroupRow({
<span className="material-symbols-outlined text-[14px] text-text-muted/40 shrink-0">
{item.icon}
</span>
<p className="text-sm font-medium truncate">
{getLabel(item.i18nKey, item.labelFallback ?? item.id)}
</p>
<p className="text-sm font-medium truncate">{getLabel(item.i18nKey, item.id)}</p>
</div>
<GroupItemVisibilityControl
item={item}
@@ -396,7 +391,6 @@ export default function SidebarTab() {
const [activePreset, setActivePreset] = useState<SidebarPresetId | null>(null);
const [confirmPreset, setConfirmPreset] = useState<SidebarPresetId | null>(null);
const [showDebug, setShowDebug] = useState(false);
const [radarAdminUrl, setRadarAdminUrl] = useState<unknown>(null);
useEffect(() => {
fetch("/api/settings")
@@ -418,7 +412,6 @@ export default function SidebarTab() {
);
setActivePreset(data?.[SIDEBAR_PRESET_KEY] ?? null);
setShowDebug(data?.debugMode === true);
setRadarAdminUrl(data?.radarAdminUrl ?? null);
setLoading(false);
})
.catch(() => setLoading(false));
@@ -465,9 +458,9 @@ export default function SidebarTab() {
patch({ [HIDDEN_SIDEBAR_GROUP_LABELS_SETTING_KEY]: next, [SIDEBAR_PRESET_KEY]: null });
};
const visibleSections = resolveRuntimeSidebarSections(SIDEBAR_SECTIONS, {
radarAdminUrl,
}).filter((s) => s.visibility !== "debug" || showDebug);
const visibleSections = SIDEBAR_SECTIONS.filter(
(s) => s.visibility !== "debug" || showDebug
);
const orderedSections = applySectionOrder(visibleSections, sectionOrder).map((s) => ({
...s,

View File

@@ -4,7 +4,6 @@ import { getSettings } from "@/lib/localDb";
import HomePageClient from "../dashboard/HomePageClient";
import BootstrapBanner from "../dashboard/BootstrapBanner";
import KimiSponsorBanner from "../dashboard/KimiSponsorBanner";
import NewsBanner from "../dashboard/NewsBanner";
export const dynamic = "force-dynamic";
@@ -19,7 +18,6 @@ export default async function HomePage() {
<>
{isBootstrapped && <BootstrapBanner />}
<KimiSponsorBanner />
<NewsBanner />
<HomePageClient machineId={machineId} />
</>
);

Some files were not shown because too many files have changed in this diff Show More