Multi-account Google Gemini provider: picks the account with the most remaining quota, fails over on 429 with exponential cooldown, probes disabled accounts in the background, and ships a Chinese/English settings page.
Install
# from a prebuilt release tarball
dsh plugin --profile web add "https://github.com/qikairo7/dsh-gemini-pool/releases/download/v0.7.2/dsh-gemini-pool-0.7.2.tgz"
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:qikairo7/dsh-gemini-pool
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).
README
dsh-gemini-pool
The way to use Gemini in DSH — turn your Google AI Pro subscription into a coding model pool
English · 简体中文
Issues · Discussions · Changelog · Security · DeepSeek Harness · Upstream
✨ What is this
DeepSeek Harness (DSH) cannot reach Gemini on its own. This plugin bridges the gap: through the Google Antigravity / Cloud Code Assist channel, it connects your existing Google AI Pro subscription to DSH. No extra API key, no separate bill.
Gemini's strengths line up with coding work: multimodal input that reads images, frontend / UI code generation, and image generation for interface assets. This plugin puts all three inside DSH, billed against your subscription quota.
Have more than one Google account? Add them all to a pool: proactive weighted round-robin by remaining quota, seamless failover on 429, and failing accounts cool down and recover by themselves. Settings has a dropdown to inspect each account's weekly / 5-hour quota, or show every account card side by side.
🆚 Why you need it
Installing this plugin changes what your Google AI Pro subscription can do:
| Without: web-only subscription | With: subscription inside DSH | |
|---|---|---|
| Gemini multimodal (vision) | ❌ unavailable while coding | ✅ drop images into the chat |
| Frontend / UI codegen | ❌ no project context in web | ✅ reads your actual codebase |
| Image gen for UI assets | ⚠️ manual copy-paste | ✅ antigravity_image_generate auto-saves |
| Multi-account quota | — | ✅ proactive weighted scheduling, seamless 429 failover |
| Quota visibility | ❌ black box | ✅ live per-account bars |
| Unhealthy accounts | ❌ keep hitting dead ones | ✅ auto-disable + probe + revive |
When the main model itself has no vision (text-only), pasted images are automatically described in text by a Gemini model from the pool and fed back to the main model. On by default — see "👁 Vision bypass for text-only main models".
Read "⚠️ Account Ban Risk" below before installing.
⚠️ Account Ban Risk — Read Before Installing
This is an unofficial third-party tool. It reaches Google endpoints by reusing the Antigravity client identity. Google has officially confirmed that using third-party tools to access Antigravity resources violates the Terms of Service, and has carried out mass bans (see the official gemini-cli announcement, Feb 2026 — paid subscribers were affected too).
Enforcement mechanism (as published by Google):
- First violation → email notice + recertification form → automatic reinstatement in 1–2 days
- Second violation → permanent ban
- Scope: most reports involve the Antigravity / Gemini channel being blocked, and paid quota is forfeited with it; the community has asked Google twice whether a ban also hits the whole Google account (Gmail / Drive), and Google has never answered directly — assume the worst
- Enforcement is sampling-based: many third-party users run for months untouched, but nobody can promise you are not next
Three ways to reduce risk:
- Use a throwaway account: register a separate Google account, never the main one holding your real assets
- Keep usage moderate: the built-in exponential backoff and cooldown help, but do not deliberately push quota limits
- Assume the channel can break at any time: the endpoints belong to Google and policy may tighten
Using this plugin means you understand and accept these risks. This project is not affiliated with Google.
💰 How is this different from API relays
You can also pay a relay for Gemini API access by the token. That is a different trade:
| API relay / reseller | dsh-gemini-pool | |
|---|---|---|
| Cost | pay-per-token with a markup | flat subscription, marginal cost ≈ 0 |
| Model authenticity | ⚠️ may be silently downgraded | ✅ direct to official endpoints |
| Privacy | ⚠️ your code/chats/images pass through the operator's server | ✅ in-process straight to Google, no middleman |
| Quota visibility | a single opaque "site balance" | live weekly / 5h bars per account |
| Exit risk | relays vanish or degrade, balance gone overnight | no third party touches your money |
The relay has one real advantage: bans hit the operator's accounts, yours stays clean. The line is simple — account safety first, light usage, or just trying things out: use a relay. Already subscribed, privacy-conscious, want the real models long-term: use this.
🚀 Quick Start
Requirements: DSH 0.2.2-rc.1, the version this release is tested against. Run dsh --version to check yours; see "🧩 Compatibility & versions" for the full range.
1. Install the plugin
dsh plugin --profile web add github:qikairo7/dsh-gemini-pool
2. Sign in with Google
Open DSH Settings → Antigravity → click "+ Add Google Account" and authorize. Add as many as you like.
3. Done
Tick the models you want in the model selector and start chatting. Quota refresh and scheduling are automatic.
Your model can't see images? Paste anyway — a pool Gemini describes them to it automatically (on by default, see "👁 Vision bypass for text-only main models").
npm run pack:dist
# the package name carries the current version from package.json; install the file actually generated under dist/
dsh plugin --profile web add ./dist/dsh-gemini-pool-*.tgz
If your DSH does not support dsh plugin add, copy the package into $DSH_HOME/profiles/web/node_modules/ and add to cordis.patch.yml:
- insert:
- id: dsh-gemini-pool
name: dsh-gemini-pool
🧩 Compatibility & versions
| Item | Requirement |
|---|---|
| DSH | 0.2.2-rc.1 verified; engines.dsh is >=0.2.0-rc.2 <0.3.0 |
| Node.js | >=24.9 (same minimum as DSH 0.2.2) |
| Distribution | GitHub Release / dsh plugin add github:...; no npm registry dependency |
| Current version | v0.9.1 (Release) |
Upgrading from v0.8.x: restart DSH and open Settings once to refresh quota. The old static model list is replaced by the live per-account catalog; models you had enabled but no account provides are removed automatically.
Recent versions
v0.9.1 — protocol and scheduling hardening
agent-prefixedrequestId; first-user-message hashedsessionId;antigravity/hub/<version>User-Agent.- Accounts without a Code Assist project are created through
onboardUser. - Scheduling prefers the exact model's
remainingFraction, then the account's 5h/weekly group. - Hide
gemini-2.5-pro/gemini-2.5-flash-thinking; conservative fallback when no live list exists; refused tiers cached for 24 hours.
v0.9.0 — model catalog and account pool
- Live per-account
fetchAvailableModelscatalog; multi-account union with capability routing. - Proactive smooth weighted round-robin by 5h / weekly quota instead of waiting for a single account to hit 429.
- Gemini 4 Argon and future families folded from the live list.
- DSH 0.2.2-rc.1 image-budget offload, tier entitlement, and Cordis 4.1 event semantics.
🧱 Network environment (behind a proxy)
The plugin contains no proxy code of its own: every Google request is an in-process fetch that uses the host's global HTTP path. The host reads HTTP_PROXY / HTTPS_PROXY / ALL_PROXY / NO_PROXY only from the harness home's .env, and only once at startup (the same names in any other .env are refused), then installs the proxy for the plugin from there.
⚠️ This is the most common cause of "the browser authorized successfully, but DSH never gets the account / refreshing data fails": the proxy file was placed in the wrong home.
| You run | Put the proxy in |
|---|---|
CLI (dsh ...) |
~/.dsh/.env |
| DSH Desktop | Windows: %APPDATA%\dsh-desktop\harness\.envmacOS: ~/Library/Application Support/dsh-desktop/harness/.env |
DSH Desktop has its own harness home — not ~/.dsh; an ~/.dsh/.env alone has no effect there. (For the same reason, the desktop account file lives at <that folder>\storages\antigravity-pool-accounts.json.)
Three lines are enough — change the port to match your proxy:
HTTP_PROXY=http://127.0.0.1:7897
HTTPS_PROXY=http://127.0.0.1:7897
- Fully quit and restart DSH afterwards — the proxy is read once at startup; reloading the page does nothing.
- Loopback (the settings GUI and the OAuth callback's local port) is bypassed by the host automatically;
NO_PROXYis unnecessary. - Self-check: if login or quota refresh fails with
UND_ERR_CONNECT_TIMEOUTorfetch failed, this path is almost certainly not proxied. Requesthttps://oauth2.googleapis.com/tokenboth directly and through the proxy to confirm (a proxied reach returns400, since the request body is missing). - Do not add proxy code to the plugin:
import('undici')is unavailable in the host's Node, and an in-processfetchfollows the host's proxy automatically.
💧 Account Pool & Scheduling
Three strategies, one click to switch in Settings:
- Smart balancing (recommended): smooth weighted round-robin by remaining quota, so requests spread before any account hits 429; drained accounts lose weight automatically
- Primary & backup: fixed primary account, automatic switch when its quota runs out
- Manual: lock to one account for debugging or dedicated runs
The account list has a dropdown to inspect one account's quota, reset time, and status; with several accounts the cards stay visible. The model catalog is the union of each account's live fetchAvailableModels reply: a model an account does not have is neither offered nor routed to that account.
Day-to-day operations run as chat commands:
| Command | What it does |
|---|---|
/antigravity-login |
sign in with a Google account |
/antigravity-quota |
show per-account quota |
/antigravity-doctor |
run self-diagnostics (vision troubleshooting below) |
/antigravity-logout |
sign out and remove stored credentials |
Credentials live at $DSH_HOME/storages/antigravity-pool-accounts.json (on DSH Desktop: %APPDATA%\dsh-desktop\harness\storages\...), including access and refresh tokens. Keep that file private. Legacy single-account credentials migrate automatically on upgrade, so you do not have to sign in again.
🧊 Cooldown & Self-healing
An account that hits 429 enters exponential-backoff cooldown. Repeated failures disable it and hand it to a background probe that revives it once quota recovers. No manual steps.
| Parameter | Default | Description |
|---|---|---|
cooldownMs |
1 min | initial cooldown, doubling on each failure |
cooldownMaxMs |
1 hr | cooldown cap |
disableThreshold |
5 | consecutive failures before disable |
probeIntervalMs |
5 min | background probe interval, auto-revive on success |
Disabled accounts carry a red tag in Settings and a one-click "Re-enable" button. All of these parameters are adjustable in the "Cooldown & Recovery" section.
👁 Vision bypass for text-only main models
When the main model cannot see images (e.g. a text-only model), a Gemini model from the pool looks at them and answers in text, through two paths:
Automatic description (main path, seamless): after a paste, the plugin swaps the image in the outgoing request for a text description generated by a pool Gemini — the main model simply reads it, no action needed. Each image is described once per process (in-process cache), so images repeated across session history do not burn quota twice; descriptions carry the original image hash, and a failed description falls back to the host's placeholder path without blocking the chat.
The
antigravity_read_imagetool (fallback): for a closer look at a specific image, the main model can call it explicitly (the argument is the hash prefix from the description; local paths inside the workspace, data: URLs, and public http(s) image URLs are also accepted) for a fresh description.Data flow: images are processed through Google accounts in the pool, sharing quota with chat and image generation.
On by default. To turn it off (any one of these): set the environment variable
ANTIGRAVITY_VISION_ENABLED=false; or toggle it off in the Settings · Vision Bypass card; or setvisionEnabled: falsein accounts.json via/antigravity/api/config. The switch governs both image admission and automatic description; with it off, pasting behaves exactly as the host does out of the box.visionModelpicks the describing model — leave it empty for automatic selection, or pick one in the Settings card.Known dependency: automatic description relies on the host's
agent/pre-stepevent and image admission onresolveModelInfo. If pasting images misbehaves after a major host upgrade, revisit this section (verified against DSH 0.2.2-rc.1).Troubleshooting: if the model still receives a placeholder after pasting an image, run
/antigravity-doctorand check thevisionBridge/visionShimlines (registered+installedis the healthy state). Server log lines prefixed[Antigravity Pool Vision]record every bridge decision (request entry, model gate, rewrite result or passthrough reason); zero prefixed lines after a paste means the event never reached the bridge.
🤖 Model families
Tick a model in Settings to enable it. Enabled models float to the top, each showing the highest available quota in the pool.
| Model | Quota pool |
|---|---|
| Gemini 4 Argon · Gemini 3.8 / 3.7 / 3.6 / 3.5 Flash | Gemini |
| Gemini 3.5 Flash Lite · Gemini 3.1 Flash Lite | Gemini |
| Gemini 3.1 Pro · Gemini 3.1 Flash Image (image gen) | Gemini |
| Gemini 3 Flash · Gemini 2.5 Flash | Gemini |
| Claude Opus 4.6 · Claude Sonnet 4.6 · GPT-OSS 120B | Claude & GPT |
The list above names model families Antigravity has offered; the real selector is whatever your accounts return. The plugin only offers models present and not disabled in fetchAvailableModels, folds thinking levels (low / medium / high) into one entry per family, and unions accounts — a request only goes to an account that actually lists the model.
Models in the same pool share the weekly and 5-hour quotas. Quota drains in proportion to token cost, so heavier models run out faster.
🧭 Architecture
flowchart LR
subgraph HOST["DSH host"]
PRE["agent/pre-step<br/>messages & images"]
LLM["llm/stream<br/>model requests"]
SEL["Model selector / Settings"]
end
subgraph PLUGIN["dsh-gemini-pool"]
CORE["Plugin core<br/>commands & API routes"]
CATALOG["Model catalog<br/>live fetchAvailableModels<br/>family folding · account union"]
POOL["Pool manager<br/>weighted scheduling · cooldown · probing"]
VB["Vision bridge<br/>image to text"]
TOOLS["Tools<br/>read_image · image_generate"]
end
STORE[("Credential store<br/>antigravity-pool-accounts.json")]
GOOGLE["Google Antigravity API"]
SEL --> CORE
CORE --> CATALOG --> POOL
PRE --> VB --> POOL
LLM --> POOL
TOOLS --> POOL
POOL --> GOOGLE
POOL --> STORE
Requests enter the plugin through the host: the agent/pre-step vision bridge rewrites images for text-only models into descriptions from a pool Gemini; the catalog builds the offered models from each account's live fetchAvailableModels and folds thinking levels; the pool manager picks accounts by remaining-quota weights and handles 429 cooldown and probing. Every call goes in-process straight to the official Google endpoints.
🤝 Contributing
Issues and PRs are welcome, and so are conversations in Discussions. Please run the local checks before opening a PR:
npm install # install dependencies
npm run check # syntax checks + tests
📄 License & Credits
This project is licensed under the MIT License.
Built on dsh-antigravity by @LiZhenNet, with community contributions from @Lukeknow0, @miuzel, @grloper and @sereineele.
Links
More in this category
Ebony-Vinyl/dsh-our-free-model★ 67530
Adds free model lanes to DeepSeek Harness — DeepSeek V4.1 Flash, Kimi K3 and others — with no login, sign-up or API key, plus a local OpenAI-compatible gateway, fallback routing and a usage dashboard.
dingminhua/dsh-connect-workbuddy★ 1386
Connects locally signed-in WorkBuddy models, CN and international alike, to DSH, reading each model's credit multiplier from the upstream catalog on every refresh, with per-model image input toggles, account switching backed by an auto-failing-over pool, manual daily check-in, and read-only credit overviews shown as compact pills on the card and in the composer.
Alice-Marx/dsh-model-router★ 957
Routes DeepSeek Harness work across configured model APIs and supported vendor CLIs with dependency-aware packages and cost previews.
V1ki/dsh-plugin-subscriptions★ 579
Use ChatGPT (Codex), Claude, and Grok subscriptions as DeepSeek Harness LLM providers, with Settings login, model catalogs, usage, plus image_generate, video_generate, and x_search tools.
XDTrees/dsh-workbuddy-xdpool★ 481
Merge every locally signed-in WorkBuddy account into DeepSeek Harness as one auto-failing-over model pool (multi-account rotation, live credits, and a model catalog showing per-model credit multipliers and free/night-discount tags).
XDTrees/dsh-xdpool★ 481
Merge every locally signed-in WorkBuddy account into DeepSeek Harness as one auto-failing-over model pool: multi-account rotation, 429 cooldowns, live credits, a model catalog with per-model credit multipliers and free/night-discount tags, QR-code login for 13 vendors, and aggregate free-tier channels. Accounts persist across restarts.
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.