busbar-ai 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +120 -115
- package/app/.next-cli-build/BUILD_ID +1 -1
- package/app/.next-cli-build/app-path-routes-manifest.json +19 -19
- package/app/.next-cli-build/build-manifest.json +2 -2
- package/app/.next-cli-build/prerender-manifest.json +2 -2
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/proxy-pools/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/pxpipe/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/token-saver/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/_global-error.html +1 -1
- package/app/.next-cli-build/server/app/_global-error.rsc +1 -1
- package/app/.next-cli-build/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/_not-found.html +1 -1
- package/app/.next-cli-build/server/app/_not-found.rsc +3 -3
- package/app/.next-cli-build/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/api/models/route.js +1 -1
- package/app/.next-cli-build/server/app/api/providers/route.js +1 -1
- package/app/.next-cli-build/server/app/api/translator/console-logs/route.js +1 -1
- package/app/.next-cli-build/server/app/api/translator/console-logs/stream/route.js +1 -1
- package/app/.next-cli-build/server/app/api/version/route.js +1 -1
- package/app/.next-cli-build/server/app/api/version/shutdown/route.js +1 -1
- package/app/.next-cli-build/server/app/api/version/update/route.js +1 -1
- package/app/.next-cli-build/server/app/callback/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/callback.html +1 -1
- package/app/.next-cli-build/server/app/callback.rsc +3 -3
- package/app/.next-cli-build/server/app/callback.segments/_full.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/callback.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/callback.segments/callback/__PAGE__.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/basic-chat.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/basic-chat.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat/__PAGE__.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_full.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/cli-tools.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/cli-tools.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools/__PAGE__.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_full.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/combos.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/combos.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos/__PAGE__.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/combos.segments/_full.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/combos.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/endpoint.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/endpoint.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint/__PAGE__.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_full.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web/__PAGE__.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_full.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/mitm.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/mitm.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm/__PAGE__.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/mitm.segments/_full.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/mitm.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/profile.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/profile.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile/__PAGE__.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/profile.segments/_full.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/profile.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers/new.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers/new.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new/__PAGE__.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_full.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers/__PAGE__.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/providers.segments/_full.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/providers.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools/__PAGE__.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_full.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/pxpipe.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/pxpipe.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard/pxpipe/__PAGE__.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_full.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/quota.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/quota.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota/__PAGE__.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/quota.segments/_full.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/quota.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing/__PAGE__.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/skills.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/skills.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk/dashboard/skills/__PAGE__.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/skills.segments/_full.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/skills.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/token-saver.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/token-saver.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard/token-saver/__PAGE__.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/token-saver.segments/_full.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/token-saver.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/translator.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/translator.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator/__PAGE__.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/translator.segments/_full.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/translator.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/usage.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/usage.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage/__PAGE__.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/usage.segments/_full.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/usage.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard.html +1 -1
- package/app/.next-cli-build/server/app/dashboard.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard/__PAGE__.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard.segments/_full.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/index.html +1 -1
- package/app/.next-cli-build/server/app/index.rsc +3 -3
- package/app/.next-cli-build/server/app/index.segments/__PAGE__.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/index.segments/_full.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/index.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/landing/page.js +1 -1
- package/app/.next-cli-build/server/app/landing/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/landing.html +1 -1
- package/app/.next-cli-build/server/app/landing.rsc +4 -4
- package/app/.next-cli-build/server/app/landing.segments/_full.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/landing.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/landing.segments/landing/__PAGE__.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/login/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/login.html +1 -1
- package/app/.next-cli-build/server/app/login.rsc +3 -3
- package/app/.next-cli-build/server/app/login.segments/_full.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/login.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/login.segments/login/__PAGE__.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app-paths-manifest.json +19 -19
- package/app/.next-cli-build/server/chunks/1133.js +1 -1
- package/app/.next-cli-build/server/chunks/1350.js +1 -1
- package/app/.next-cli-build/server/chunks/2318.js +1 -1
- package/app/.next-cli-build/server/chunks/2764.js +1 -1
- package/app/.next-cli-build/server/chunks/412.js +1 -1
- package/app/.next-cli-build/server/chunks/436.js +1 -1
- package/app/.next-cli-build/server/chunks/6877.js +1 -1
- package/app/.next-cli-build/server/chunks/716.js +1 -1
- package/app/.next-cli-build/server/chunks/8238.js +1 -1
- package/app/.next-cli-build/server/middleware-build-manifest.js +1 -1
- package/app/.next-cli-build/server/pages/404.html +1 -1
- package/app/.next-cli-build/server/pages/500.html +1 -1
- package/app/.next-cli-build/static/chunks/{1321-440881581f681064.js → 1321-5df4810e8afd778c.js} +1 -1
- package/app/.next-cli-build/static/chunks/{5497-c9880cc4ac4d8a42.js → 5497-3037d5b4d70a4cc8.js} +2 -2
- package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/skills/page-bccc40958c066d7a.js +1 -0
- package/app/.next-cli-build/static/chunks/app/landing/page-f3fcddb38b64683f.js +1 -0
- package/app/cli/.build-home/AppData/Roaming/9router/db/data.sqlite-shm +0 -0
- package/app/cli/.build-home/AppData/Roaming/9router/db/data.sqlite-wal +0 -0
- package/app/package.json +2 -1
- package/app/public/paypal-qr.png +0 -0
- package/app/public/paypal-qr.svg +1 -0
- package/cli.js +888 -888
- package/package.json +3 -2
- package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/skills/page-7ce0c03d90f7fa44.js +0 -1
- package/app/.next-cli-build/static/chunks/app/landing/page-c2281d0269a6adab.js +0 -1
- /package/app/.next-cli-build/static/{IWMKFD-rCH-KfRpvTgTqk → s5jg02dt7_Ke0ZVHd5w0-}/_buildManifest.js +0 -0
- /package/app/.next-cli-build/static/{IWMKFD-rCH-KfRpvTgTqk → s5jg02dt7_Ke0ZVHd5w0-}/_ssgManifest.js +0 -0
package/README.md
CHANGED
|
@@ -1,115 +1,120 @@
|
|
|
1
|
-
<div align="center">
|
|
2
|
-
<img src="https://raw.githubusercontent.com/TejasLamba2006/busbar/main/public/banner.png" alt="Busbar" width="100%"/>
|
|
3
|
-
|
|
4
|
-
# Busbar
|
|
5
|
-
|
|
6
|
-
**A local LLM multiplexer. One `/v1` endpoint in front of 291 providers.**
|
|
7
|
-
|
|
8
|
-
In electrical engineering, a busbar is the solid copper strip that collects power from multiple sources and feeds every circuit on one common rail. Busbar does the same for 291 LLM providers on `localhost:20128/v1`.
|
|
9
|
-
|
|
10
|
-
[](https://www.npmjs.com/package/busbar)
|
|
11
|
-
[](LICENSE)
|
|
12
|
-
</div>
|
|
13
|
-
|
|
14
|
-
## What Busbar is
|
|
15
|
-
|
|
16
|
-
Busbar is a local gateway that speaks the OpenAI, Anthropic, and Gemini APIs on port `20128`. It connects 291 native providers behind one `/v1` endpoint: OAuth subscriptions, API keys, free tiers, aggregators, local models, web search, web fetch, TTS, STT, image, video, and embeddings.
|
|
17
|
-
|
|
18
|
-
Point your tools at it, add accounts in the dashboard, and it handles format translation, model combos, multi-account fallback, token refresh, and usage tracking.
|
|
19
|
-
|
|
20
|
-
Busbar is a fork of [9Router](https://github.com/decolua/9router). The on-disk data directory is still `9router`, so existing databases, API keys, and connections keep loading.
|
|
21
|
-
|
|
22
|
-
## Why Busbar exists
|
|
23
|
-
|
|
24
|
-
### Why OmniRoute feels bloated
|
|
25
|
-
|
|
26
|
-
OmniRoute grew into a monolith: 193 SQLite migrations, 90+ CI ratchet scripts, embedded A2A/ACP agent servers, Qdrant vector memory, gamification, sponsor banners, chaos mode, streaming regex PII redaction that mutates payloads, and a 25-file heuristic router. It uses more RAM, starts slowly, and ships features a local gateway should not run.
|
|
27
|
-
|
|
28
|
-
### Why stock 9Router was not enough
|
|
29
|
-
|
|
30
|
-
Stock 9Router is fast and lean, but:
|
|
31
|
-
|
|
32
|
-
- It ships about 144 providers.
|
|
33
|
-
- The dashboard has no provider/model search and no category or media filtering.
|
|
34
|
-
- `/v1/models` blocks for 15 to 23 seconds waiting on slow upstream catalogs.
|
|
35
|
-
- No native `web_search` and `web_fetch` server-tool redirects for non-Anthropic models.
|
|
36
|
-
- It lacks multi-proxy failover and stealth-model reasoning fixes.
|
|
37
|
-
|
|
38
|
-
### What Busbar adds
|
|
39
|
-
|
|
40
|
-
Busbar keeps 9Router's footprint and ports the useful parts of OmniRoute without the rest.
|
|
41
|
-
|
|
42
|
-
1. **291 native providers and a filter bar.** 150+ additional providers with config-driven connection testing. The dashboard has instant search by provider or model ID, `All | Configured | Compact` views, 13 category chips, and 7 media-kind filters.
|
|
43
|
-
2. **Sub-second `/v1/models` (23.4s to 1.0s).** Catalogs refresh in the background and persist in the SQLite `kv` table, so `/v1/models` never waits on the Kiro, Qoder, Copilot, or Cursor resolvers.
|
|
44
|
-
3. **Native `web_search` and `web_fetch` redirect.** Claude Code's web search and fetch tools work on Gemini, DeepSeek, GLM, Codex, or any OpenAI model, routed through Exa, Brave, Tavily, Serper, or SearXNG. Includes SSRF protection and domain filtering.
|
|
45
|
-
4. **Claude Code auto-permission classifier compat.** The optional `claudeClassifierCompat` setting lets non-Claude models answer Claude Code's security classifier without failing permission prompts.
|
|
46
|
-
5. **Per-connection proxy pool rotation and local direct toggle.** Rotate requests across Cloudflare workers, SOCKS5/HTTP proxies, and your own IP (`__local__`), per connection or per retry. Timed-out relays are skipped without locking the upstream account.
|
|
47
|
-
6. **Streaming empty-turn retry and thinking-signature recovery.** The first 128 KB of every upstream SSE stream is cloned and checked, so empty or aborted turns retry before bytes reach the client. Claude 5/5.5 `CAIS` protobuf signatures are validated, Vertex `thoughtSignature` poisoning is fixed, and invalid historical thinking signatures are recovered automatically.
|
|
48
|
-
7. **`models.dev` auto-pricing.** 4-rate pricing (input, output, cache read, cache write/reasoning) across 2,180+ model basenames, including custom Azure and OpenAI-compatible deployments.
|
|
49
|
-
8. **RTK and Headroom protected-tools guard.** Output from `Read`, `Edit`, `Write`, `Grep`, `NotebookEdit`, `MultiEdit`, `patch`, `apply_patch`, and `anchor
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
busbar
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
export
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
export
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
npm
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
- [
|
|
111
|
-
- [
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/TejasLamba2006/busbar/main/public/banner.png" alt="Busbar" width="100%"/>
|
|
3
|
+
|
|
4
|
+
# Busbar
|
|
5
|
+
|
|
6
|
+
**A local LLM multiplexer. One `/v1` endpoint in front of 291 providers.**
|
|
7
|
+
|
|
8
|
+
In electrical engineering, a busbar is the solid copper strip that collects power from multiple sources and feeds every circuit on one common rail. Busbar does the same for 291 LLM providers on `localhost:20128/v1`.
|
|
9
|
+
|
|
10
|
+
[](https://www.npmjs.com/package/busbar-ai)
|
|
11
|
+
[](LICENSE)
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
## What Busbar is
|
|
15
|
+
|
|
16
|
+
Busbar is a local gateway that speaks the OpenAI, Anthropic, and Gemini APIs on port `20128`. It connects 291 native providers behind one `/v1` endpoint: OAuth subscriptions, API keys, free tiers, aggregators, local models, web search, web fetch, TTS, STT, image, video, and embeddings.
|
|
17
|
+
|
|
18
|
+
Point your tools at it, add accounts in the dashboard, and it handles format translation, model combos, multi-account fallback, token refresh, and usage tracking.
|
|
19
|
+
|
|
20
|
+
Busbar is a fork of [9Router](https://github.com/decolua/9router). The on-disk data directory is still `9router`, so existing databases, API keys, and connections keep loading.
|
|
21
|
+
|
|
22
|
+
## Why Busbar exists
|
|
23
|
+
|
|
24
|
+
### Why OmniRoute feels bloated
|
|
25
|
+
|
|
26
|
+
OmniRoute grew into a monolith: 193 SQLite migrations, 90+ CI ratchet scripts, embedded A2A/ACP agent servers, Qdrant vector memory, gamification, sponsor banners, chaos mode, streaming regex PII redaction that mutates payloads, and a 25-file heuristic router. It uses more RAM, starts slowly, and ships features a local gateway should not run.
|
|
27
|
+
|
|
28
|
+
### Why stock 9Router was not enough
|
|
29
|
+
|
|
30
|
+
Stock 9Router is fast and lean, but:
|
|
31
|
+
|
|
32
|
+
- It ships about 144 providers.
|
|
33
|
+
- The dashboard has no provider/model search and no category or media filtering.
|
|
34
|
+
- `/v1/models` blocks for 15 to 23 seconds waiting on slow upstream catalogs.
|
|
35
|
+
- No native `web_search` and `web_fetch` server-tool redirects for non-Anthropic models.
|
|
36
|
+
- It lacks multi-proxy failover and stealth-model reasoning fixes.
|
|
37
|
+
|
|
38
|
+
### What Busbar adds
|
|
39
|
+
|
|
40
|
+
Busbar keeps 9Router's footprint and ports the useful parts of OmniRoute without the rest.
|
|
41
|
+
|
|
42
|
+
1. **291 native providers and a filter bar.** 150+ additional providers with config-driven connection testing. The dashboard has instant search by provider or model ID, `All | Configured | Compact` views, 13 category chips, and 7 media-kind filters.
|
|
43
|
+
2. **Sub-second `/v1/models` (23.4s to 1.0s).** Catalogs refresh in the background and persist in the SQLite `kv` table, so `/v1/models` never waits on the Kiro, Qoder, Copilot, or Cursor resolvers.
|
|
44
|
+
3. **Native `web_search` and `web_fetch` redirect.** Claude Code's web search and fetch tools work on Gemini, DeepSeek, GLM, Codex, or any OpenAI model, routed through Exa, Brave, Tavily, Serper, or SearXNG. Includes SSRF protection and domain filtering.
|
|
45
|
+
4. **Claude Code auto-permission classifier compat.** The optional `claudeClassifierCompat` setting lets non-Claude models answer Claude Code's security classifier without failing permission prompts.
|
|
46
|
+
5. **Per-connection proxy pool rotation and local direct toggle.** Rotate requests across Cloudflare workers, SOCKS5/HTTP proxies, and your own IP (`__local__`), per connection or per retry. Timed-out relays are skipped without locking the upstream account.
|
|
47
|
+
6. **Streaming empty-turn retry and thinking-signature recovery.** The first 128 KB of every upstream SSE stream is cloned and checked, so empty or aborted turns retry before bytes reach the client. Claude 5/5.5 `CAIS` protobuf signatures are validated, Vertex `thoughtSignature` poisoning is fixed, and invalid historical thinking signatures are recovered automatically.
|
|
48
|
+
7. **`models.dev` auto-pricing.** 4-rate pricing (input, output, cache read, cache write/reasoning) across 2,180+ model basenames, including custom Azure and OpenAI-compatible deployments.
|
|
49
|
+
8. **RTK and Headroom protected-tools guard.** Output from `Read`, `Edit`, `Write`, `Grep`, `NotebookEdit`, `MultiEdit`, `patch`, `apply_patch`, and `anchor` is never compressed or summarized. Error results are preserved too. Line numbers and exact strings that `Edit` depends on stay intact.
|
|
50
|
+
9. **OpenCode `FreeTierError` and abuse direct-egress replay.** When OpenCode free models return a `FreeTierError` or an IP-abuse block, the request replays once through the next proxy in the pool or your direct egress, instead of failing the turn.
|
|
51
|
+
|
|
52
|
+
## Installation and quick start
|
|
53
|
+
|
|
54
|
+
Global install:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
npm install -g busbar-ai
|
|
58
|
+
busbar
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Or run with `npx`:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npx busbar-ai
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
The dashboard opens at `http://localhost:20128/dashboard`. The API is served at `http://localhost:20128/v1`.
|
|
68
|
+
|
|
69
|
+
The `9router` command still works as an alias for `busbar`.
|
|
70
|
+
|
|
71
|
+
### Claude Code
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
export ANTHROPIC_BASE_URL=http://localhost:20128
|
|
75
|
+
export ANTHROPIC_AUTH_TOKEN=<your Busbar API key>
|
|
76
|
+
claude
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Codex and the OpenAI SDK
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
export OPENAI_BASE_URL=http://localhost:20128/v1
|
|
83
|
+
export OPENAI_API_KEY=<your Busbar API key>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
from openai import OpenAI
|
|
88
|
+
|
|
89
|
+
client = OpenAI(base_url="http://localhost:20128/v1", api_key="<your Busbar API key>")
|
|
90
|
+
r = client.chat.completions.create(
|
|
91
|
+
model="<provider/model or combo name>",
|
|
92
|
+
messages=[{"role": "user", "content": "hello"}],
|
|
93
|
+
)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Build from source
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
git clone https://github.com/TejasLamba2006/busbar.git
|
|
100
|
+
cd busbar
|
|
101
|
+
cp .env.example .env
|
|
102
|
+
npm install
|
|
103
|
+
npm run dev
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Set `INITIAL_PASSWORD`, `JWT_SECRET`, and `API_KEY_SECRET` in `.env` before exposing the server beyond localhost.
|
|
107
|
+
|
|
108
|
+
## Docs
|
|
109
|
+
|
|
110
|
+
- [Architecture](docs/ARCHITECTURE.md)
|
|
111
|
+
- [Routing engine conventions](open-sse/AGENTS.md)
|
|
112
|
+
- [Changelog](CHANGELOG.md)
|
|
113
|
+
|
|
114
|
+
## Author and support
|
|
115
|
+
|
|
116
|
+
Made by [Tejas Lamba](https://tejas.is-a.dev/) ([GitHub](https://github.com/TejasLamba2006)). Support the project via [PayPal](https://www.paypal.com/paypalme/tejaslamba) or [GitHub Sponsors](https://github.com/sponsors/TejasLamba2006).
|
|
117
|
+
|
|
118
|
+
## License
|
|
119
|
+
|
|
120
|
+
MIT
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
s5jg02dt7_Ke0ZVHd5w0-
|
|
@@ -124,18 +124,18 @@
|
|
|
124
124
|
"/favicon.ico/route": "/favicon.ico",
|
|
125
125
|
"/manifest.webmanifest/route": "/manifest.webmanifest",
|
|
126
126
|
"/api/cli-tools/codex-profiles/route": "/api/cli-tools/codex-profiles",
|
|
127
|
-
"/api/cli-tools/codex-settings/route": "/api/cli-tools/codex-settings",
|
|
128
127
|
"/api/cli-tools/devin-settings/route": "/api/cli-tools/devin-settings",
|
|
129
128
|
"/api/cli-tools/hermes-profiles/route": "/api/cli-tools/hermes-profiles",
|
|
129
|
+
"/api/cli-tools/codex-settings/route": "/api/cli-tools/codex-settings",
|
|
130
130
|
"/api/cli-tools/omp-settings/route": "/api/cli-tools/omp-settings",
|
|
131
131
|
"/api/combos/presets/route": "/api/combos/presets",
|
|
132
|
-
"/api/combos/route": "/api/combos",
|
|
133
132
|
"/api/dashboard/playground/[...operation]/route": "/api/dashboard/playground/[...operation]",
|
|
133
|
+
"/api/combos/route": "/api/combos",
|
|
134
134
|
"/api/headroom/extras/route": "/api/headroom/extras",
|
|
135
135
|
"/api/headroom/proxy/[...path]/route": "/api/headroom/proxy/[...path]",
|
|
136
136
|
"/api/headroom/restart/route": "/api/headroom/restart",
|
|
137
|
-
"/api/headroom/start/route": "/api/headroom/start",
|
|
138
137
|
"/api/headroom/status/route": "/api/headroom/status",
|
|
138
|
+
"/api/headroom/start/route": "/api/headroom/start",
|
|
139
139
|
"/api/headroom/stop/route": "/api/headroom/stop",
|
|
140
140
|
"/api/keys/route": "/api/keys",
|
|
141
141
|
"/api/mcp/[plugin]/message/route": "/api/mcp/[plugin]/message",
|
|
@@ -143,44 +143,44 @@
|
|
|
143
143
|
"/api/models/alias/route": "/api/models/alias",
|
|
144
144
|
"/api/models/custom/route": "/api/models/custom",
|
|
145
145
|
"/api/models/disabled/route": "/api/models/disabled",
|
|
146
|
-
"/api/oauth/kiro/import-cli-proxy/route": "/api/oauth/kiro/import-cli-proxy",
|
|
147
|
-
"/api/oauth/[provider]/[action]/route": "/api/oauth/[provider]/[action]",
|
|
148
146
|
"/api/oauth/kiro/auto-import/route": "/api/oauth/kiro/auto-import",
|
|
147
|
+
"/api/oauth/kiro/import-cli-proxy/route": "/api/oauth/kiro/import-cli-proxy",
|
|
149
148
|
"/api/oauth/xiaomi-mimo/login/status/route": "/api/oauth/xiaomi-mimo/login/status",
|
|
150
149
|
"/api/oauth/xiaomi-mimo/login/start/route": "/api/oauth/xiaomi-mimo/login/start",
|
|
151
|
-
"/api/provider
|
|
150
|
+
"/api/oauth/[provider]/[action]/route": "/api/oauth/[provider]/[action]",
|
|
152
151
|
"/api/providers/[id]/overrides/route": "/api/providers/[id]/overrides",
|
|
153
152
|
"/api/providers/[id]/route": "/api/providers/[id]",
|
|
154
|
-
"/api/
|
|
155
|
-
"/api/providers/[id]/models/route": "/api/providers/[id]/models",
|
|
153
|
+
"/api/provider-nodes/route": "/api/provider-nodes",
|
|
156
154
|
"/api/providers/suggested-models/route": "/api/providers/suggested-models",
|
|
155
|
+
"/api/providers/client/route": "/api/providers/client",
|
|
157
156
|
"/api/providers/route": "/api/providers",
|
|
158
|
-
"/api/proxy-pools/[id]/route": "/api/proxy-pools/[id]",
|
|
159
157
|
"/api/proxy-pools/[id]/test/route": "/api/proxy-pools/[id]/test",
|
|
160
158
|
"/api/proxy-pools/cloudflare-deploy/route": "/api/proxy-pools/cloudflare-deploy",
|
|
159
|
+
"/api/proxy-pools/[id]/route": "/api/proxy-pools/[id]",
|
|
161
160
|
"/api/proxy-pools/deno-deploy/route": "/api/proxy-pools/deno-deploy",
|
|
162
161
|
"/api/proxy-pools/netlify-deploy/route": "/api/proxy-pools/netlify-deploy",
|
|
163
|
-
"/api/proxy-pools/route": "/api/proxy-pools",
|
|
164
162
|
"/api/pxpipe/health/route": "/api/pxpipe/health",
|
|
165
|
-
"/api/proxy-pools/vercel-deploy/route": "/api/proxy-pools/vercel-deploy",
|
|
166
163
|
"/api/pxpipe/install/route": "/api/pxpipe/install",
|
|
164
|
+
"/api/proxy-pools/route": "/api/proxy-pools",
|
|
167
165
|
"/api/pxpipe/logs/route": "/api/pxpipe/logs",
|
|
168
166
|
"/api/pxpipe/restart/route": "/api/pxpipe/restart",
|
|
169
167
|
"/api/pxpipe/start/route": "/api/pxpipe/start",
|
|
170
|
-
"/api/pxpipe/stats/route": "/api/pxpipe/stats",
|
|
171
168
|
"/api/pxpipe/status/route": "/api/pxpipe/status",
|
|
169
|
+
"/api/pxpipe/stats/route": "/api/pxpipe/stats",
|
|
172
170
|
"/api/pxpipe/stop/route": "/api/pxpipe/stop",
|
|
173
|
-
"/api/
|
|
171
|
+
"/api/proxy-pools/vercel-deploy/route": "/api/proxy-pools/vercel-deploy",
|
|
174
172
|
"/api/settings/proxy-test/route": "/api/settings/proxy-test",
|
|
175
|
-
"/api/settings/route": "/api/settings",
|
|
173
|
+
"/api/settings/database/route": "/api/settings/database",
|
|
176
174
|
"/api/translator/console-logs/stream/route": "/api/translator/console-logs/stream",
|
|
177
175
|
"/api/usage/[connectionId]/claude-reset/route": "/api/usage/[connectionId]/claude-reset",
|
|
178
|
-
"/api/
|
|
176
|
+
"/api/settings/route": "/api/settings",
|
|
179
177
|
"/api/usage/errors/route": "/api/usage/errors",
|
|
180
|
-
"/api/usage/[connectionId]/route": "/api/usage/[connectionId]",
|
|
178
|
+
"/api/usage/[connectionId]/codex-reset-credits/route": "/api/usage/[connectionId]/codex-reset-credits",
|
|
181
179
|
"/api/usage/stats/route": "/api/usage/stats",
|
|
182
|
-
"/api/usage/stream/route": "/api/usage/stream",
|
|
183
180
|
"/api/v1/audio/transcriptions/route": "/api/v1/audio/transcriptions",
|
|
181
|
+
"/api/providers/[id]/models/route": "/api/providers/[id]/models",
|
|
182
|
+
"/api/usage/[connectionId]/route": "/api/usage/[connectionId]",
|
|
183
|
+
"/api/usage/stream/route": "/api/usage/stream",
|
|
184
184
|
"/api/v1beta/models/[...path]/route": "/api/v1beta/models/[...path]",
|
|
185
185
|
"/callback/page": "/callback",
|
|
186
186
|
"/dashboard/settings/pricing/page": "/dashboard/settings/pricing",
|
|
@@ -207,7 +207,7 @@
|
|
|
207
207
|
"/(dashboard)/dashboard/usage/page": "/dashboard/usage",
|
|
208
208
|
"/(dashboard)/dashboard/console-log/page": "/dashboard/console-log",
|
|
209
209
|
"/(dashboard)/dashboard/providers/page": "/dashboard/providers",
|
|
210
|
-
"/(dashboard)/dashboard/providers/[id]/page": "/dashboard/providers/[id]",
|
|
211
210
|
"/(dashboard)/dashboard/profile/page": "/dashboard/profile",
|
|
212
|
-
"/(dashboard)/dashboard/proxy-pools/page": "/dashboard/proxy-pools"
|
|
211
|
+
"/(dashboard)/dashboard/proxy-pools/page": "/dashboard/proxy-pools",
|
|
212
|
+
"/(dashboard)/dashboard/providers/[id]/page": "/dashboard/providers/[id]"
|
|
213
213
|
}
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
],
|
|
5
5
|
"devFiles": [],
|
|
6
6
|
"lowPriorityFiles": [
|
|
7
|
-
"static/
|
|
8
|
-
"static/
|
|
7
|
+
"static/s5jg02dt7_Ke0ZVHd5w0-/_buildManifest.js",
|
|
8
|
+
"static/s5jg02dt7_Ke0ZVHd5w0-/_ssgManifest.js"
|
|
9
9
|
],
|
|
10
10
|
"rootMainFiles": [
|
|
11
11
|
"static/chunks/webpack-954c2cb06fa8c503.js",
|
|
@@ -510,7 +510,7 @@
|
|
|
510
510
|
"routeType": "page",
|
|
511
511
|
"response": "complete",
|
|
512
512
|
"compute": "static",
|
|
513
|
-
"htmlSize":
|
|
513
|
+
"htmlSize": 38686,
|
|
514
514
|
"experimentalBypassFor": [
|
|
515
515
|
{
|
|
516
516
|
"type": "header",
|
|
@@ -654,7 +654,7 @@
|
|
|
654
654
|
"routeType": "page",
|
|
655
655
|
"response": "complete",
|
|
656
656
|
"compute": "static",
|
|
657
|
-
"htmlSize":
|
|
657
|
+
"htmlSize": 33513,
|
|
658
658
|
"experimentalBypassFor": [
|
|
659
659
|
{
|
|
660
660
|
"type": "header",
|