Compare commits

..

38 Commits

Author SHA1 Message Date
Xiangzhe
d2d2598a0d Merge remote-tracking branch 'origin/release/v3.8.50' into fix/radar-oss-cumulative-integration 2026-08-14 21:00:01 -03:00
Diego Rodrigues de Sa e Souza
e05ac345da feat(sse): honor provider-rule lock scope for agentrouter (connection vs model) (#10419)
Makes the ProviderErrorRule `scope` field real at the persistence layer, exclusively for agentrouter (owner decision; every other provider keeps byte-identical behavior).

checkFallbackError now surfaces `ruleScope` behind the HONORS_RULE_LOCK_SCOPE_PROVIDERS allowlist, and the agentrouter 403 path consults the rules before the generic apikey-FORBIDDEN early-return. markAccountUnavailable honors scope "connection" with a temporary connection cooldown instead of a per-model lockout — guarded so a permanent state can never be downgraded to a transient retry loop — and combo now skips the exhausted account within the same request, which also stops force-reusing the just-cooled connection via allowRateLimitedConnection.

Documented in RESILIENCE_GUIDE §7 with the honest limits (disableCooling connections keep per-model behavior; the 6h model-access cooldown is clamped by mlSettings.maxCooldownMs, 30min by default; same-request skip needs targets carrying their own connectionId).

Closes #10334
2026-08-14 20:52:53 -03:00
Xiangzhe
dfcf6086a2 fix(radar): close cumulative quality regressions 2026-08-14 19:47:07 -03:00
Xiangzhe
6233ca6642 test(radar): seed guided setup E2E timing 2026-08-14 19:08:50 -03:00
Xiangzhe
45a4358b61 docs: sync measured Radar integration counts 2026-08-14 18:54:08 -03:00
Xiangzhe
6cad6314b5 Merge remote-tracking branch 'origin/release/v3.8.50' into fix/radar-oss-cumulative-integration 2026-08-14 18:48:20 -03:00
Diego Rodrigues de Sa e Souza
7bb3bc7e32 fix(ci): pin Build (advisory) to a hosted runner with memory provisioning (#10408)
* fix(ci): pin Build (advisory) to a hosted runner with memory provisioning

`Build (advisory)` has been reporting a permanent red on every PR while
producing no usable signal at all.

Measured over the last 25 quality.yml runs (2026-08-14): not one instance of
the job 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 for over 2 hours and was still unclaimed — or, when it did land
on a runner, killed mid-build by this workflow's own cancel-in-progress
concurrency. All 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. The job was consuming a runner the real gates compete for while
telling every PR author it was broken.

Gap 19 deliberately 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 of its last 25 runs in ~15 min. The difference is memory PROVISIONING, not
the machine: a 10 GB swapfile plus a 12 GB V8 heap. Swap is the part that
matters, because --max-old-space-size bounds only V8's JS heap and never
Turbopack's native Rust allocation (#6409).

Pins the job to ubuntu-latest and mirrors both settings from build.yml.
USE_VPS_RUNNER keeps its other consumers (ci.yml Build, nightly-release-green,
npm-publish), so the variable stays meaningful. Fork safety is strictly
improved: no PR can reach the LAN runner through this job any more.

check:workflows --ratchet: 186 zizmor findings, baseline 190, no regression.
prettier + YAML parse: clean.

* fix(ci): scope Build (advisory) to fork PRs

Follow-up to the hosted-runner pin in this same PR, after measuring what the
job is actually for.

build.yml's `Fast Production Build` triggers on `push: branches: ["**"]` and
runs `build:release` — a superset of this job's `npm run build`, plus the CLI
bundle. For an own-origin branch that push fires here, so the tree was being
built twice per PR. A fork contributor pushes to THEIR repo, so build.yml
never runs in this repo and this job is their only pre-merge build signal.

That could have argued for deleting the job, except the traffic says
otherwise: 72 of the last 100 PRs into release/** come from forks. The fork
case is the majority, not the exception. So the job earns its place — it just
should not duplicate build.yml for the own-origin 28%. Added the fork filter
to the existing `if`.

Also corrects the reliability claim in the previous commit message. Over a
wider window the job is not literally never-green: across 2026-08-13/14 it
reached `success` on roughly 10-15% of runs (13/138 on 08-14, 7/53 sampled on
08-13). Chronically unreliable, not permanently dead — the conclusion and the
fix are unchanged.

The #7307 guard in tests/unit/build/check-workflows.test.ts pinned the old
self-hosted expression, so it is realigned here: it now asserts the hosted
pin, the absence of self-hosted/USE_VPS_RUNNER in the job's DIRECTIVES (the
comment legitimately explains why the pool was abandoned, so the scan strips
comments), both memory settings, and the fork filter. Mutation-validated —
restoring self-hosted, dropping the swapfile, or flipping the fork filter each
turns it red.

check-workflows.test.ts: 32 pass, 0 fail.
check:workflows --ratchet: 186 findings, baseline 190, no regression.

---------

Co-authored-by: Xiangzhe <bakryun0718@proton.me>
2026-08-14 17:27:45 -03:00
Diego Rodrigues de Sa e Souza
8d1a59771a fix(providers): refresh the translate-path golden for the bailian Token Plan endpoint (#10410)
#10290 moved bailian-coding-plan from the Coding Plan host to the documented
Token Plan one, but the provider/translate-path golden still pinned
coding-intl.dashscope.aliyuncs.com, so tests/unit/provider-translate-path-golden.test.ts
fails on the release tip.

Regenerates the snapshot (UPDATE_GOLDEN=1) — the diff is exactly the two
bailian-coding-plan URLs, every other provider byte-identical — and fixes the
same stale host in the endpoint matrix of
docs/providers/ALIBABA-QWEN-PROVIDER-FAMILIES.md.

This golden covers every provider's resolved URL, which is why neither the
focused tests nor typecheck caught the change: only the unit shard runs it.

Refs #9603

Co-authored-by: Xiangzhe <bakryun0718@proton.me>
2026-08-14 16:52:00 -03:00
Xiangzhe
bac3b4eb37 Merge remote-tracking branch 'origin/release/v3.8.50' into fix/radar-oss-cumulative-integration 2026-08-14 15:44:57 -03:00
Diego Rodrigues de Sa e Souza
abd4df63dc fix(sse): surface Qwen/Alibaba personal Token Plan quota in dashboard and preflight (#10290)
* fix(sse): surface Qwen/Alibaba personal Token Plan quota in dashboard and preflight

The personal Token Plan (5-hour / 7-day sliding windows) has no official
OpenAPI and the inference API key cannot read it. Add a cookie-authenticated
fetcher for the console gateway shared by home.qwencloud.com and the Model
Studio console (contract captured live from a logged-in session):

- open-sse/services/qwenTokenPlanQuotaFetcher.ts: POST /data/api.json
  (IntlBroadScopeAspnGateway / sfm_bailian) for usage + quota-config +
  subscription; sec_token resolved best-effort from the dashboard HTML;
  per-window parse (fields are omitted while a window is Temporarily
  Removed); 60s usage cache, 1h tier cache.
- usage/qwen-token-plan.ts leaf + registration in the usage dispatcher,
  USAGE_FETCHER_PROVIDERS, USAGE_SUPPORTED_PROVIDERS,
  PROVIDER_LIMITS_APIKEY_PROVIDERS and bespoke preflight/monitor windows.
- Also adds bailian-coding-plan to USAGE_SUPPORTED_PROVIDERS /
  PROVIDER_LIMITS_APIKEY_PROVIDERS: the coding-plan fetcher existed but the
  dashboard filtered those connections out (UI gap).

Refs #9603 (Problema 1 — quota missing; the 429 recovery half is a
follow-up).

* docs(env): document Qwen Token Plan quota env vars + regen omni-settings skill

QWEN_CLOUD_COOKIE, QWEN_CLOUD_SEC_TOKEN, QWEN_TOKEN_PLAN_HOST and
QWEN_TOKEN_PLAN_DASHBOARD_URL added to .env.example and
docs/reference/ENVIRONMENT.md (check:env-doc-sync), with the generated
omni-settings skill refreshed (check:agent-skills-sync).

Refs #9603

* revert: keep hand-tuned omni-settings thinking-budget section

The agent-skills-sync drift predates this PR (hand improvement from #10169
not yet synced into the generator source) — it fails on every open PR and
belongs to a base-reds fix, not this branch. Regenerating here would erase
the intentional content.

* feat(dashboard): add the Qwen/Model Studio console cookie field to the connection modal

The Token Plan quota fetcher is cookie-authenticated (the inference API key
cannot read the console gateway), but no modal field existed to paste that
cookie — so the quota was unconfigurable from the dashboard and the fetcher
could only ever return its 'needs a cookie' message.

Adds the field for qwen-cloud-token-plan and bailian-coding-plan alongside the
existing ollama-cloud / alibaba console-cookie inputs (same password-input,
blank-keeps-stored semantics), pre-fills it when editing a connection, and
extends the providerSpecificData string/length validation to the two new keys.

Tests: tests/unit/qwen-token-plan-cookie-field.test.ts (RED before, GREEN
after) covers persistence + trimming, the blank-input no-overwrite rule and
schema acceptance/rejection.

Refs #9603

* docs(dashboard): correct the Qwen console cookie instructions

The placeholder claimed the cookie looks like 'token=...'; the qwencloud
portal actually issues 'login_qwencloud_ticket=...' alongside cna/cnaui/aui
(mirroring login_aliyunid_ticket on the Alibaba console), so the hint pointed
at the wrong value.

Replaces the guesswork with the verified retrieval steps in all three places
an operator can hit — the modal field hint, the fetcher's 'needs a cookie'
message and .env.example/ENVIRONMENT.md: log in to home.qwencloud.com >
Billing > Subscription, F12 > Network, reload, filter by api.json, click a
request to cs-data.qwencloud.com and copy the WHOLE Cookie request header.
Also documents that the value must go on one line (it contains '=' and ';')
and that it dies with the browser session.

Refs #9603

* fix(dashboard): tolerate partial form objects in the qwen cookie branch

Adding bailian-coding-plan to QWEN_TOKEN_PLAN_PROVIDERS routed callers that
previously matched NO branch in assignQuotaScrapingProviderData into the new
one, which assumed the two new fields are always present. Older callers build
a partial form object, so buildAddProviderSpecificData threw:

  TypeError: Cannot read properties of undefined (reading 'trim')
  (tests/unit/dashboard/agentrouter-connection-modal-fields.test.ts)

Reads the new fields with optional chaining and adds a regression test that
calls the helper with those keys deleted for both providers.

Refs #9603

* refactor(dashboard): move quota-scraping form logic into a UI-free module

tests/unit/qwen-token-plan-cookie-field.test.ts imported QuotaScrapingFields
directly, which pulls `@/shared/components` and, through that barrel,
untranspiled ESM (@lobehub/icons). The node:test runner cannot parse it and
the whole test file died in CI with:

  SyntaxError: Unexpected token 'export'
    at @lobehub/icons/es/Ai21/components/Mono.js

(It passed locally, so only the CI shard surfaced it.)

Extracts the pure pieces — QWEN_TOKEN_PLAN_PROVIDERS, QuotaScrapingFieldValues,
EMPTY_QUOTA_SCRAPING_FIELDS and assignQuotaScrapingProviderData — into
quotaScrapingFieldValues.ts. The component imports them and re-exports the
public names, so every existing importer keeps its current path. The unit test
now targets the UI-free module.

Refs #9603

* fix(providers): point bailian-coding-plan at the Token Plan endpoint and its console

Two independent defects kept this provider unusable with a valid Alibaba
Token Plan key (verified live 2026-08-14 with the owner's key and cookie):

1. Wrong inference host. The catalog entry is named "Alibaba Token Plan",
   links to token-plan-overview and its hint asks for a Token Plan key, but
   the registry pointed at coding-intl.dashscope.aliyuncs.com — the Coding
   Plan host, which rejects Token Plan keys with 401 invalid_api_key. The
   documented Anthropic base URL for Token Plan is
   token-plan.ap-southeast-1.maas.aliyuncs.com/apps/anthropic
   (https://www.alibabacloud.com/help/en/model-studio/more-tools). Against
   the new host the same key returns 200 for all six registry models and a
   real completion; auth stays on x-api-key.

2. Wrong console identity for quota. The personal Token Plan is sold through
   two consoles sharing one backend, and the gateway validates the session
   against the console declared in the request: an Alibaba console cookie
   (login_aliyunid_ticket) sent with the QwenCloud identity is refused with
   BailianGateway.Login.NotLogined. resolveConsoleSite() now picks host,
   cornerstoneParam.consoleSite/domain and Origin/Referer from the cookie's
   login ticket, falling back to the provider. With that switch the same
   cookie returns usage/subscription/quota-config.

Also routes bailian-coding-plan quota through the Token Plan fetcher (the
Coding Plan call returns "Bad Request" for these accounts), keeping the old
fetcher as the fallback for real Coding Plan keys, and labels the plan by
console ("Alibaba Token Plan (Pro)" vs "Qwen …").

Live validation: inference 200 (qwen3.7-plus answered "FUNCIONA"); quota
12,934/40,000 credits, 67.7% remaining, resets 2026-08-20.

Refs #9603

---------

Co-authored-by: Xiangzhe <bakryun0718@proton.me>
2026-08-14 15:40:33 -03:00
Xiangzhe
7580feb1bf Merge remote-tracking branch 'origin/release/v3.8.50' into fix/radar-oss-cumulative-integration 2026-08-14 12:22:42 -03:00
Xiangzhe
be04c7aecb fix(radar): reconcile cumulative release integration 2026-08-14 12:21:43 -03:00
Xiangzhe
834e53b95b docs(radar): explain supporter key recovery 2026-08-14 11:02:37 -03:00
Xiangzhe
da148eddb7 docs(radar): document end-to-end activation 2026-08-14 11:02:36 -03:00
backryun
3784c35b29 fix(radar): validate aggregate sync body 2026-08-14 11:02:35 -03:00
backryun
74f146a7d4 feat(radar): surface verified model metadata 2026-08-14 11:02:34 -03:00
backryun
2256057f4a feat(radar): add owner-only admin link 2026-08-14 11:02:29 -03:00
backryun
b314b1b112 test(radar): move D12 guard out of OSS 2026-08-14 11:01:49 -03:00
backryun
b334d2d05a feat(radar): complete guided provider setup 2026-08-14 11:01:48 -03:00
diegosouzapw
baa68bfc06 docs(changelog): add Radar launch news fragment 2026-08-14 11:01:26 -03:00
diegosouzapw
d0aff219f5 feat(radar): prepare launch news surface 2026-08-14 11:01:25 -03:00
diegosouzapw
6f48ac4bfe docs(changelog): add Radar Intel fragment 2026-08-14 11:00:13 -03:00
diegosouzapw
e80ac605bc docs(radar): document Intel and CLI contract 2026-08-14 11:00:13 -03:00
diegosouzapw
1a55b20963 feat(cli): add Radar status and sync commands 2026-08-14 11:00:13 -03:00
diegosouzapw
a45076fa2a feat(radar): recognize supporters and add Intel UI 2026-08-14 11:00:12 -03:00
diegosouzapw
7859c843de feat(radar): sync signed Intel insights 2026-08-14 10:59:42 -03:00
diegosouzapw
b8a6557449 docs(changelog): record Radar supporter offers 2026-08-14 10:59:41 -03:00
diegosouzapw
fa7bf4df7b docs(radar): format offers route table 2026-08-14 10:59:41 -03:00
diegosouzapw
f806740a2f feat(radar): add supporter offers dashboard 2026-08-14 10:59:37 -03:00
diegosouzapw
e2e589c79c feat(radar): sync signed supporter offers 2026-08-14 10:58:11 -03:00
diegosouzapw
b11d55332b docs(changelog): record Radar guided combos 2026-08-14 10:58:11 -03:00
diegosouzapw
ee6695acad refactor(mcp): modularize Radar catalog tool 2026-08-14 10:58:10 -03:00
diegosouzapw
b6bba896b3 docs(radar): document guided combos and MCP 2026-08-14 10:58:09 -03:00
diegosouzapw
ea95cc2937 feat(mcp): expose Radar catalog tool 2026-08-14 10:52:20 -03:00
diegosouzapw
a801abc8e9 feat(radar): add guided combos page 2026-08-14 10:52:14 -03:00
diegosouzapw
86caa94baa feat(radar): build guided combo suggestions 2026-08-14 10:48:50 -03:00
diegosouzapw
2ebab9c686 docs(changelog): add Radar local state entry 2026-08-14 10:48:50 -03:00
diegosouzapw
340edbc997 feat(radar): persist local catalog state 2026-08-14 10:48:48 -03:00
244 changed files with 14109 additions and 1924 deletions

View File

@@ -2040,6 +2040,22 @@ APP_LOG_TO_FILE=true
# ALIBABA_CODING_PLAN_HOST= # ALIBABA_CODING_PLAN_HOST=
# ALIBABA_CODING_PLAN_QUOTA_URL= # ALIBABA_CODING_PLAN_QUOTA_URL=
# ── Qwen Cloud / Model Studio personal Token Plan quota ──
# Cookie-authenticated console-gateway fetcher (issue #9603). Used by:
# open-sse/services/qwenTokenPlanQuotaFetcher.ts. Prefer the per-connection
# Dashboard fields (qwenCloudCookie / qwenCloudSecToken) — these env vars are
# global fallbacks. Cookie/sec_token are SENSITIVE session credentials.
# Getting the cookie: log in to home.qwencloud.com > Billing > Subscription,
# press F12 > Network, reload, filter by api.json, click any request to
# cs-data.qwencloud.com and copy the WHOLE Cookie value from Request Headers
# (it contains login_qwencloud_ticket). Paste it on ONE line — the value may
# contain '=' and ';'. It expires with the browser session; re-paste it when
# the dashboard reports an expired session.
# QWEN_CLOUD_COOKIE=
# QWEN_CLOUD_SEC_TOKEN=
# QWEN_TOKEN_PLAN_HOST=
# QWEN_TOKEN_PLAN_DASHBOARD_URL=
# ── Alibaba Model Studio free-tier quota sync ── # ── Alibaba Model Studio free-tier quota sync ──
# Console front-end path overrides for the free-tier quota fetcher. Used by: # Console front-end path overrides for the free-tier quota fetcher. Used by:
# open-sse/services/alibabaFreeTierQuotaFetcher.ts. When unset, the fetcher # open-sse/services/alibabaFreeTierQuotaFetcher.ts. When unset, the fetcher
@@ -2636,9 +2652,9 @@ QUOTA_STORE_DRIVER=sqlite
# ═══════════════════════════════════════════════════════════════════════════════ # ═══════════════════════════════════════════════════════════════════════════════
# Optional add-on (feature flag RADAR_ENABLED, default off — see feature flag # 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 # settings, not an env var) that overlays a signed, freshly-curated free-model
# catalog on top of the release baseline. All four variables below are optional # catalog on top of the release baseline. The first four variables below are
# and only needed to point the client at a self-hosted/forked feed or # optional overrides for a self-hosted/forked feed or supporter-key flow. The
# supporter-key flow instead of the default OmniRoute Radar service. Used by: # fifth is an optional, default-free link to the owner's private operations panel. Used by:
# src/lib/radar/sync.ts, src/lib/radar/pinnedKeys.ts, src/lib/radar/links.ts. # 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 # Base URL of the Radar feed service. Overrides the built-in default so forks
@@ -2659,6 +2675,11 @@ QUOTA_STORE_DRIVER=sqlite
# page). No pricing/value lives in this repo — only the link. # page). No pricing/value lives in this repo — only the link.
# RADAR_SUPPORTER_PLANS_URL=https://radar.omniroute.online/planos # 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 # 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` - [ ] `npm run lint`
- [ ] Reconciled with the current active release base; focused checks rerun afterward - [ ] Reconciled with the current active release base; focused checks rerun afterward
- [ ] Production-code changes include a new or updated automated test in this PR - [ ] Production-code changes include a new or updated automated test in this PR
- [ ] SonarQube PR analysis is green or any remaining issues are explicitly documented below - SonarQube is temporarily opt-in while the private project has no quota; it is not a PR gate.
## Tests Added Or Updated ## Tests Added Or Updated

View File

@@ -998,7 +998,10 @@ jobs:
name: SonarQube name: SonarQube
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: test-coverage needs: test-coverage
if: ${{ !cancelled() && needs.test-coverage.result == 'success' }} # 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' }}
env: env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
@@ -1397,7 +1400,7 @@ jobs:
echo "| i18n UI Coverage | $(status '${{ needs.i18n-ui-coverage.result }}') |" >> "$GITHUB_STEP_SUMMARY" 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 "| 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 "| PR Test Policy | $(status '${{ needs.pr-test-policy.result }}') |" >> "$GITHUB_STEP_SUMMARY"
echo "| SonarQube | $(status '${{ needs.sonarqube.result }}') |" >> "$GITHUB_STEP_SUMMARY" echo "| SonarQube (opt-in; disabled without SONARQUBE_ENABLED=true) | $(status '${{ needs.sonarqube.result }}') |" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY" echo "" >> "$GITHUB_STEP_SUMMARY"
echo "## 🏗️ Build" >> "$GITHUB_STEP_SUMMARY" echo "## 🏗️ Build" >> "$GITHUB_STEP_SUMMARY"

View File

@@ -372,7 +372,7 @@ jobs:
- name: Upload Trivy SARIF to Security tab - name: Upload Trivy SARIF to Security tab
if: needs.prepare.outputs.version != 'main' if: needs.prepare.outputs.version != 'main'
continue-on-error: true continue-on-error: true
uses: github/codeql-action/upload-sarif@v4.37.6 uses: github/codeql-action/upload-sarif@v4.37.4
with: with:
sarif_file: trivy-results.sarif sarif_file: trivy-results.sarif
category: trivy-image category: trivy-image

View File

@@ -60,13 +60,49 @@ jobs:
build: build:
name: Build (advisory) name: Build (advisory)
needs: changes needs: changes
if: ${{ github.event_name != 'pull_request' || ((github.event.pull_request.draft == false || startsWith(github.head_ref, 'mergify/merge-queue/')) && needs.changes.outputs.code == 'true') }} # FORK PRs ONLY. build.yml's `Fast Production Build` triggers on `push: branches: ["**"]`
# Dynamic runner — same fork-safe rule as ci.yml / fast-gates. # and runs `build:release` — a superset of this job — so for an own-origin branch this job
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' }} # 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
# #7307: advisory for the first week of release-PR runs; remove # #7307: advisory for the first week of release-PR runs; remove
# continue-on-error after the production-build signal is stable. # continue-on-error after the production-build signal is stable.
continue-on-error: true continue-on-error: true
steps: 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 - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with: with:
persist-credentials: false persist-credentials: false
@@ -79,6 +115,10 @@ jobs:
- run: npm run build - run: npm run build
env: env:
OMNIROUTE_USE_TURBOPACK: "1" 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 # No artifact upload here: the PR-to-release quality workflow has no
# downstream package/e2e jobs that consume the Next.js build output. # 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. **OmniRoute** — unified AI proxy/router. One endpoint, 339 LLM providers, auto-fallback.
| Layer | Location | Purpose | | Layer | Location | Purpose |
| ------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | | ------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| API Routes | `src/app/api/v1/` | Next.js App Router — entry points | | API Routes | `src/app/api/v1/` | Next.js App Router — entry points |
| Handlers | `open-sse/handlers/` | Request processing (chat, embeddings, etc) | | Handlers | `open-sse/handlers/` | Request processing (chat, embeddings, etc) |
| Executors | `open-sse/executors/` | Provider-specific HTTP dispatch | | Executors | `open-sse/executors/` | Provider-specific HTTP dispatch |
| Translators | `open-sse/translator/` | Format conversion (OpenAI↔Claude↔Gemini) | | Translators | `open-sse/translator/` | Format conversion (OpenAI↔Claude↔Gemini) |
| Transformer | `open-sse/transformer/` | Responses API ↔ Chat Completions | | Transformer | `open-sse/transformer/` | Responses API ↔ Chat Completions |
| Services | `open-sse/services/` | Combo routing, rate limits, caching, etc | | Services | `open-sse/services/` | Combo routing, rate limits, caching, etc |
| Database | `src/lib/db/` | SQLite domain modules (145 migrations) | | Database | `src/lib/db/` | SQLite domain modules (148 migrations) |
| Domain/Policy | `src/domain/` | Policy engine, cost rules, fallback logic | | 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 | | 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 | | A2A Server | `src/lib/a2a/` | JSON-RPC 2.0 agent protocol |
| Skills | `src/lib/skills/` | Extensible skill framework | | Skills | `src/lib/skills/` | Extensible skill framework |
| Memory | `src/lib/memory/` | Persistent conversational memory | | 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). 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 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 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 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 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 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. `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> </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 105 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 109 tools, A2A, memory, guardrails, evals — 25,000+ tests)."/>
<br/> <br/>
<br/> <br/>
@@ -461,7 +461,7 @@ All **19** strategies — mix & match per combo step:
</div> </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 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."/> <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."/>
<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> <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,6 +513,25 @@ Pix copia-e-cola:
<br/> <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"> <div align="center">
## ✨ What's New ## ✨ What's New
@@ -748,7 +767,7 @@ Expose OmniRoute over **MCP**, **A2A**, a **REST API**, **webhooks** or a **remo
<table> <table>
<tr><th align="left">Interface</th><th align="left">Endpoint / command</th><th align="left">Use it for</th></tr> <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 (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>105 tools</b>, 31 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>109 tools</b>, 33 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>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>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> <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>
@@ -1061,7 +1080,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>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>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>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) — 95 domain modules, 145 migrations</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>Memory</b></td><td>SQLite FTS5 full-text + int8-quantized vector embeddings, typed decay</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>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> <tr><td nowrap><b>Protocols</b></td><td>MCP (stdio / HTTP / SSE) + A2A v0.3 (JSON-RPC 2.0 + SSE)</td></tr>
@@ -1135,7 +1154,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><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/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="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>105 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>109 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="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="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> <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

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

View File

@@ -921,6 +921,11 @@
"model": "Filter by model" "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": { "resilience": {
"description": "Inspect and manage resilience mechanisms", "description": "Inspect and manage resilience mechanisms",
"status": { "status": {

View File

@@ -918,6 +918,11 @@
"model": "Filtrar por model" "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": { "resilience": {
"description": "Inspecionar e gerenciar mecanismos de resiliência", "description": "Inspecionar e gerenciar mecanismos de resiliência",
"status": { "status": {

View File

@@ -0,0 +1 @@
- **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

@@ -0,0 +1 @@
- **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

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

View File

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

View File

@@ -0,0 +1 @@
- **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(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,6 +27,7 @@
"providers-bailian-coding-plan.spec.ts": 240, "providers-bailian-coding-plan.spec.ts": 240,
"providers-management.spec.ts": 324, "providers-management.spec.ts": 324,
"proxy-registry.smoke.spec.ts": 218, "proxy-registry.smoke.spec.ts": 218,
"radar-guided-setup.spec.ts": 177,
"resilience-plan-alignment.spec.ts": 382, "resilience-plan-alignment.spec.ts": 382,
"responsive.spec.ts": 21, "responsive.spec.ts": 21,
"search-tools-studio.spec.ts": 133, "search-tools-studio.spec.ts": 133,

View File

@@ -205,10 +205,10 @@ Runs on pull requests only.
Runs after `build`. Blocks merge on failure. Runs after `build`. Blocks merge on failure.
| Suite | Validates | Blocking | | Suite | Validates | Blocking |
| ---------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | | ---------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| `test:vitest` | MCP server (105 tools), autoCombo, cache — vitest runner | Yes | | `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 | | `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) ### Nightly workflows (scheduled, advisory)

View File

@@ -102,7 +102,7 @@ OmniRoute/
| **.gitleaks.toml** | gitleaks secret-scan ruleset | | **.gitleaks.toml** | gitleaks secret-scan ruleset |
| **.zizmor.yml** | zizmor GitHub-Actions security-lint config | | **.zizmor.yml** | zizmor GitHub-Actions security-lint config |
| **socket.yml** | Socket.dev supply-chain config | | **socket.yml** | Socket.dev supply-chain config |
| **news.json** | In-app release-notes feed (read by `src/shared/utils/releaseNotes.ts`) | | **news.json** | Localized v2 announcement feed; Radar launch item ships inactive |
| **flake.nix** / **flake.lock** | Nix dev-shell definition + lock | | **flake.nix** / **flake.lock** | Nix dev-shell definition + lock |
| **.env** | Local secrets (gitignored — generated from `.env.example`) | | **.env** | Local secrets (gitignored — generated from `.env.example`) |
@@ -182,7 +182,7 @@ src/
| `compliance/` | Audit log + provider audit — see `docs/security/COMPLIANCE.md` | | `compliance/` | Audit log + provider audit — see `docs/security/COMPLIANCE.md` |
| `compression/` | Compression engine glue (engines live in `open-sse/services/compression/`) | | `compression/` | Compression engine glue (engines live in `open-sse/services/compression/`) |
| `config/` | Runtime config helpers | | `config/` | Runtime config helpers |
| `db/` | 95+ domain DB modules + 144 migrations (always go through here for SQLite) | | `db/` | 95+ domain DB modules + 148 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` | | `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` | | `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.) | | `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/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) | | `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 | | `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 | | `plugins/` | Plugin registry |
| `promptCache/` | Anthropic-style prompt cache breakpoints | | `promptCache/` | Anthropic-style prompt cache breakpoints |
| `skills/` | Skills framework (built-in + marketplace + SkillsSH) — see `docs/frameworks/SKILLS.md` | | `skills/` | Skills framework (built-in + marketplace + SkillsSH) — see `docs/frameworks/SKILLS.md` |
@@ -209,7 +209,7 @@ src/
| `cacheLayer.ts`, `idempotencyLayer.ts` | Request caching + idempotency | | `cacheLayer.ts`, `idempotencyLayer.ts` | Request caching + idempotency |
| (~30 more top-level files) | Specialized helpers (logEnv, modelsDevSync, piiSanitizer, etc.) | | (~30 more top-level files) | Specialized helpers (logEnv, modelsDevSync, piiSanitizer, etc.) |
### `src/db/` — Database (117 modules + 144 migrations) ### `src/db/` — Database (117 modules + 148 migrations)
| Subdir | Purpose | | Subdir | Purpose |
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -256,6 +256,7 @@ src/
| `utils/circuitBreaker.ts` | Provider circuit breaker (see `docs/architecture/RESILIENCE_GUIDE.md`) | | `utils/circuitBreaker.ts` | Provider circuit breaker (see `docs/architecture/RESILIENCE_GUIDE.md`) |
| `utils/apiAuth.ts` | API key validation, scope checking | | `utils/apiAuth.ts` | API key validation, scope checking |
| `utils/fetchTimeout.ts` | Timeout/abort wrappers for upstream fetch | | `utils/fetchTimeout.ts` | Timeout/abort wrappers for upstream fetch |
| `utils/releaseNotes.ts` | Closed v2/legacy announcement parser, localization and ID dismissal |
--- ---
@@ -270,7 +271,7 @@ open-sse/
├── translator/ # Format converters (9 request, 9 response, 9 helpers) ├── translator/ # Format converters (9 request, 9 response, 9 helpers)
├── transformer/ # Responses API ↔ Chat Completions (TransformStream) ├── transformer/ # Responses API ↔ Chat Completions (TransformStream)
├── services/ # ~80+ service modules (combo, accountFallback, autoCombo, reasoningCache, claude code/chatgpt stealth, modelDeprecation, taskAwareRouter, workflowFSM, etc.) ├── services/ # ~80+ service modules (combo, accountFallback, autoCombo, reasoningCache, claude code/chatgpt stealth, modelDeprecation, taskAwareRouter, workflowFSM, etc.)
├── mcp-server/ # MCP server (105 tools, 3 transports, 31 scopes) ├── mcp-server/ # MCP server (109 tools, 3 transports, 33 scopes)
├── config/ # Provider/model registries, header config, model aliases ├── config/ # Provider/model registries, header config, model aliases
├── utils/ # TLS client, proxy fetch/dispatcher, network helpers ├── utils/ # TLS client, proxy fetch/dispatcher, network helpers
├── index.ts # Workspace entry ├── index.ts # Workspace entry
@@ -406,7 +407,7 @@ open-sse/
| Doc | Purpose | | Doc | Purpose |
| -------------------------- | ------------------------------------------------------------------- | | -------------------------- | ------------------------------------------------------------------- |
| `MCP-SERVER.md` | MCP server: 105 tools, 3 transports, 31 scopes, REST endpoints | | `MCP-SERVER.md` | MCP server: 109 tools, 3 transports, 33 scopes, REST endpoints |
| `A2A-SERVER.md` | A2A v0.3: JSON-RPC, 6 skills, REST helpers, agent card | | `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 | | `AGENT_PROTOCOLS_GUIDE.md` | Unified guide: A2A vs ACP vs Cloud Agents |
| `CLOUD_AGENT.md` | Codex Cloud / Devin / Jules orchestration | | `CLOUD_AGENT.md` | Codex Cloud / Devin / Jules orchestration |

View File

@@ -330,32 +330,75 @@ excludeMarkers, defaultRetryAfterMs}`), matched via `applyStatusRestatement()`.
Permanent errors (agentrouter's `无权访问模型` — no access to this model) are Permanent errors (agentrouter's `无权访问模型` — no access to this model) are
NEVER restated: `excludeMarkers` vetoes the rule even when `textMarkers` hit, NEVER restated: `excludeMarkers` vetoes the rule even when `textMarkers` hit,
so the error keeps its original status and nothing retries it forever. A so the error keeps its original status and nothing retries it forever. The
separate provider classification rule matching provider classification rule
(`agentrouter-model-access-denied` in `open-sse/config/providerErrorRules.ts`) (`agentrouter-model-access-denied` in `open-sse/config/providerErrorRules.ts`:
declares an `auth_error`/scope-`model` match for this text, but it does not `reason: "auth_error"`, `scope: "model"`, a `6h` declared base cooldown) is
fire on the live production path today: the rule only matches `status === consulted by `checkFallbackError` (`open-sse/services/accountFallback.ts`)
403`, and `checkFallbackError`'s apikey-category `FORBIDDEN` branch *before* the generic apikey-category `FORBIDDEN` early-return, gated on
(`open-sse/services/accountFallback.ts`) returns early for a plain 403 `honorsRuleLockScope(provider)` (#10334 — currently agentrouter-exclusive via
*before* the provider-rule lookup ever runs. In practice a `无权访问模型` 403 the `HONORS_RULE_LOCK_SCOPE_PROVIDERS` allowlist in
is handled the same way as the base apikey-provider 403 path (see Connection `providerErrorRules.ts`). The rule's declared 6h cooldown flows through as
Cooldown, §2), not as a 6h model lockout. The rule still exists as a `fallbackResult.baseCooldownMs`, but it still feeds the pre-existing
declarative classification consumable by future callers of `classifyError` per-model-quota lockout path (`lockModelIfPerModelQuota()` /
with context — wiring it into the production `checkFallbackError` path is `recordModelLockoutFailure()`, unchanged by #10334 except for the cooldown
tracked as a follow-up, not yet done. 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.
Restated quota errors (`额度不足`) do reach a provider rule in production Restated quota errors (`额度不足`) reach a provider rule in production
(`agentrouter-user-quota-exhausted`, scope `"connection"`), but `scope` on (`agentrouter-user-quota-exhausted`: `reason: "quota_exhausted"`, `scope:
`ProviderErrorRuleMatch` is currently informational — the persistence path "connection"`, no declared cooldown of its own — the persistence layer's
(`checkFallbackError``combo.ts`) only consumes `reason` and `cooldownMs`, scaled backoff default applies). Since #10334, `scope` on
never `scope`. What actually happens for agentrouter (`passthroughModels: `ProviderErrorRuleMatch` IS consumed end-to-end, but **only** for providers in
true``hasPerModelQuota()` returns `true`) is a **per-model** lockout via the `HONORS_RULE_LOCK_SCOPE_PROVIDERS` allowlist (`providerErrorRules.ts`
`recordModelLockoutFailure()`: the connection itself is never cooled down for today only `"agentrouter"`, gated via `honorsRuleLockScope()`). For every
this error (`combo.ts` skips `recordProviderCooldown` for 429 when other provider `scope` remains informational, exactly as before #10334.
`hasPerModelQuota` is true), so other models on the same account keep being `checkFallbackError` surfaces the matched rule's scope as
tried — each one burns one call and its own lockout before combo routing `fallbackResult.ruleScope`; `isAgentrouterConnectionQuotaScope()`
moves on. Honoring `scope` end-to-end (so a `"connection"` match actually (`src/sse/services/auth.ts`) is the shared guard that confirms a
locks the connection) is tracked as a follow-up. `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.
### Two-stage design: status restatement, then classification ### Two-stage design: status restatement, then classification
@@ -380,6 +423,15 @@ allowlisted providers, the structured error otherwise. Adding a provider to
that the default path for every provider not on the list stays that the default path for every provider not on the list stays
byte-for-byte unchanged. 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 ### Adding a new quota-misstating gateway
1. Register one rule array in `statusRestatementRegistry` 1. Register one rule array in `statusRestatementRegistry`
@@ -395,7 +447,15 @@ byte-for-byte unchanged.
`checkFallbackError` only ever hands the rule the structured `checkFallbackError` only ever hands the rule the structured
`{code, type}` error and a body-text rule will never match live traffic. `{code, type}` error and a body-text rule will never match live traffic.
Rules that match purely on `status`/`headers` (like Opencode's or Rules that match purely on `status`/`headers` (like Opencode's or
Minimax's) do not need this opt-in. 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.
3. Add unit tests mirroring `tests/unit/upstream-status-restatement.test.ts` 3. Add unit tests mirroring `tests/unit/upstream-status-restatement.test.ts`
and `tests/unit/agentrouter-error-rules.test.ts` (including the and `tests/unit/agentrouter-error-rules.test.ts` (including the
not-permanent / not-creditsExhausted guards, and — if the provider needs 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 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."> <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.">
<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> <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> <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> <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>
<g opacity="0"><animate attributeName="opacity" values="0;1" dur="0.4s" begin="0.51s" fill="freeze"/> <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="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">105</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>
<use href="#no" x="604" y="359"/> <use href="#no" x="604" y="359"/>
<use href="#mid" x="760" y="359"/> <use href="#mid" x="760" y="359"/>
<use href="#no" x="916" 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 105 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 109 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> <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> <defs>
<pattern id="gridPaperP" width="32" height="32" patternUnits="userSpaceOnUse"> <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"/> <path d="M 7,11 L 10,14 L 15.4,8.2"/>
</g> </g>
<text x="862" y="354" font-size="18" font-weight="800" fill="#7ee787">Production-grade</text> <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 (105</text> <text x="826" y="388" font-size="13.5" fill="#a1a1aa">Circuit breakers, TLS stealth, MCP (109</text>
<text x="826" y="410" font-size="13.5" fill="#a1a1aa">tools), A2A, memory, guardrails, evals —</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> <text x="826" y="432" font-size="13.5" fill="#a1a1aa">25,000+ tests.</text>
</g> </g>

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -1,14 +1,14 @@
--- ---
title: "OmniRoute MCP Server Documentation" title: "OmniRoute MCP Server Documentation"
version: 3.8.40 version: 3.8.50
lastUpdated: 2026-06-28 lastUpdated: 2026-08-08
--- ---
# OmniRoute MCP Server Documentation # OmniRoute MCP Server Documentation
> Model Context Protocol server with 105 tools across routing, cache, compression, memory, skills, proxy, pool, and context source operations. > Model Context Protocol server with 109 tools across routing, cache, compression, memory, skills, proxy, pool, Radar, and context source operations.
> >
> 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. > 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.
## Installation ## Installation
@@ -64,7 +64,7 @@ Cursor, Cline, and compatible MCP client setup.
--- ---
## Essential Tools (8) — Phase 1 ## Essential Tools (13) — Phase 1
| Tool | Scopes | Description | | Tool | Scopes | Description |
| :------------------------------ | :-------------------- | :------------------------------------------------------------ | | :------------------------------ | :-------------------- | :------------------------------------------------------------ |
@@ -72,16 +72,15 @@ Cursor, Cline, and compatible MCP client setup.
| `omniroute_list_combos` | `read:combos` | All configured combos with strategies (optional metrics) | | `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_get_combo_metrics` | `read:combos` | Performance metrics for a specific combo |
| `omniroute_switch_combo` | `write:combos` | Activate or deactivate a 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_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_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_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_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 |
## Phase 1 — Search | `omniroute_tool_search` | `read:tools` | Discover tools from the registered MCP catalog |
| `omniroute_web_search` | `execute:search` | Web search through the configured search providers |
| Tool | Scopes | Description | | `omniroute_web_fetch` | `execute:search` | Fetch web content through the configured fetch providers |
| :--------------------- | :--------------- | :--------------------------------------------------------------------------------------------------------------------------------- |
| `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 ## Advanced Tools (11) — Phase 2
@@ -227,7 +226,7 @@ See [AGENT-SKILLS.md](./AGENT-SKILLS.md) for the full catalog and how external a
## Related Frameworks (v3.8.0) ## Related Frameworks (v3.8.0)
computed = 105, computed by `countUniqueMcpTools()`) is intentionally The MCP tool inventory above (109 unique tools, computed by `countUniqueMcpTools()`) is intentionally
scoped to runtime routing/cache/compression/memory/skills/proxy/context-source operations. Two adjacent 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: frameworks ship alongside the MCP server in v3.8.0 and are documented separately:
@@ -369,7 +368,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`). 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 105 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 109 tools are announced unchanged.
| Variable | Mode | | Variable | Mode |
| :--------------- | :-------------------------------------------------------------------------------------- | | :--------------- | :-------------------------------------------------------------------------------------- |

View File

@@ -1,13 +1,13 @@
--- ---
title: "Radar Free-Model Catalog" title: "Radar Free-Model Catalog"
version: 3.8.50 version: 3.8.50
lastUpdated: 2026-08-08 lastUpdated: 2026-08-13
--- ---
# Radar Free-Model Catalog # Radar Free-Model Catalog
> **Source of truth:** `src/lib/radar/`, `src/lib/db/radar.ts`, `src/app/api/radar/` > **Source of truth:** `src/lib/radar/`, `src/lib/db/radar.ts`, `src/app/api/radar/`
> **Last updated:** 2026-08-08 — v3.8.50 > **Last updated:** 2026-08-13 — v3.8.50
Radar is an **optional add-on** that overlays a signed, freshly-curated free-model 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 catalog on top of the release baseline (`FREE_MODEL_BUDGETS` in
@@ -15,11 +15,12 @@ catalog on top of the release baseline (`FREE_MODEL_BUDGETS` in
faster than release cadence — providers add, shrink, or discontinue free quotas between 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. releases, and the baseline catalog can only be refreshed when a new version ships.
**Nothing that is free today stops being free.** Radar never removes or paywalls a **Nothing that is free today stops being free because of the remote feed.** Radar never
baseline entry; it only refreshes limits/status fields at read time and can layer in paywalls a baseline entry; it only refreshes limits/status fields at read time and can
newly-discovered free models between releases. The baseline catalog itself is never layer in newly-discovered free models between releases. An operator can still hide a
mutated on disk — see [Read-time overlay merge rules](#read-time-overlay-merge-rules) model locally, and can restore it from the same dashboard. The baseline catalog itself
below. is never mutated on disk — see
[Read-time overlay merge rules](#read-time-overlay-merge-rules) below.
--- ---
@@ -29,14 +30,39 @@ 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 workstreams. It is a code-level status, not a promise that a particular hosted deployment
or external integration is currently available. or external integration is currently available.
| Area | Status in this release | | 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. | | 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. | | 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. | | 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. | | 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. | | 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. |
| 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. | | 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.
--- ---
@@ -48,15 +74,16 @@ Radar is gated end-to-end by the `RADAR_ENABLED` feature flag
**When the flag is off, the surface does not exist:** **When the flag is off, the surface does not exist:**
- `GET /api/radar/catalog`, `POST /api/radar/sync`, `POST /api/radar/settings` all - All `/api/radar/*` endpoints, including local model-state reads and writes,
return `404` before touching any Radar module. return `404` before touching any Radar module.
- The dashboard screens (`/dashboard/radar`, `/dashboard/radar/setup`) render - The dashboard screens (`/dashboard/radar`, `/dashboard/radar/setup`,
`/dashboard/radar/combos`, `/dashboard/radar/offers`, `/dashboard/radar/intel`) render
`notFound()`. `notFound()`.
- `getRadarCatalog()` (`src/lib/radar/index.ts`) returns the untouched baseline — - `getRadarCatalog()` (`src/lib/radar/index.ts`) returns the untouched baseline —
same entry count, same values, every entry tagged `origin: "baseline"` — and never same entry count, same values, every entry tagged `origin: "baseline"` — and never
reads the feed cache. reads the feed cache.
- No network call is ever made; `syncRadar()` (`src/lib/radar/sync.ts`) returns - No Radar network call is ever made; each sync module returns `{ status: "disabled" }`
`{ status: "disabled" }` at step 1 without touching `fetch`. before touching `fetch`.
This is a strict superset gate: flipping the flag on unlocks the _screens_, nothing 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 more. It does not upload data, does not start a background sync, and does not change
@@ -78,14 +105,17 @@ Opt-in false → { status: "opt_out" } — no network call
When both are on, the sync path is: When both are on, the sync path is:
1. `GET <feed base URL>/v1/catalog/latest` with an optional `Authorization: Bearer 1. `GET <feed base URL>/v1/catalog/latest` with `x-omniroute-radar-schema: 2` and an optional
<supporter key>` header (see below). `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.
2. Nothing about the request, the operator, or their traffic is uploaded — it is a 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 plain, unauthenticated-by-default GET. OmniRoute never posts usage data, provider
configuration, or model traffic to the feed service. configuration, or model traffic to the feed service.
3. The response is verified, validated, and cached locally (see 3. The response is verified, validated, and cached locally (see
[Security model](#security-model)). Radar has exactly two server-side network paths: [Security model](#security-model)). Radar has exactly four server-side network paths:
`syncRadar()` for the catalog and `syncRadarReferrals()` for the standalone referrals feed. `syncRadar()` for the catalog, `syncRadarReferrals()` for referrals, and
`syncRadarOffers()` / `syncRadarIntel()` for supporter-only offers and Intel.
The **supporter key** is an optional Bearer token (`radar_settings.supporter_key`) The **supporter key** is an optional Bearer token (`radar_settings.supporter_key`)
that lets the feed service decide which tier to serve (see that lets the feed service decide which tier to serve (see
@@ -95,7 +125,7 @@ that lets the feed service decide which tier to serve (see
helpers (`src/lib/db/encryption.ts`) used for provider credentials. helpers (`src/lib/db/encryption.ts`) used for provider credentials.
- Set via `POST /api/radar/settings` (`{ supporterKey: "omr_" + 40 hex chars }`) and - Set via `POST /api/radar/settings` (`{ supporterKey: "omr_" + 40 hex chars }`) and
**never echoed back** — the response returns a masked form (`omr_****abcd`). **never echoed back** — the response returns a masked form (`omr_****abcd`).
- Changing or clearing it atomically invalidates both the catalog and referrals caches. The - Changing or clearing it atomically invalidates the catalog, referrals, offers, and Intel caches. The
next sync/read resolves the new entitlement server-side; saving a key does not itself make 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. 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 - Sent to the feed service as a Bearer token on the sync GET — nothing else about the
@@ -128,6 +158,29 @@ client component never reads `process.env` itself.
| `RADAR_CONTRIBUTOR_CLAIM_URL` | Overrides the contributor-claim URL (default `https://radar.omniroute.online/auth/github`). | | `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`). | | `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 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 (`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` path: pasting a key and submitting sends `POST /api/radar/settings`
@@ -141,6 +194,57 @@ 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 remain the way to _obtain_ a key in the first place; this input is where an operator
who already has one activates it. 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 ## Security model
@@ -271,6 +375,54 @@ Four rules, in order of precedence:
entry (`tombstones` set), the feed re-adding that `provider:modelId` in a later entry (`tombstones` set), the feed re-adding that `provider:modelId` in a later
version does not bring it back. 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 ### Provenance markers
Every merged entry carries an `origin` field the UI renders as a badge: Every merged entry carries an `origin` field the UI renders as a badge:
@@ -284,30 +436,41 @@ Every merged entry carries an `origin` field the UI renders as a badge:
## Local surfaces — never a feed proxy ## Local surfaces — never a feed proxy
Five local routes back the UI, all under `src/app/api/radar/`: The local Radar route families below back the UI under `src/app/api/radar/`:
| Route | Method | Purpose | | Route | Method | Purpose |
| ---------------------- | ------ | --------------------------------------------------------------------------------------------------------------------- | | ------------------------------ | ------ | --------------------------------------------------------------------------------------------------------------------- |
| `/api/radar/catalog` | GET | Returns the merged catalog (`getRadarCatalog()`) from the local cache. | | `/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/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` | GET | Returns `{ optIn, hasSupporterKey, supporterKeyMasked }` — never the raw key. |
| `/api/radar/settings` | POST | Sets opt-in and/or the (encrypted) supporter 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/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. |
**Hard rule: these routes never proxy the feed service.** The browser only ever talks **Hard rule: these routes never proxy the feed service.** The browser only ever talks
to the local OmniRoute server. The two modules that touch the Radar service are to the local OmniRoute server. The four modules that touch the Radar service are
`src/lib/radar/sync.ts` (catalog) and `src/lib/radar/referralsSync.ts` (referrals); both `src/lib/radar/sync.ts` (catalog), `src/lib/radar/referralsSync.ts` (referrals), and
always run server-side, never client-side. This keeps the feed URL and any supporter key `src/lib/radar/offersSync.ts` (offers) plus `src/lib/radar/intelSync.ts` (Intel); all run
out of client-facing network traffic entirely. server-side, never client-side. This keeps
the feed URL and any supporter key out of client-facing network traffic entirely.
All five routes return `404` when `RADAR_ENABLED` is off (see All Radar endpoints return `404` when `RADAR_ENABLED` is off (see
[Flag](#flag-radar_enabled-default-off) above), and route error responses through [Flag](#flag-radar_enabled-default-off) above), and route error responses through
`buildErrorBody()`/`sanitizeErrorMessage()` per the repo-wide error-sanitization rule `buildErrorBody()`/`sanitizeErrorMessage()` per the repo-wide error-sanitization rule
(`docs/security/ERROR_SANITIZATION.md`). (`docs/security/ERROR_SANITIZATION.md`).
### Authentication ### Authentication
All five routes require authentication via `isAuthenticated()` All Radar endpoints require authentication via `isAuthenticated()`
(`src/shared/utils/apiAuth.ts`) — a dashboard session cookie or a management-scoped (`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 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` `404` check always runs **before** the auth check, so an install with `RADAR_ENABLED`
@@ -318,6 +481,58 @@ 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 (free credits)
Referral links are served from a **standalone, always-current** feed — Referral links are served from a **standalone, always-current** feed —
@@ -473,8 +688,9 @@ service without touching client code:
1. Serve a `GET /v1/catalog/latest` endpoint returning a JSON body that satisfies 1. Serve a `GET /v1/catalog/latest` endpoint returning a JSON body that satisfies
`RadarFeedSchema` (`src/lib/radar/feedSchema.ts`) — top-level `feed: `RadarFeedSchema` (`src/lib/radar/feedSchema.ts`) — top-level `feed:
"omniroute-radar"`, `schemaVersion: 1`, `version`, `tier`, `providers`, `models`, "omniroute-radar"`, `schemaVersion: 2`, `version`, `tier`, `providers`, `models`,
`quirks`, and `totals`. `quirks`, and `totals`. Honor `x-omniroute-radar-schema: 2`; a transition-compatible server
should default requests without it to a separately signed v1 artifact.
2. Sign the exact response bytes with an Ed25519 key pair and return the base64 2. Sign the exact response bytes with an Ed25519 key pair and return the base64
signature in the `x-omniroute-feed-signature` response header. 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 3. Set `RADAR_FEED_URL` to the new base URL and `RADAR_FEED_PUBKEY` to the matching
@@ -498,11 +714,24 @@ 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 (`src/lib/radar/referralsFeedSchema.ts`) and sign it with the same Ed25519 key pair as
the catalog feed. 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 ## Related docs
- [`docs/security/ERROR_SANITIZATION.md`](../security/ERROR_SANITIZATION.md) — the - [`docs/security/ERROR_SANITIZATION.md`](../security/ERROR_SANITIZATION.md) — the
error-response pattern the five `/api/radar/*` routes follow. error-response pattern the `/api/radar/*` routes follow.
- [`docs/reference/ENVIRONMENT.md`](../reference/ENVIRONMENT.md#27-radar-feed-self-hosting) - [`docs/reference/ENVIRONMENT.md`](../reference/ENVIRONMENT.md#27-radar-feed-self-hosting)
— `RADAR_FEED_URL` / `RADAR_FEED_PUBKEY` reference. — `RADAR_FEED_URL` / `RADAR_FEED_PUBKEY` reference.

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -4,10 +4,7 @@
--- ---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 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 ## Overview
@@ -21,7 +18,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
- **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
@@ -109,7 +106,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ └── streaming.ts # SSE streaming for A2A │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -131,7 +128,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── extraction.ts # Memory extraction from conversations
@@ -214,11 +211,11 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── moderations.ts # Content moderation │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── httpTransport.ts # HTTP transport handler
@@ -269,7 +266,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ ├── i18n/ # 43-language translated docs │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── guides/ # USER_GUIDE.md, TROUBLESHOOTING.md, ELECTRON_GUIDE.md, I18N.md
@@ -352,9 +349,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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `docs/frameworks/MCP-SERVER.md`.
@@ -397,7 +394,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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`.
@@ -441,7 +438,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`. 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, 145 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, 148 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. 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.
@@ -485,7 +482,7 @@ diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool
- **339-provider catalog** with 90+ free tiers, one-click account imports, and bulk key add - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -65,6 +65,7 @@ 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 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 window and never as the first move. Docker: never rewrite a version tag — rollback is
repointing `latest` to the last good digest. repointing `latest` to the last good digest.
## Hotfix Fast-Lane (label `hotfix`) ## Hotfix Fast-Lane (label `hotfix`)
A PR labeled `hotfix` skips the heavy CI matrix (9-shard E2E, coverage ratchet, A PR labeled `hotfix` skips the heavy CI matrix (9-shard E2E, coverage ratchet,
@@ -276,6 +277,22 @@ Deploy skills use the light rsync flow — no `npm pack`, no `npm i -g`:
- [ ] Open milestone for next version - [ ] Open milestone for next version
- [ ] If critical: pin discussion or post in `news.json` for in-app banner - [ ] 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+) ## Embedded Services smoke (v3.8.4+)
Before shipping any release that includes embedded services changes, verify: 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 | | 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 | | `alibaba` | `https://dashscope-intl.aliyuncs.com/compatible-mode/v1` | `https://dashscope.aliyuncs.com/compatible-mode/v1` | OpenAI |
| `bailian-coding-plan` | `https://coding-intl.dashscope.aliyuncs.com/apps/anthropic/v1` | `https://coding.dashscope.aliyuncs.com/apps/anthropic/v1` | Anthropic | | `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 |
| `qwen-cloud` | `https://dashscope-intl.aliyuncs.com/compatible-mode/v1` | `https://dashscope.aliyuncs.com/compatible-mode/v1` | OpenAI | | `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 | | `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

@@ -1142,6 +1142,10 @@ Provider quota endpoints, network tunnels (Tailscale, Ngrok, MITM debug proxy),
| `REDIS_URL` | `redis://localhost:6379` | `src/shared/utils/rateLimiter.ts` | Redis connection string for the rate limiter backend. | | `REDIS_URL` | `redis://localhost:6379` | `src/shared/utils/rateLimiter.ts` | Redis connection string for the rate limiter backend. |
| `ALIBABA_CODING_PLAN_HOST` | _(production host)_ | `open-sse/services/bailianQuotaFetcher.ts` | Override the host used to fetch Alibaba Bailian coding-plan quotas. | | `ALIBABA_CODING_PLAN_HOST` | _(production host)_ | `open-sse/services/bailianQuotaFetcher.ts` | Override the host used to fetch Alibaba Bailian coding-plan quotas. |
| `ALIBABA_CODING_PLAN_QUOTA_URL` | derived from host | `open-sse/services/bailianQuotaFetcher.ts` | Full quota URL override for Alibaba Bailian. | | `ALIBABA_CODING_PLAN_QUOTA_URL` | derived from host | `open-sse/services/bailianQuotaFetcher.ts` | Full quota URL override for Alibaba Bailian. |
| `QWEN_CLOUD_COOKIE` | _(unset)_ | `open-sse/services/qwenTokenPlanQuotaFetcher.ts` | Console session cookie for the Qwen Cloud / Model Studio personal Token Plan quota gateway (the inference API key cannot read it). Copy the whole `Cookie` request header — it contains `login_qwencloud_ticket` — from any `api.json` call to `cs-data.qwencloud.com` on home.qwencloud.com Billing Subscription (F12 Network). Sensitive and session-scoped; prefer the per-connection `qwenCloudCookie` Dashboard field. |
| `QWEN_CLOUD_SEC_TOKEN` | _(unset)_ | `open-sse/services/qwenTokenPlanQuotaFetcher.ts` | Manual `sec_token` override for the Token Plan console gateway. Sensitive; when unset the fetcher resolves it from the dashboard HTML using the cookie. |
| `QWEN_TOKEN_PLAN_HOST` | `https://cs-data.qwencloud.com` | `open-sse/services/qwenTokenPlanQuotaFetcher.ts` | Gateway host override for the personal Token Plan quota fetcher (e.g. `bailian-singapore-cs.alibabacloud.com` for the Model Studio console). |
| `QWEN_TOKEN_PLAN_DASHBOARD_URL` | `https://home.qwencloud.com/` | `open-sse/services/qwenTokenPlanQuotaFetcher.ts` | Dashboard URL used to resolve `sec_token` from the logged-in HTML. |
| `ALIBABA_FREE_TIER_VISION_FE_PATH` | `/costing-balance/free-quota-image-video` | `open-sse/services/alibabaFreeTierQuotaFetcher.ts` | Console front-end path override for fetching Alibaba Model Studio free-tier vision/media quota. | | `ALIBABA_FREE_TIER_VISION_FE_PATH` | `/costing-balance/free-quota-image-video` | `open-sse/services/alibabaFreeTierQuotaFetcher.ts` | Console front-end path override for fetching Alibaba Model Studio free-tier vision/media quota. |
| `ALIBABA_FREE_TIER_MULTIMODAL_FE_PATH` | `/costing-balance/free-quota-multimodal` | `open-sse/services/alibabaFreeTierQuotaFetcher.ts` | Console front-end path override for fetching Alibaba Model Studio free-tier multimodal quota. | | `ALIBABA_FREE_TIER_MULTIMODAL_FE_PATH` | `/costing-balance/free-quota-multimodal` | `open-sse/services/alibabaFreeTierQuotaFetcher.ts` | Console front-end path override for fetching Alibaba Model Studio free-tier multimodal quota. |
| `ALIBABA_FREE_TIER_AUDIO_FE_PATH` | `/costing-balance/free-quota-audio` | `open-sse/services/alibabaFreeTierQuotaFetcher.ts` | Console front-end path override for fetching Alibaba Model Studio free-tier audio quota. | | `ALIBABA_FREE_TIER_AUDIO_FE_PATH` | `/costing-balance/free-quota-audio` | `open-sse/services/alibabaFreeTierQuotaFetcher.ts` | Console front-end path override for fetching Alibaba Model Studio free-tier audio quota. |
@@ -1348,17 +1352,24 @@ that should be able to run the docs translator.
Optional add-on gated by the RADAR_ENABLED feature flag (default off — a feature Optional add-on gated by the RADAR_ENABLED feature flag (default off — a feature
flag toggled via Settings/DB, not an env var; see flag toggled via Settings/DB, not an env var; see
[docs/frameworks/RADAR.md](../frameworks/RADAR.md#flag-radar_enabled-default-off)). [docs/frameworks/RADAR.md](../frameworks/RADAR.md#flag-radar_enabled-default-off)).
The four variables below are optional overrides used only to point the client at a The first four variables below are optional overrides for a self-hosted or forked feed and
self-hosted or forked feed / supporter-key flow instead of the default OmniRoute supporter-key flows. The fifth, `RADAR_ADMIN_URL`, is a separate default-free link to the owner's
Radar service. See [docs/frameworks/RADAR.md](../frameworks/RADAR.md) for the full private operations panel. See [docs/frameworks/RADAR.md](../frameworks/RADAR.md) for the full
module doc. 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.
| Variable | Default | Source File | Description | | Variable | Default | Source File | Description |
| -------------------------------- | --------------------------------------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------ | | -------------------------------- | --------------------------------------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------ |
| `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_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_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_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_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_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
> 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. > 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.
## Overview ## 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"`) - **Runtime:** Node.js `>=22.0.0 <23 || >=24.0.0 <27`, ES Modules (`"type": "module"`)
- **Framework:** Next.js 16 (App Router) with TypeScript 6 - **Framework:** Next.js 16 (App Router) with TypeScript 6
- **Database:** SQLite via better-sqlite3 (local, zero-config, 145 migrations) - **Database:** SQLite via better-sqlite3 (local, zero-config, 148 migrations)
- **State management:** Zustand (client), SQLite (server persistence) - **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons - **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 - **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 │ │ │ └── streaming.ts # SSE streaming for A2A
│ │ ├── acp/ # Agent Communication Protocol registry and manager │ │ ├── acp/ # Agent Communication Protocol registry and manager
│ │ ├── compliance/ # Compliance policy engine │ │ ├── compliance/ # Compliance policy engine
│ │ ├── db/ # SQLite database layer (99 modules + migrations) │ │ ├── db/ # SQLite database layer (117 modules + migrations)
│ │ │ ├── core.ts # Database initialization, connection, schema │ │ │ ├── core.ts # Database initialization, connection, schema
│ │ │ ├── providers.ts # Provider connection CRUD │ │ │ ├── providers.ts # Provider connection CRUD
│ │ │ ├── models.ts # Model catalog management │ │ │ ├── models.ts # Model catalog management
@@ -124,7 +124,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── secrets.ts # Secrets management │ │ │ ├── secrets.ts # Secrets management
│ │ │ ├── stateReset.ts # State reset utilities │ │ │ ├── stateReset.ts # State reset utilities
│ │ │ ├── migrationRunner.ts # Schema migration runner │ │ │ ├── migrationRunner.ts # Schema migration runner
│ │ │ └── migrations/ # 117 versioned SQL migration files │ │ │ └── migrations/ # 148 versioned SQL migration files
│ │ ├── evals/ # Eval runner and scheduler │ │ ├── evals/ # Eval runner and scheduler
│ │ ├── memory/ # Persistent conversational memory │ │ ├── memory/ # Persistent conversational memory
│ │ │ ├── extraction.ts # Memory extraction from conversations │ │ │ ├── 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 │ │ ├── moderations.ts # Content moderation
│ │ ├── rerank.ts # Reranking API │ │ ├── rerank.ts # Reranking API
│ │ └── search.ts # Web search API │ │ └── search.ts # Web search API
│ ├── mcp-server/ # Built-in MCP server (105 tools, 3 transports: stdio/SSE/streamable-HTTP) │ ├── mcp-server/ # Built-in MCP server (109 tools, 3 transports: stdio/SSE/streamable-HTTP)
│ │ ├── server.ts # MCP server core (tool registration, scope enforcement) │ │ ├── server.ts # MCP server core (tool registration, scope enforcement)
│ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools) │ │ ├── tools/ # Tool implementations (advancedTools, memoryTools, skillTools)
│ │ ├── schemas/ # Zod input schemas (tools, audit, a2a) │ │ ├── schemas/ # Zod input schemas (tools, audit, a2a)
│ │ ├── scopeEnforcement.ts # Scope-based access control (31 scopes) │ │ ├── scopeEnforcement.ts # Scope-based access control (33 scopes)
│ │ ├── audit.ts # Tool call audit logging │ │ ├── audit.ts # Tool call audit logging
│ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat │ │ ├── runtimeHeartbeat.ts # MCP runtime heartbeat
│ │ └── httpTransport.ts # HTTP transport handler │ │ └── 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 │ ├── i18n/ # 43-language translated docs
│ ├── architecture/ # ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, REPOSITORY_MAP.md, AUTHZ_GUIDE.md, RESILIENCE_GUIDE.md, QUALITY_GATES.md │ ├── 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 │ ├── reference/ # API_REFERENCE.md, PROVIDER_REFERENCE.md, CLI-TOOLS.md
│ ├── frameworks/ # MCP-SERVER.md (105 tools), A2A-SERVER.md, SKILLS.md, MEMORY.md, CLOUD_AGENT.md, EVALS.md, WEBHOOKS.md │ ├── frameworks/ # MCP-SERVER.md (109 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 │ ├── routing/ # AUTO-COMBO.md (14-factor scoring), REASONING_REPLAY.md
│ ├── security/ # GUARDRAILS.md, COMPLIANCE.md, STEALTH_GUIDE.md, PUBLIC_CREDS.md, ERROR_SANITIZATION.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 │ ├── 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) - **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 - **ACP** — Agent Communication Protocol registry and manager
### MCP Server (105 Tools) ### MCP Server (109 Tools)
105 tools across modules: **43 base** (health, combos, quotas, routing, cost, models, cache, 109 tools across modules: **44 canonical** (health, combos, quotas, routing, cost, models, cache,
diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**, diagnostics) plus **memory**, **skill**, **agentSkill**, **githubSkill**, **pool**, **notion**,
**obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory: **obsidian**, **localCorpus**, **gamification**, and **plugin** modules. Full per-tool inventory:
`docs/frameworks/MCP-SERVER.md`. `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. 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 99 `src/lib/db/` modules with 117 SQL migrations. 9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in 117 `src/lib/db/` modules with 148 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`. 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`. 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, 145 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, 148 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. 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 - **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` - **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 - **14-factor Auto-Combo scoring** with bandit exploration and progressive cooldown
- **MCP server expanded to 105 tools / 31 scopes** (base + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules) - **MCP server expanded to 109 tools / 33 scopes** (canonical + memory/skill/agentSkill/githubSkill/pool/notion/obsidian/localCorpus/gamification/plugin modules)
- **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks - **Cloud Agents** (Codex Cloud, Devin, Jules), **Guardrails**, **Evals**, **Webhooks**, **Compliance** frameworks
- **Embedded services** manager (install/start/stop bundled services from the dashboard) - **Embedded services** manager (install/start/stop bundled services from the dashboard)
- **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic - **Prompt compression** (RTK + Caveman codecs) saving up to ~95% tokens on eligible traffic

View File

@@ -1,8 +1,43 @@
{ {
"active": false, "schemaVersion": 2,
"title": "Novidade no Omniverse", "items": [
"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", "id": "radar-launch-2026-08",
"linkLabel": "Conhecer o tOmni", "active": false,
"icon": "campaign" "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"
}
]
} }

View File

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

View File

@@ -60,7 +60,12 @@ export const bailian_coding_planProvider: RegistryEntry = {
alias: "bcp", alias: "bcp",
format: "claude", format: "claude",
executor: "default", executor: "default",
baseUrl: "https://coding-intl.dashscope.aliyuncs.com/apps/anthropic/v1", // Token Plan endpoint (the catalog entry is "Alibaba Token Plan"). The former
// coding-intl.dashscope.aliyuncs.com host only accepts Coding Plan keys and rejects
// Token Plan keys with 401 invalid_api_key. Verified live 2026-08-14: this host
// returns 200 for every model below with the same key.
// Docs: https://www.alibabacloud.com/help/en/model-studio/more-tools
baseUrl: "https://token-plan.ap-southeast-1.maas.aliyuncs.com/apps/anthropic/v1",
chatPath: "/messages", chatPath: "/messages",
authType: "apikey", authType: "apikey",
authHeader: "x-api-key", authHeader: "x-api-key",

View File

@@ -1,6 +1,6 @@
# OmniRoute MCP Server # OmniRoute MCP Server
> **Model Context Protocol server** that exposes OmniRoute's gateway intelligence as **107 tools** for AI agents. > **Model Context Protocol server** that exposes OmniRoute's gateway intelligence as **109 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. > **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 │ │ OmniRoute MCP Server │
│ ┌──────────────┐ ┌─────────────────┐ ┌────────────────────┐ │ │ ┌──────────────┐ ┌─────────────────┐ ┌────────────────────┐ │
│ │ Scope │ │ 107 MCP Tools │ │ Audit Logger │ │ │ │ Scope │ │ 109 MCP Tools │ │ Audit Logger │ │
│ │ Enforcement │──│ (core + memory │──│ (SHA-256/SQLite) │ │ │ │ Enforcement │──│ (core + memory │──│ (SHA-256/SQLite) │ │
│ │ │ │ + skills + …) │ │ │ │ │ │ │ │ + skills + …) │ │ │ │
│ └──────────────┘ └────────┬────────┘ └────────────────────┘ │ │ └──────────────┘ └────────┬────────┘ └────────────────────┘ │
@@ -120,18 +120,23 @@ omniroute --mcp
## Tool Reference ## Tool Reference
### Phase 1: Essential Tools (8) ### Phase 1: Essential Tools (13)
| # | Tool | Scopes | Description | | # | Tool | Scopes | Description |
| --- | ------------------------------- | --------------------- | -------------------------------------------------------------------------- | | --- | ------------------------------- | --------------------- | -------------------------------------------------------------------------- |
| 1 | `omniroute_get_health` | `read:health` | Gateway health, uptime, memory, circuit breakers, rate limits, cache stats | | 1 | `omniroute_tool_search` | `read:tools` | Discover tools from the registered MCP catalog |
| 2 | `omniroute_list_combos` | `read:combos` | List all combos (model chains) with strategies and optional metrics | | 2 | `omniroute_get_health` | `read:health` | Gateway health, uptime, memory, circuit breakers, rate limits, cache stats |
| 3 | `omniroute_get_combo_metrics` | `read:combos` | Performance metrics for a specific combo | | 3 | `omniroute_list_combos` | `read:combos` | List all combos (model chains) with strategies and optional metrics |
| 4 | `omniroute_switch_combo` | `write:combos` | Activate or deactivate a combo for routing | | 4 | `omniroute_get_combo_metrics` | `read:combos` | Performance metrics for a specific combo |
| 5 | `omniroute_check_quota` | `read:quota` | Remaining API quota per provider with token health status | | 5 | `omniroute_switch_combo` | `write:combos` | Activate or deactivate a combo for routing |
| 6 | `omniroute_route_request` | `execute:completions` | Send a chat completion through intelligent routing | | 6 | `omniroute_create_combo` | `write:combos` | Create a validated combo through the existing combo API |
| 7 | `omniroute_cost_report` | `read:usage` | Cost report by period (session/day/week/month) with per-provider breakdown | | 7 | `omniroute_check_quota` | `read:quota` | Remaining API quota per provider with token health status |
| 8 | `omniroute_list_models_catalog` | `read:models` | List all available models across providers with capabilities and pricing | | 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 |
### Phase 2: Advanced Tools (8) ### Phase 2: Advanced Tools (8)

View File

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

View File

@@ -0,0 +1,151 @@
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

@@ -0,0 +1,170 @@
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,6 +91,8 @@ export {
ccrStatsTool, ccrStatsTool,
} from "./tools.ts"; } from "./tools.ts";
export { radarCatalogInput, radarCatalogOutput, radarCatalogTool } from "./radarCatalog.ts";
// A2A schemas // A2A schemas
export { export {
AgentCardSchema, AgentCardSchema,

View File

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

View File

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

View File

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

View File

@@ -15,7 +15,11 @@ import {
serviceSupervisorCooldown, serviceSupervisorCooldown,
isNimFunctionDegraded, isNimFunctionDegraded,
} from "../config/errorConfig.ts"; } from "../config/errorConfig.ts";
import { getProviderErrorRuleMatch, resolveRuleMatchBody } from "../config/providerErrorRules.ts"; import {
getProviderErrorRuleMatch,
resolveRuleMatchBody,
honorsRuleLockScope,
} from "../config/providerErrorRules.ts";
import * as rot from "./rotationConfig.ts"; import * as rot from "./rotationConfig.ts";
import { getPassthroughProviders, getProviderCategory } from "../config/providerRegistry.ts"; import { getPassthroughProviders, getProviderCategory } from "../config/providerRegistry.ts";
import { import {
@@ -1458,6 +1462,11 @@ export function checkFallbackError(
/** #6061: the provider-configured cooldown (ms) before backoff scaling, surfaced so the /** #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. */ * caller can persist an explicit reset window instead of the engine's scaled cooldown. */
configuredCooldownMs?: number; 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. // #10360: an executor-result contract violation is OUR bug, not the provider's.
// Retrying reproduces it verbatim, and cooling the connection down (or tripping // Retrying reproduces it verbatim, and cooling the connection down (or tripping
@@ -1712,6 +1721,36 @@ export function checkFallbackError(
return { shouldFallback: false, cooldownMs: 0, reason: RateLimitReason.UNKNOWN }; 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 ( if (
status === HTTP_STATUS.FORBIDDEN && status === HTTP_STATUS.FORBIDDEN &&
provider && provider &&
@@ -1764,6 +1803,8 @@ export function checkFallbackError(
providerMatch?.cooldownMs !== undefined && providerMatch.cooldownMs > 0 providerMatch?.cooldownMs !== undefined && providerMatch.cooldownMs > 0
? providerMatch.cooldownMs ? providerMatch.cooldownMs
: undefined; : undefined;
const ruleScope =
providerMatch && honorsRuleLockScope(provider) ? providerMatch.scope : undefined;
const fallback = buildRetryableFallback(reason); const fallback = buildRetryableFallback(reason);
if (providerCooldownMs !== undefined) { if (providerCooldownMs !== undefined) {
return { return {
@@ -1771,9 +1812,10 @@ export function checkFallbackError(
cooldownMs: providerCooldownMs, cooldownMs: providerCooldownMs,
baseCooldownMs: providerCooldownMs, baseCooldownMs: providerCooldownMs,
configuredCooldownMs: providerCooldownMs, configuredCooldownMs: providerCooldownMs,
ruleScope,
}; };
} }
return fallback; return { ...fallback, ruleScope };
} }
// #6842: non-backoff configured rules (e.g. status_402) previously never // #6842: non-backoff configured rules (e.g. status_402) previously never
// consulted providerRuleRegistry, so a provider-specific rule (like // consulted providerRuleRegistry, so a provider-specific rule (like
@@ -1789,12 +1831,15 @@ export function checkFallbackError(
) )
: null; : null;
const cooldownMs = providerMatch?.cooldownMs ?? configuredRule.cooldownMs ?? 0; const cooldownMs = providerMatch?.cooldownMs ?? configuredRule.cooldownMs ?? 0;
const ruleScope =
providerMatch && honorsRuleLockScope(provider) ? providerMatch.scope : undefined;
return { return {
shouldFallback: true, shouldFallback: true,
cooldownMs, cooldownMs,
baseCooldownMs: cooldownMs, baseCooldownMs: cooldownMs,
configuredCooldownMs: cooldownMs, configuredCooldownMs: cooldownMs,
reason: providerMatch?.reason ?? configuredRule.reason ?? RateLimitReason.UNKNOWN, reason: providerMatch?.reason ?? configuredRule.reason ?? RateLimitReason.UNKNOWN,
ruleScope,
}; };
} }

View File

@@ -27,6 +27,10 @@ import {
import { RateLimitReason } from "../../config/constants.ts"; import { RateLimitReason } from "../../config/constants.ts";
import { isProviderCircuitOpenResult, isRequestScopedUpstreamFailure } from "./comboPredicates.ts"; import { isProviderCircuitOpenResult, isRequestScopedUpstreamFailure } from "./comboPredicates.ts";
import { isCloudflareFingerprintRejection } from "../errorClassifier.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"; import type { ComboLogger, ResolvedComboTarget } from "./types.ts";
// Connection-level failure statuses: the provider connection itself is likely bad (upstream // Connection-level failure statuses: the provider connection itself is likely bad (upstream
@@ -60,7 +64,13 @@ export type ComboExhaustionSets = {
export type ApplyComboTargetExhaustionOptions = { export type ApplyComboTargetExhaustionOptions = {
result: { status: number; headers?: Headers | null }; result: { status: number; headers?: Headers | null };
fallbackResult: Parameters<typeof isProviderExhaustedReason>[0]; 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;
};
errorText: string; errorText: string;
rawModel: string; rawModel: string;
isTokenLimitBreach: boolean; isTokenLimitBreach: boolean;
@@ -86,6 +96,56 @@ export function applyComboTargetExhaustion(
const { result, sets, log, tag, errorText, structuredError } = opts; const { result, sets, log, tag, errorText, structuredError } = opts;
const provider = target.provider; 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. // #8133/#8137: auth-level failures (401/403) mean that connection's credentials are bad.
// Split out to keep applyComboTargetExhaustion under the complexity ceiling. // Split out to keep applyComboTargetExhaustion under the complexity ceiling.
// Cloudflare 1010 (a 403 carrying error_code 1010 / browser_signature_banned) is NOT an // Cloudflare 1010 (a 403 carrying error_code 1010 / browser_signature_banned) is NOT an
@@ -259,6 +319,35 @@ 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 * #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 * the provider connection itself is bad → skip remaining same-connection (or same-provider, when

View File

@@ -0,0 +1,437 @@
/**
* qwenTokenPlanQuotaFetcher.ts — Qwen Cloud / Alibaba Model Studio PERSONAL Token Plan
* quota fetcher (issue #9603, "quota is missing").
*
* The personal Token Plan (5-hour / 7-day sliding windows) has NO official OpenAPI —
* the console gateway is the only quota surface, and the inference API key does NOT
* authenticate it. Both portals read the same backend:
* - home.qwencloud.com portal → https://cs-data.qwencloud.com (default)
* - Model Studio console (intl) → https://bailian-singapore-cs.alibabacloud.com
*
* Transport (captured live 2026-08-13 from a logged-in session):
* POST {host}/data/api.json?product=sfm_bailian&action=IntlBroadScopeAspnGateway
* &api=zeldaHttp.apikeyMgr.%2Ftokenplan%2Fpersonal%2Fapi%2Fv2%2F<endpoint>
* form body: product, action, sec_token, region, params =
* {"Api":"zeldaHttp.apikeyMgr./tokenplan/personal/api/v2/<endpoint>","V":"1.0",
* "Data":{"commodityCode":"sfm_tokenplansolo_public_intl","cornerstoneParam":{...}}}
* Auth: browser session Cookie (providerSpecificData or QWEN_CLOUD_COOKIE env).
* sec_token: best-effort — resolved from the dashboard HTML (`SEC_TOKEN: "…"`) when
* not provided; some accounts reject requests without it
* (BailianGateway.Workspace.NotAuthorised).
*
* Windows: usage returns per<Window>Percentage (fraction used, 0..1) +
* per<Window>ResetTime (epoch ms). Fields are OMITTED while a window is
* "Temporarily Removed" (observed for 5-hour), so every window is optional.
*
* Cache: usage 60s per connection; subscription/quota-config (slow-moving tier data)
* 1h per connection. Registration: registerQwenTokenPlanQuotaFetcher() at startup.
*/
import { registerQuotaFetcher, registerQuotaWindows, type QuotaInfo } from "./quotaPreflight.ts";
import { registerMonitorFetcher } from "./quotaMonitor.ts";
import { throttleQuotaFetch } from "./quotaFetchThrottle.ts";
const DEFAULT_GATEWAY_HOST = "https://cs-data.qwencloud.com";
const DEFAULT_DASHBOARD_URL = "https://home.qwencloud.com/";
/**
* The same personal Token Plan is sold through two consoles that share one backend.
* The gateway validates the browser session against the console identity sent in the
* request, so an Alibaba cookie paired with the QwenCloud identity is rejected with
* `BailianGateway.Login.NotLogined` (verified live 2026-08-14).
*/
export interface TokenPlanConsoleSite {
consoleSite: "QWENCLOUD" | "ALIYUN";
domain: string;
gatewayHost: string;
dashboardUrl: string;
origin: string;
}
const CONSOLE_SITES: Record<"qwencloud" | "aliyun", TokenPlanConsoleSite> = {
qwencloud: {
consoleSite: "QWENCLOUD",
domain: "home.qwencloud.com",
gatewayHost: DEFAULT_GATEWAY_HOST,
dashboardUrl: DEFAULT_DASHBOARD_URL,
origin: "https://home.qwencloud.com",
},
aliyun: {
consoleSite: "ALIYUN",
domain: "modelstudio.console.alibabacloud.com",
gatewayHost: "https://bailian-singapore-cs.alibabacloud.com",
dashboardUrl: "https://modelstudio.console.alibabacloud.com/",
origin: "https://modelstudio.console.alibabacloud.com",
},
};
/** Providers served by the Alibaba (Model Studio) console rather than QwenCloud. */
const ALIYUN_CONSOLE_PROVIDERS = new Set(["bailian-coding-plan", "alibaba", "alibaba-cn"]);
/**
* Pick the console identity for a cookie: the login ticket names its console
* (`login_aliyunid_ticket` vs `login_qwencloud_ticket`). Unmarked cookies fall back to
* the provider, then to QwenCloud.
*/
export function resolveConsoleSite(
cookie: string,
provider: string | undefined
): TokenPlanConsoleSite {
if (/login_aliyunid_ticket=/.test(cookie)) return CONSOLE_SITES.aliyun;
if (/login_qwencloud_ticket=/.test(cookie)) return CONSOLE_SITES.qwencloud;
if (provider && ALIYUN_CONSOLE_PROVIDERS.has(provider)) return CONSOLE_SITES.aliyun;
return CONSOLE_SITES.qwencloud;
}
const GATEWAY_REGION = "ap-southeast-1";
const GATEWAY_PRODUCT = "sfm_bailian";
const GATEWAY_ACTION = "IntlBroadScopeAspnGateway";
const COMMODITY_CODE = "sfm_tokenplansolo_public_intl";
const TOKEN_PLAN_API_PREFIX = "zeldaHttp.apikeyMgr./tokenplan/personal/api/v2/";
const USAGE_CACHE_TTL_MS = 60_000;
const TIER_CACHE_TTL_MS = 60 * 60_000;
// Window keys surfaced to the dashboard / quota-window registry
export const QWEN_TOKEN_PLAN_WINDOW_5H = "window_5h";
export const QWEN_TOKEN_PLAN_WINDOW_WEEKLY = "window_weekly";
// usage payload field prefix → window key (fields: per<prefix>Percentage / per<prefix>ResetTime)
const WINDOW_FIELD_MAP: Record<string, string> = {
"5Hour": QWEN_TOKEN_PLAN_WINDOW_5H,
"1Week": QWEN_TOKEN_PLAN_WINDOW_WEEKLY,
};
export interface QwenTokenPlanQuota extends QuotaInfo {
windows: Record<string, { percentUsed: number; resetAt: string | null }>;
/** Which console served the quota — drives the plan label shown in the dashboard. */
consoleSite: TokenPlanConsoleSite["consoleSite"];
/** Subscription tier (e.g. "pro") or null when the subscription call failed. */
specCode: string | null;
/** Credit limits of the active tier (from quota-config), when resolvable. */
tierLimits: { fiveHour: number | null; weekly: number | null };
}
interface UsageCacheEntry {
quota: QwenTokenPlanQuota;
fetchedAt: number;
}
interface TierCacheEntry {
specCode: string | null;
tierLimits: { fiveHour: number | null; weekly: number | null };
fetchedAt: number;
}
const usageCache = new Map<string, UsageCacheEntry>();
const tierCache = new Map<string, TierCacheEntry>();
const secTokenCache = new Map<string, { token: string; fetchedAt: number }>();
const _cacheCleanup = setInterval(() => {
const now = Date.now();
for (const [key, entry] of usageCache) {
if (now - entry.fetchedAt > USAGE_CACHE_TTL_MS * 5) usageCache.delete(key);
}
for (const [key, entry] of tierCache) {
if (now - entry.fetchedAt > TIER_CACHE_TTL_MS * 2) tierCache.delete(key);
}
for (const [key, entry] of secTokenCache) {
if (now - entry.fetchedAt > TIER_CACHE_TTL_MS * 2) secTokenCache.delete(key);
}
}, 5 * 60_000);
if (typeof _cacheCleanup === "object" && "unref" in _cacheCleanup) {
(_cacheCleanup as { unref?: () => void }).unref?.();
}
// ─── Helpers ─────────────────────────────────────────────────────────────────
function toRecord(value: unknown): Record<string, unknown> {
return value && typeof value === "object" && !Array.isArray(value)
? (value as Record<string, unknown>)
: {};
}
function toNumberOrNull(value: unknown): number | null {
if (typeof value === "number" && Number.isFinite(value)) return value;
if (typeof value === "string") {
const parsed = parseFloat(value);
if (Number.isFinite(parsed)) return parsed;
}
return null;
}
function toTrimmedString(value: unknown): string {
return typeof value === "string" ? value.trim() : "";
}
function getCookie(providerSpecificData: Record<string, unknown> | undefined): string {
for (const key of ["qwenCloudCookie", "alibabaConsoleCookie", "cookie"]) {
const value = toTrimmedString(providerSpecificData?.[key]);
if (value) return value;
}
return process.env.QWEN_CLOUD_COOKIE?.trim() || "";
}
function getConfiguredSecToken(providerSpecificData: Record<string, unknown> | undefined): string {
for (const key of ["qwenCloudSecToken", "alibabaConsoleSecToken"]) {
const value = toTrimmedString(providerSpecificData?.[key]);
if (value) return value;
}
return process.env.QWEN_CLOUD_SEC_TOKEN?.trim() || "";
}
function getGatewayHost(site: TokenPlanConsoleSite): string {
const configured = process.env.QWEN_TOKEN_PLAN_HOST?.trim();
if (!configured) return site.gatewayHost;
return /^https?:\/\//i.test(configured) ? configured : `https://${configured}`;
}
function getDashboardUrl(site: TokenPlanConsoleSite): string {
return process.env.QWEN_TOKEN_PLAN_DASHBOARD_URL?.trim() || site.dashboardUrl;
}
/** Extract the console `SEC_TOKEN: "…"` embedded in the logged-in dashboard HTML. */
export function extractQwenSecToken(html: string): string | null {
const match = /SEC_?TOKEN["']?\s*[:=]\s*["']([^"']+)["']/i.exec(html);
return match ? match[1] : null;
}
async function resolveSecToken(
connectionId: string,
cookie: string,
site: TokenPlanConsoleSite
): Promise<string> {
const cached = secTokenCache.get(connectionId);
if (cached && Date.now() - cached.fetchedAt < TIER_CACHE_TTL_MS) {
return cached.token;
}
try {
const response = await fetch(getDashboardUrl(site), {
method: "GET",
headers: {
Cookie: cookie,
"User-Agent":
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0 Safari/537.36",
Accept: "text/html",
},
redirect: "follow",
signal: AbortSignal.timeout(8_000),
});
const html = await response.text();
const token = extractQwenSecToken(html);
if (token) {
secTokenCache.set(connectionId, { token, fetchedAt: Date.now() });
return token;
}
} catch {
// best-effort — some accounts work without sec_token
}
return "";
}
// ─── Gateway transport ───────────────────────────────────────────────────────
async function callGateway(
endpoint: string,
cookie: string,
secToken: string,
site: TokenPlanConsoleSite
): Promise<unknown | null> {
const api = `${TOKEN_PLAN_API_PREFIX}${endpoint}`;
const url = `${getGatewayHost(site)}/data/api.json?product=${GATEWAY_PRODUCT}&action=${GATEWAY_ACTION}&api=${encodeURIComponent(api)}`;
const params = JSON.stringify({
Api: api,
V: "1.0",
Data: {
commodityCode: COMMODITY_CODE,
cornerstoneParam: {
console: "ONE_CONSOLE",
consoleSite: site.consoleSite,
domain: site.domain,
productCode: "p_efm",
protocol: "V2",
xsp_lang: "en-US",
},
},
});
const body = new URLSearchParams({
product: GATEWAY_PRODUCT,
action: GATEWAY_ACTION,
sec_token: secToken,
region: GATEWAY_REGION,
params,
});
try {
// #6911: space concurrent upstream quota fetches (mirrors bailianQuotaFetcher.ts).
await throttleQuotaFetch();
const response = await fetch(url, {
method: "POST",
headers: {
Cookie: cookie,
"Content-Type": "application/x-www-form-urlencoded",
Accept: "application/json",
Origin: site.origin,
Referer: `${site.origin}/`,
},
body: body.toString(),
signal: AbortSignal.timeout(8_000),
});
const raw = await response.json();
return parseGatewayEnvelope(raw);
} catch {
// Network error, timeout, non-JSON (login redirect page) — fail open
return null;
}
}
/** Unwrap {code:"200", data:{DataV2:{data:{code:"SUCCESS", data:<payload>}}}} → payload. */
function parseGatewayEnvelope(raw: unknown): unknown | null {
const obj = toRecord(raw);
if (obj["code"] !== "200" && obj["code"] !== 200) return null;
const inner = toRecord(toRecord(toRecord(obj["data"])["DataV2"])["data"]);
if (inner["code"] !== "SUCCESS" || inner["success"] !== true) return null;
return inner["data"] ?? null;
}
// ─── Parsers ─────────────────────────────────────────────────────────────────
function parseUsageWindows(
payload: unknown
): Record<string, { percentUsed: number; resetAt: string | null }> {
const obj = toRecord(payload);
const windows: Record<string, { percentUsed: number; resetAt: string | null }> = {};
for (const [fieldPrefix, windowKey] of Object.entries(WINDOW_FIELD_MAP)) {
const percent = toNumberOrNull(obj[`per${fieldPrefix}Percentage`]);
if (percent === null) continue; // window omitted (e.g. 5-hour "Temporarily Removed")
const resetMs = toNumberOrNull(obj[`per${fieldPrefix}ResetTime`]);
windows[windowKey] = {
percentUsed: percent,
resetAt: resetMs && resetMs > 0 ? new Date(resetMs).toISOString() : null,
};
}
return windows;
}
async function resolveTierInfo(
connectionId: string,
cookie: string,
secToken: string,
site: TokenPlanConsoleSite
): Promise<TierCacheEntry> {
const cached = tierCache.get(connectionId);
if (cached && Date.now() - cached.fetchedAt < TIER_CACHE_TTL_MS) {
return cached;
}
const [quotaConfig, subscription] = await Promise.all([
callGateway("quota-config", cookie, secToken, site),
callGateway("subscription", cookie, secToken, site),
]);
const specCode = toTrimmedString(toRecord(subscription)["specCode"]) || null;
const tierRecord = specCode ? toRecord(toRecord(quotaConfig)[specCode]) : {};
const entry: TierCacheEntry = {
specCode,
tierLimits: {
fiveHour: toNumberOrNull(tierRecord["five_hour"]),
weekly: toNumberOrNull(tierRecord["weekly"]),
},
fetchedAt: Date.now(),
};
tierCache.set(connectionId, entry);
return entry;
}
// ─── Core fetcher ────────────────────────────────────────────────────────────
/**
* Fetch the personal Token Plan quota for a qwen-cloud-token-plan connection.
* Returns percentUsed = max across the windows present in the usage response,
* or null when no cookie is configured / the console session expired.
*/
export async function fetchQwenTokenPlanQuota(
connectionId: string,
connection?: Record<string, unknown>
): Promise<QuotaInfo | null> {
const cached = usageCache.get(connectionId);
if (cached && Date.now() - cached.fetchedAt < USAGE_CACHE_TTL_MS) {
return cached.quota;
}
const providerSpecificData =
connection?.providerSpecificData &&
typeof connection.providerSpecificData === "object" &&
!Array.isArray(connection.providerSpecificData)
? (connection.providerSpecificData as Record<string, unknown>)
: undefined;
const cookie = getCookie(providerSpecificData);
if (!cookie) return null;
const site = resolveConsoleSite(
cookie,
typeof connection?.provider === "string" ? connection.provider : undefined
);
const secToken =
getConfiguredSecToken(providerSpecificData) ||
(await resolveSecToken(connectionId, cookie, site));
const usagePayload = await callGateway("usage", cookie, secToken, site);
if (usagePayload === null) return null;
const windows = parseUsageWindows(usagePayload);
const windowEntries = Object.values(windows);
if (windowEntries.length === 0) return null;
const worst = windowEntries.reduce((max, w) => (w.percentUsed > max.percentUsed ? w : max));
const tier = await resolveTierInfo(connectionId, cookie, secToken, site);
const total = tier.tierLimits.weekly ?? 100;
const quota: QwenTokenPlanQuota = {
used: Math.round(worst.percentUsed * total),
total,
percentUsed: worst.percentUsed,
resetAt: worst.resetAt,
windows,
consoleSite: site.consoleSite,
specCode: tier.specCode,
tierLimits: tier.tierLimits,
limitReached: worst.percentUsed >= 1,
};
usageCache.set(connectionId, { quota, fetchedAt: Date.now() });
return quota;
}
// ─── Invalidation ────────────────────────────────────────────────────────────
export function invalidateQwenTokenPlanQuotaCache(connectionId: string): void {
usageCache.delete(connectionId);
tierCache.delete(connectionId);
secTokenCache.delete(connectionId);
}
// ─── Registration ────────────────────────────────────────────────────────────
/**
* Register the Qwen Token Plan quota fetcher with the preflight and monitor systems.
* Call once at server startup (src/sse/handlers/chat.ts), BEFORE registerGenericQuotaFetchers().
*/
export function registerQwenTokenPlanQuotaFetcher(): void {
registerQuotaFetcher("qwen-cloud-token-plan", fetchQwenTokenPlanQuota);
registerMonitorFetcher("qwen-cloud-token-plan", fetchQwenTokenPlanQuota);
registerQuotaWindows("qwen-cloud-token-plan", [
QWEN_TOKEN_PLAN_WINDOW_5H,
QWEN_TOKEN_PLAN_WINDOW_WEEKLY,
]);
}

View File

@@ -69,6 +69,7 @@ import { getXaiOauthUsage } from "./usage/xaiOauth.ts";
import { getGrokCliUsage } from "./usage/grokCli.ts"; import { getGrokCliUsage } from "./usage/grokCli.ts";
import { getFirecrawlUsage } from "./usage/firecrawl.ts"; import { getFirecrawlUsage } from "./usage/firecrawl.ts";
import { getCommandCodeUsage } from "./usage/command-code.ts"; import { getCommandCodeUsage } from "./usage/command-code.ts";
import { getQwenTokenPlanUsage } from "./usage/qwen-token-plan.ts";
import { getConolUsage } from "./conolUsage.ts"; import { getConolUsage } from "./conolUsage.ts";
type JsonRecord = Record<string, unknown>; type JsonRecord = Record<string, unknown>;
@@ -111,6 +112,7 @@ export const USAGE_FETCHER_PROVIDERS = [
"minimax-cn", "minimax-cn",
"crof", "crof",
"bailian-coding-plan", "bailian-coding-plan",
"qwen-cloud-token-plan",
"nanogpt", "nanogpt",
"deepseek", "deepseek",
"opencode", "opencode",
@@ -202,6 +204,8 @@ export async function getUsageForProvider(
return await getCrofUsage(apiKey || ""); return await getCrofUsage(apiKey || "");
case "bailian-coding-plan": case "bailian-coding-plan":
return await getBailianCodingPlanUsage(id || "", apiKey || "", providerSpecificData); return await getBailianCodingPlanUsage(id || "", apiKey || "", providerSpecificData);
case "qwen-cloud-token-plan":
return await getQwenTokenPlanUsage(id || "", apiKey || "", providerSpecificData);
case "nanogpt": case "nanogpt":
return await getNanoGptUsage(apiKey || ""); return await getNanoGptUsage(apiKey || "");
case "deepseek": case "deepseek":

View File

@@ -10,6 +10,7 @@
*/ */
import { fetchBailianQuota, type BailianTripleWindowQuota } from "../bailianQuotaFetcher.ts"; import { fetchBailianQuota, type BailianTripleWindowQuota } from "../bailianQuotaFetcher.ts";
import { getQwenTokenPlanUsage } from "./qwen-token-plan.ts";
/** /**
* Bailian (Alibaba Token Plan) Usage * Bailian (Alibaba Token Plan) Usage
@@ -21,11 +22,25 @@ export async function getBailianCodingPlanUsage(
providerSpecificData?: Record<string, unknown> providerSpecificData?: Record<string, unknown>
) { ) {
try { try {
// The catalog entry is "Alibaba Token Plan" and now points at the Token Plan
// endpoint, so prefer the Token Plan quota (console cookie) when one is
// configured. The Coding Plan path below stays as the fallback for accounts
// that really do hold a Coding Plan key (#9603).
const tokenPlanUsage = await getQwenTokenPlanUsage(
connectionId,
apiKey,
providerSpecificData,
"bailian-coding-plan"
);
if ("quotas" in tokenPlanUsage) return tokenPlanUsage;
const connection = { apiKey, providerSpecificData }; const connection = { apiKey, providerSpecificData };
const quota = await fetchBailianQuota(connectionId, connection); const quota = await fetchBailianQuota(connectionId, connection);
if (!quota) { if (!quota) {
return { message: "Alibaba Token Plan connected. Unable to fetch quota." }; // Neither surface answered — surface the Token Plan guidance, which tells the
// operator how to supply the cookie the console gateway requires.
return tokenPlanUsage;
} }
const bailianQuota = quota as BailianTripleWindowQuota; const bailianQuota = quota as BailianTripleWindowQuota;

View File

@@ -0,0 +1,96 @@
/**
* usage/qwen-token-plan.ts — Qwen Cloud / Alibaba Model Studio personal Token Plan
* usage leaf (issue #9603).
*
* Delegates to qwenTokenPlanQuotaFetcher (cookie-authenticated console gateway) and
* shapes the 5-hour / weekly sliding windows into the standard usage response. The
* inference API key cannot read this quota — the connection needs a console session
* cookie in providerSpecificData (qwenCloudCookie / alibabaConsoleCookie / cookie)
* or the QWEN_CLOUD_COOKIE env var.
*/
import {
fetchQwenTokenPlanQuota,
QWEN_TOKEN_PLAN_WINDOW_5H,
QWEN_TOKEN_PLAN_WINDOW_WEEKLY,
type QwenTokenPlanQuota,
} from "../qwenTokenPlanQuotaFetcher.ts";
import type { UsageQuota } from "./quota.ts";
function windowToQuota(
window: { percentUsed: number; resetAt: string | null } | undefined,
totalCredits: number | null,
displayName: string
): UsageQuota | null {
if (!window) return null;
const total = totalCredits ?? 100;
const used = Math.round(window.percentUsed * total);
const remaining = Math.max(0, total - used);
return {
used,
total,
remaining,
remainingPercentage: Math.round((1 - window.percentUsed) * 1000) / 10,
resetAt: window.resetAt,
unlimited: false,
displayName,
};
}
/**
* Qwen Cloud personal Token Plan usage (5-hour + weekly sliding windows).
*/
export async function getQwenTokenPlanUsage(
connectionId: string,
apiKey: string,
providerSpecificData?: Record<string, unknown>,
provider = "qwen-cloud-token-plan"
) {
try {
const quota = await fetchQwenTokenPlanQuota(connectionId, {
apiKey,
providerSpecificData,
provider,
});
if (!quota) {
return {
message:
"Qwen Token Plan connected. Quota needs a console session cookie — the inference " +
"API key cannot read it. Get it at home.qwencloud.com Billing Subscription " +
"(logged in): F12 Network, reload, filter by api.json, click a request to " +
"cs-data.qwencloud.com and copy the whole Cookie value from Request Headers " +
"(it contains login_qwencloud_ticket). Paste it into the connection's " +
"'Qwen / Model Studio console cookie' field, or set QWEN_CLOUD_COOKIE. " +
"The cookie expires with the browser session — re-paste it when this message returns.",
};
}
const tokenPlanQuota = quota as QwenTokenPlanQuota;
const quotas: Record<string, UsageQuota> = {};
const fiveHour = windowToQuota(
tokenPlanQuota.windows[QWEN_TOKEN_PLAN_WINDOW_5H],
tokenPlanQuota.tierLimits.fiveHour,
"5-hour window"
);
if (fiveHour) quotas.five_hour = fiveHour;
const weekly = windowToQuota(
tokenPlanQuota.windows[QWEN_TOKEN_PLAN_WINDOW_WEEKLY],
tokenPlanQuota.tierLimits.weekly,
"Weekly window"
);
if (weekly) quotas.weekly = weekly;
const specCode = tokenPlanQuota.specCode;
const brand = tokenPlanQuota.consoleSite === "ALIYUN" ? "Alibaba" : "Qwen";
const plan = specCode
? `${brand} Token Plan (${specCode.charAt(0).toUpperCase()}${specCode.slice(1)})`
: `${brand} Token Plan`;
return { plan, quotas };
} catch (error) {
return { message: `Qwen Token Plan error: ${(error as Error).message}` };
}
}

View File

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

View File

@@ -43,15 +43,14 @@ export const KNOWN_DUPLICATE_VERSIONS = new Set([
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// ALLOWLIST 2 — gaps de sequência CONHECIDOS. // ALLOWLIST 2 — gaps de sequência CONHECIDOS.
// Fonte: auditoria do disco (src/lib/db/migrations/). Além dos slots legados, // Fonte: auditoria do disco (src/lib/db/migrations/). Além dos slots legados,
// 144145 seguem reservados pelas migrations Radar que já existem na série // As migrations Radar 144145 e a migration 143 já aterrissaram. O job registry
// empilhada; a migration 143 já aterrissou. O job registry foi promovido de 139 // foi promovido de 139 para 146 pela tabela RENAMED_MIGRATION_COMPATIBILITY. A
// para 146 pela tabela RENAMED_MIGRATION_COMPATIBILITY. A
// 147149 estão reservadas por migrations atualmente em trânsito nos PRs #8228, // 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. // #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 // O stale-enforcement exige que cada reserva seja removida quando os arquivos
// correspondentes aterrissarem na release. // correspondentes aterrissarem na release.
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
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) 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)
function pad3(n) { function pad3(n) {
return String(n).padStart(3, "0"); return String(n).padStart(3, "0");

View File

@@ -22,7 +22,6 @@ import { HomeProviderTopologySection } from "./HomeProviderTopologySection";
import { shouldShowProviderTopologyOnHome } from "./homeAppearance"; import { shouldShowProviderTopologyOnHome } from "./homeAppearance";
const ProviderQuotaWidget = dynamic(() => import("../home/ProviderQuotaWidget"), { ssr: false }); const ProviderQuotaWidget = dynamic(() => import("../home/ProviderQuotaWidget"), { ssr: false });
import type { NewsAnnouncement } from "@/shared/utils/releaseNotes";
type UpdateStep = { type UpdateStep = {
step: string; step: string;
@@ -37,7 +36,6 @@ type VersionInfo = {
channel: string; channel: string;
autoUpdateSupported: boolean; autoUpdateSupported: boolean;
autoUpdateError?: string | null; autoUpdateError?: string | null;
news?: NewsAnnouncement | null;
}; };
type HomePageClientProps = { type HomePageClientProps = {
@@ -1047,37 +1045,6 @@ export default function HomePageClient({ machineId }: HomePageClientProps) {
</div> </div>
)} )}
</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> </div>
)} )}

View File

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

View File

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

View File

@@ -340,6 +340,8 @@ export default function EditConnectionModal({
opencodeGoAuthCookie: "", opencodeGoAuthCookie: "",
ollamaCloudUsageCookie: "", ollamaCloudUsageCookie: "",
alibabaConsoleCookie: stringField(connection.providerSpecificData?.alibabaConsoleCookie), alibabaConsoleCookie: stringField(connection.providerSpecificData?.alibabaConsoleCookie),
qwenCloudCookie: stringField(connection.providerSpecificData?.qwenCloudCookie),
qwenCloudSecToken: stringField(connection.providerSpecificData?.qwenCloudSecToken),
alibabaConsoleSecToken: stringField( alibabaConsoleSecToken: stringField(
connection.providerSpecificData?.alibabaConsoleSecToken connection.providerSpecificData?.alibabaConsoleSecToken
), ),

View File

@@ -3,44 +3,16 @@
import { Input } from "@/shared/components"; import { Input } from "@/shared/components";
import { providerText, type ProviderMessageTranslator } from "../../providerPageHelpers"; import { providerText, type ProviderMessageTranslator } from "../../providerPageHelpers";
export type QuotaScrapingFieldValues = { import {
opencodeGoWorkspaceId: string; assignQuotaScrapingProviderData,
opencodeGoAuthCookie: string; EMPTY_QUOTA_SCRAPING_FIELDS,
ollamaCloudUsageCookie: string; QWEN_TOKEN_PLAN_PROVIDERS,
alibabaConsoleCookie: string; type QuotaScrapingFieldValues,
alibabaConsoleSecToken: string; } from "./quotaScrapingFieldValues";
};
export const EMPTY_QUOTA_SCRAPING_FIELDS: QuotaScrapingFieldValues = { // Re-exported so existing importers (modals, tests) keep their current paths.
opencodeGoWorkspaceId: "", export { assignQuotaScrapingProviderData, EMPTY_QUOTA_SCRAPING_FIELDS };
opencodeGoAuthCookie: "", export type { QuotaScrapingFieldValues };
ollamaCloudUsageCookie: "",
alibabaConsoleCookie: "",
alibabaConsoleSecToken: "",
};
export function assignQuotaScrapingProviderData(
provider: string | undefined,
values: QuotaScrapingFieldValues,
target: Record<string, unknown>
) {
if (provider === "opencode-go") {
target.opencodeGoWorkspaceId = values.opencodeGoWorkspaceId.trim() || undefined;
if (values.opencodeGoAuthCookie.trim()) {
target.opencodeGoAuthCookie = values.opencodeGoAuthCookie.trim();
}
} else if (provider === "ollama-cloud" && values.ollamaCloudUsageCookie.trim()) {
target.ollamaCloudUsageCookie = values.ollamaCloudUsageCookie.trim();
} else if (
(provider === "alibaba" || provider === "alibaba-cn") &&
values.alibabaConsoleCookie.trim()
) {
target.alibabaConsoleCookie = values.alibabaConsoleCookie.trim();
if (values.alibabaConsoleSecToken.trim()) {
target.alibabaConsoleSecToken = values.alibabaConsoleSecToken.trim();
}
}
}
type QuotaScrapingFieldsProps = { type QuotaScrapingFieldsProps = {
provider?: string; provider?: string;
@@ -170,5 +142,50 @@ export default function QuotaScrapingFields({
); );
} }
if (QWEN_TOKEN_PLAN_PROVIDERS.has(provider ?? "")) {
return (
<div className="flex flex-col gap-3 rounded-lg border border-border/50 bg-surface/20 p-4">
<Input
label={providerText(t, "qwenCloudCookieLabel", "Qwen / Model Studio console cookie")}
name="qwenCloudCookie"
type="password"
value={values.qwenCloudCookie}
onChange={(e) => onChange({ qwenCloudCookie: e.target.value })}
placeholder="cna=...; login_qwencloud_ticket=...; ..."
hint={providerText(
t,
"qwenCloudCookieHint",
(editMode ? "Leave blank to keep the stored cookie. " : "") +
"Required for Token Plan quota — the inference API key cannot read it. " +
"How to get it: open home.qwencloud.com Billing Subscription while logged in, " +
"press F12 Network, reload the page, filter by api.json, click any request to " +
"cs-data.qwencloud.com, then under Request Headers copy the WHOLE Cookie value " +
"(it contains login_qwencloud_ticket). It expires with the browser session — " +
"re-paste it when the quota reports an expired session."
)}
autoComplete="off"
spellCheck={false}
autoCapitalize="off"
/>
<Input
label={providerText(t, "qwenCloudSecTokenLabel", "Qwen console sec_token (optional)")}
name="qwenCloudSecToken"
type="password"
value={values.qwenCloudSecToken}
onChange={(e) => onChange({ qwenCloudSecToken: e.target.value })}
placeholder="GjRV..."
hint={providerText(
t,
"qwenCloudSecTokenHint",
"Optional — resolved automatically from the dashboard. Set it only if quota sync reports a permission error."
)}
autoComplete="off"
spellCheck={false}
autoCapitalize="off"
/>
</div>
);
}
return null; return null;
} }

View File

@@ -0,0 +1,64 @@
/**
* quotaScrapingFieldValues.ts — form-state shape + persistence rules for the
* quota-scraping credential fields (cookies / workspace ids) rendered by
* QuotaScrapingFields.tsx.
*
* Kept in a UI-free module on purpose: importing the .tsx pulls in
* `@/shared/components`, whose barrel reaches untranspiled ESM deps
* (@lobehub/icons) that the node:test runner cannot parse. Unit tests import
* this file instead; the component re-exports it for existing callers.
*/
/** Providers whose quota lives behind the Qwen/Model Studio console gateway (#9603). */
export const QWEN_TOKEN_PLAN_PROVIDERS = new Set(["qwen-cloud-token-plan", "bailian-coding-plan"]);
export type QuotaScrapingFieldValues = {
opencodeGoWorkspaceId: string;
opencodeGoAuthCookie: string;
ollamaCloudUsageCookie: string;
alibabaConsoleCookie: string;
alibabaConsoleSecToken: string;
qwenCloudCookie: string;
qwenCloudSecToken: string;
};
export const EMPTY_QUOTA_SCRAPING_FIELDS: QuotaScrapingFieldValues = {
opencodeGoWorkspaceId: "",
opencodeGoAuthCookie: "",
ollamaCloudUsageCookie: "",
alibabaConsoleCookie: "",
alibabaConsoleSecToken: "",
qwenCloudCookie: "",
qwenCloudSecToken: "",
};
export function assignQuotaScrapingProviderData(
provider: string | undefined,
values: QuotaScrapingFieldValues,
target: Record<string, unknown>
) {
if (provider === "opencode-go") {
target.opencodeGoWorkspaceId = values.opencodeGoWorkspaceId.trim() || undefined;
if (values.opencodeGoAuthCookie.trim()) {
target.opencodeGoAuthCookie = values.opencodeGoAuthCookie.trim();
}
} else if (provider === "ollama-cloud" && values.ollamaCloudUsageCookie.trim()) {
target.ollamaCloudUsageCookie = values.ollamaCloudUsageCookie.trim();
} else if (
(provider === "alibaba" || provider === "alibaba-cn") &&
values.alibabaConsoleCookie.trim()
) {
target.alibabaConsoleCookie = values.alibabaConsoleCookie.trim();
if (values.alibabaConsoleSecToken.trim()) {
target.alibabaConsoleSecToken = values.alibabaConsoleSecToken.trim();
}
} else if (QWEN_TOKEN_PLAN_PROVIDERS.has(provider ?? "") && values.qwenCloudCookie?.trim()) {
// Optional access: callers (AddApiKeyModal/EditConnectionModal form state, and
// existing tests) may pass a partial form object without the newer fields —
// bailian-coding-plan previously matched no branch here at all.
target.qwenCloudCookie = values.qwenCloudCookie.trim();
if (values.qwenCloudSecToken?.trim()) {
target.qwenCloudSecToken = values.qwenCloudSecToken.trim();
}
}
}

View File

@@ -0,0 +1,381 @@
"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

@@ -0,0 +1,201 @@
"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>
);
}

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