dsh-llm-bridge
Verifieddsh-llm-bridge · v0.1.1 · MIT · Web UI
Use ChatGPT Codex, Claude, Grok, Antigravity, Kimi, GLM, Cursor, Kiro, Copilot, Qwen, ERNIE, Spark, JetBrains, Perplexity, Replit, and Cody accounts as DeepSeek Harness LLM providers via OAuth.
Install
dsh plugin add dsh-llm-bridge Confirm the layer applied with dsh --profile default --dump-config — see the install guide.
Source
Tags
Creators
Readme
dsh-llm-bridge
Overview
dsh-llm-bridge turns paid personal AI accounts into first-class LLM providers for DeepSeek Harness.
Sign in with OAuth PKCE. The plugin pools multiple accounts per vendor, rotates on rate limits and quota, and keeps tokens on the host. Other plugins can call the in-process Cordis service ctx.subscriptions without tokens leaving memory.
graph LR
subgraph DSHCore [DeepSeek Harness Session]
Agent[DSH Agent] --> Router{Provider Router}
end
subgraph BridgeCore [dsh-llm-bridge]
Router --> Pool{Multi-Account Vendor Pool}
Pool -->|Account 1| Acc1[Primary: Active]
Pool -->|Account 2| Acc2[Secondary: Standby]
Pool -->|Account 3| Acc3[Fallback: Cooldown]
Acc1 -->|HTTP 429 / Quota| Rotate[Quota and Cooldown Rotator]
Rotate -->|Switches traffic| Acc2
end
subgraph VendorBridges [Upstream Vendors]
Acc1 --> B1[ChatGPT / Codex]
Acc1 --> B2[Claude Pro / Max]
Acc1 --> B3[xAI / Grok]
Acc1 --> B4[Google Cloud Code Assist]
end
subgraph EcosystemBridge [Cordis: ctx.subscriptions]
Pool --> Other[Other DSH plugins]
end
style DSHCore fill:#1e1e2e,stroke:#89b4fa,stroke-width:2px,color:#cdd6f4
style BridgeCore fill:#181825,stroke:#cba6f7,stroke-width:2px,color:#cdd6f4
style VendorBridges fill:#11111b,stroke:#a6e3a1,stroke-width:2px,color:#cdd6f4
style EcosystemBridge fill:#181825,stroke:#f38ba8,stroke-width:2px,color:#cdd6f4
Built-in vendors
| Key | Plan | Protocol |
|---|---|---|
codex |
ChatGPT Plus / Pro | Codex streaming, tool calling, image drawing |
claude |
Claude Pro / Max | Native Messages protocol, usage tracking |
grok |
xAI / X Premium | Reasoning responses, billing checks, social search |
antigravity |
Google Cloud Code Assist | Antigravity (/v1/loadCodeAssist, /v1/streamGenerateContent) |
kimi |
Moonshot Kimi | OAuth device flow (auth.kimi.com), OpenAI-compatible chat |
glm |
Z.ai GLM Coding Plan | GLM coding endpoint (api.z.ai), live quota monitor |
cursor |
Cursor | Cursor backend (api2.cursor.sh), billing-period usage |
kiro |
AWS Kiro | Desktop OAuth (app.kiro.dev), streaming assistance |
copilot |
GitHub Copilot | GitHub device flow, Copilot chat completions |
qwen |
Alibaba Qwen (DashScope) | OpenAI-compatible endpoint, API key auth |
ernie |
Baidu ERNIE (Qianfan) | OAuth2 via API Key + Secret Key |
spark |
iFlytek Spark | OpenAI-compatible Spark HTTP API |
jetbrains |
JetBrains AI Assistant | JetBrains AI relay (api.jetbrains.ai) |
perplexity |
Perplexity Pro | Sonar model catalog (api.perplexity.ai) |
replit |
Replit Core | Replit AI API, connect-token auth |
cody |
Sourcegraph Cody Pro | Sourcegraph API, access-token auth |
Register extra vendors at runtime with createVendorFromProfile.
Features
Multi-account rotation
- Attach several accounts per vendor (
CODEX_OAUTH_1,CODEX_OAUTH_2, …). - Fail over on
HTTP 429,RATE_LIMIT, andQUOTA_EXCEEDED. - Preemptive switch with
switchAtRemainingbefore a window hits zero. - Cooldown from
Retry-After,x-ratelimit-reset, ISO dates, and epoch timestamps. - A 429 on a reasoning model cools only that family on the account. Standard models on the same account stay available.
Credentials and login
- Tokens never appear in HTTP API responses or in the Web UI. The UI shows masked labels, health, and quota bars.
- Tokens live in encrypted
$DSH_HOME/.credentials.yamlon the host. - Loopback callback (
autoLoopback, on by default): for loopback redirect URIs (Codex:1455, Grok:56121) the plugin catches the callback locally. Paste fallback stays available. - Device-code login (Codex): on a headless host, start device login, open
https://auth.openai.com/codex/deviceon any device, enter the code. - Web-origin redirect (
useWebCallback) and manual paste of the redirected URL or code remain available. - Access tokens refresh in the background before they expire.
Per-account proxy
Each slot accepts http://, https://, or socks5://[user:pass@]host:port. OAuth refresh, vendor checks, and model requests use that proxy. Check proxy measures round-trip latency to the vendor base URL.
Privacy and diagnostics
privacyMaskhides emails asj***[email protected]in the UI and in API labels.- Generate diagnostics report copies plugin/runtime versions, OS, per-vendor health, HTTP status counts, recent ≥400 errors, and non-secret settings. Tokens, emails, credential refs, and proxy URLs are excluded.
- The same block links to this repo’s issue tracker.
Local Ollama fallback
When Ollama is reachable at ollamaBaseUrl (default http://127.0.0.1:11434), it appears in the native model picker. If every account of a provider is exhausted and nothing has streamed yet, chat continues on ollamaFallbackModel (or the first model from /api/tags). Logged as kind: fallback.
Reasoning, verbosity, and fast mode
- Codex effort comes from the live catalog and is sent as
reasoning.effort. Grok forwards effort with its own catalog filter. codexVerbosity:low/medium/highastext.verbosity. Empty uses the protocol default.codexFastModesendsservice_tier: priority.- Claude adaptive thinking (
thinking: { type: "adaptive" }) and effort (output_config.effort) for Opus 4.6+ / Sonnet 4.6+. Unsupported models omit the fields so the vendor does not return 400. hideDeprecatedModelsdropstest/preview/dev/alpha/beta/legacyids from the picker.
Quota UI
- Composer indicator (
composerQuota):off/percent/bar/forecast. Forecast uses a 24h burn-rate window. - Session header pill with pool health, plus a modal of every account.
- Draggable overlay gauge that docks to screen edges.
- Codex reset-credit cards with a 5-second confirm and a single-flight lock so a double click cannot spend two cards.
Cordis service
Other plugins can call vendors in-process:
const res = await ctx.subscriptions.request('codex', '/backend-api/codex/images/generations', {
method: 'POST',
body: JSON.stringify({ prompt: 'Cyberpunk landscape', size: '1024x1024' }),
})
Calls stay in memory. A path allowlist blocks SSRF.
Install
dsh plugin --profile web add github:jayden-dang/dsh-llm-bridge
Or from npm after publish:
dsh plugin --profile web add dsh-llm-bridge
Restart the DSH Web UI after install (systemctl --user restart dsh-web). Open Settings → Plugins → Plugin Settings → LLM Bridge and connect accounts.
Common options live on that settings card. OAuth client IDs, redirect URIs, API base URLs, and custom vendors go in settings.yaml.
Configuration
dsh-llm-bridge:
switchAtRemaining: 1
cooldownMs: 60000
autoLoopback: true
privacyMask: false
ollamaBaseUrl: http://127.0.0.1:11434
ollamaFallback: true
ollamaFallbackModel: '' # empty = first model from /api/tags
hideDeprecatedModels: false
codexVerbosity: '' # low | medium | high
codexFastMode: false
composerQuota: 'off' # off | percent | bar | forecast
accounts:
codex:
- ref: CODEX_OAUTH_1
label: "Work Pro Account"
- ref: CODEX_OAUTH_2
label: "Personal Plus Account"
claude:
- ref: CLAUDE_OAUTH_1
label: "Claude Max"
grok:
- ref: GROK_OAUTH_1
label: "X Premium"
Per-slot fields include expiresAt (ms epoch) and proxyUrl.
HTTP API
| Route | Method | Purpose |
|---|---|---|
/dsh-llm-bridge/diagnostics |
GET | Anonymized diagnostics (no secrets, tokens, or proxy URLs) |
/dsh-llm-bridge/proxy-check |
POST | Latency check of a slot proxy against the vendor base URL |
/dsh-llm-bridge/oauth/device/start |
POST | Start Codex device-code login |
/dsh-llm-bridge/oauth/device/poll |
POST | Poll device-code authorization |
/dsh-llm-bridge/update |
GET/POST | In-place update from the npm registry |
Update routes require a loopback client (127.0.0.1, ::1, localhost), the x-dsh-plugin-update header, and same-origin checks.
Development
Source is TypeScript 7 in src/ (server + Web UI client), compiled to lib/. The client emits the DSH ModuleLoader bundle at lib/client.js.
npm run typecheck
npm run build
Localization
The plugin ships English only.
License
MIT © Jayden Đặng