DeepSeek Harness Plugin

qikairo7/dsh-gemini-pool

Stars ★ 8 Category Models & Providers Added 2026-09-26

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:

  1. Use a throwaway account: register a separate Google account, never the main one holding your real assets
  2. Keep usage moderate: the built-in exponential backoff and cooldown help, but do not deliberately push quota limits
  3. 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- prefixed requestId; first-user-message hashed sessionId; 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 fetchAvailableModels catalog; 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_PROXY is unnecessary.
  • Self-check: if login or quota refresh fails with UND_ERR_CONNECT_TIMEOUT or fetch failed, this path is almost certainly not proxied. Request https://oauth2.googleapis.com/token both directly and through the proxy to confirm (a proxied reach returns 400, 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-process fetch follows 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_image tool (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 set visionEnabled: false in 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. visionModel picks 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-step event and image admission on resolveModelInfo. 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-doctor and check the visionBridge / visionShim lines (registered + installed is 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.

Content from the project README on GitHub ↗

Links

More in this category

View the whole category →

Community comments

Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.