Back to directory

dsh-vision-router

Curated pickMaintenance: Active

ysr666/dsh-vision-router

Eyes for text-only DeepSeek Harness agents: built-in free vision chain (no key) + pixel-level vision tools (Q&A, grounding, crop, pixel diff, colors, OCR, SVG trace, cutout, screenshots). One-command install, no Python, image turns work like ordinary tool-calling turns.

Install

dsh has no central install command — add this plugin’s entry (documented in its README below) to your profile or patch config, then restart.

How installs work

829

stars

35

forks

JavaScript

Language

MIT

License

2026-08-13

Created

2026-08-19

Last push

README

DSH Vision Router — eyes for text-only DeepSeek Harness agents

dsh-vision-router

Paste an image and it just works — eyes for text-only agents on DeepSeek Harness. Free out of the box, no key, no Python, one command.

DeepSeek keeps thinking; the built-in free vision chain and fourteen deep tools do the seeing. Image turns behave like ordinary tool-calling turns — grounded, measurable, repeatable.

awesome · DSH plugin dsh-recommend 🏅 精选认证 dsh score 0.90 Listed on DSHPlugin.app

Release v1.7.1 Verified: 657 tests License: MIT Node.js >=22 No Python DSH Web profile

English · 中文

💬 QQ community group: 1105463028

[!WARNING] 📌 Announcement (v1.7.1)

v1.7.1: Remote settings can now be enabled after an explicit risk confirmation.

Demo: paste an image, the agent locates the send button with vision_ground / vision_crop / vision_pixel_diff and answers with coordinates

Contents

Why this exists

Most DSH vision plugins bridge images to DeepSeek as text descriptions — lossy, one-shot, and blind to pixels. This plugin keeps the original pixels on the vision model's side and DeepSeek on the reasoning side, and makes looking at an image an ordinary tool call:

  • One command install. The package ships its own composition patch (dsh.bundle.patch): dsh plugin add wires the row, the admission wrapper and the attachment limits automatically — zero manual file edits. Taking over the official DeepSeek route is an optional setting (stealth mode, off by default).
  • Free by default. Vision tools end with a five-model OVHcloud anonymous fallback: no account, no key, 2 requests/minute per IP per model, roughly 10 RPM in theory across independent buckets. User-provided vision models run first.
  • No Python. The whole pipeline — downscale, grounding, crop, pixel diff, palette, OCR, SVG trace, cutout, HTML screenshot — runs on sharp / potrace / tesseract / system Chrome.
  • Continuous multi-step image work. An image turn is a text turn that calls tools: vision_groundvision_cropvision_describevision_pixel_diff → fix → screenshot again. The agent keeps iterating until the work is done.
  • DeepSeek stays the brain. Text turns are untouched in model, cost and context. The vision model is only the eyes, called on demand; answers are cached by image content.
  • Transparent to the user. Uploaded images keep rendering as images in the conversation UI; the rewrite that points the model at the vision tools happens only inside the model call, never in the session log.

How it compares

One-line take: most dsh vision plugins turn images into text descriptions for DeepSeek (description bridge — lossy); this plugin hands the image turn straight to a vision model (routing bridge — pixel-faithful), with a built-in keyless free fallback.

Manual model switching MCP vision bridge dsh-vision-router
Pixel fidelity ✅ full (when switched) ❌ text description only ✅ full, on the image turn
Automatic
Daily model untouched ❌ (whole session swapped)
Provider failure recovery ✅ fallback chains
Reusable structured queries partial ✅ JSON mode + caching
Free out-of-the-box ✅ built-in keyless endpoint
Fits dsh composition external server ✅ one plugin row

Difference from existing dsh community projects (all excellent, each with its own focus; descriptions reflect their READMEs as of 2026-08):

Project Approach What this plugin adds
dsh-vision-sidecar Pre-describes images with an external VLM; the description joins the session as a message to DeepSeek; LLM7.io anonymous endpoint by default (OVHcloud listed as a no-key alternative) Description bridge; this plugin adds raw-image routing, with vision_describe covering descriptions on demand
dsh-vision-proxy Wraps a provider route and transcribes images into text in the request stream Transcription bridge; this plugin wraps no provider — it rewrites routing through agent/request waterfalls
dsh-vision-provider Registers DeepSeek + Vision combined routes: images are described by the chosen vision model before reaching DeepSeek Two-model bridge idea; this plugin adds automatic routing, fallback chains and tools on top
modlens The first dsh vision plugin; reuses local Claude Code/Codex/OpenCode/Pi logins as vision engines Engine-reuse idea; this plugin ships its own provider chain and depends on no other local CLI
dsh-vision-toolkit Ten intent-aware visual tools (Q&A/OCR/pixel verification/UI restoration), called explicitly on demand Broader tool set; this plugin adds whole-turn auto-routing and a keyless free fallback
dsh-tool-vision An inspect_image tool plus an agent/pre-step waterfall bridge (pasted images become tool hints before entering the log) Similar waterfall bridge; this plugin adds turn routing, fallback chains, caching and the free endpoint

Design lineage

The deep-vision tool layer and UI-restoration workflow in this project were informed by Anionex/agent-vision-toolkit and its native DSH implementation Anionex/dsh-vision-toolkit. In particular, this project drew on their intent-driven tool selection, progressive tool exposure, pixel-diff verification loop, and parts of the visual-tool decomposition and naming, including long-screenshot OCR, foreground extraction, and HTML screenshot tooling.

All code in dsh-vision-router is independently implemented. On top of those referenced design ideas, this project independently developed its turn-level/tools-first vision routing, DSH admission/wrapper integration, multi-backend provider and failure fallback chains, built-in free vision chain, attachment/image-memory handling, caching, and related runtime resilience mechanisms.

We appreciate Anionex's prior work and the broader DSH community. Clear attribution and independent iteration can coexist; both help keep the DSH ecosystem open, collaborative, and healthy.

Acknowledgements

This project borrows ideas from all of the above — especially the keyless free-endpoint exploration (LLM7.io and OVHcloud anonymous tiers) by dsh-vision-sidecar. Thanks to the authors of dsh-vision-proxy, dsh-vision-provider, modlens, dsh-vision-toolkit, and dsh-tool-vision.

Quick start

1. Install the plugin

For normal npm/npx installs, installation is a single command:

npx @deepseek-ai/dsh plugin --profile web add dsh-vision-router

[!WARNING] If this profile already loads community plugins manually through cordis.patch.yml, do not mix that legacy setup with dsh plugin add / dsh plugin list: current DSH CLI behavior can also append bundle-patch dependencies to dsh.profile.bundles, causing those plugins to register twice. Migrate the existing manual plugin rows to bundle-managed loading first, or keep using the manual installation path. See deepseek-harness discussion #2889.

[!NOTE] Third-party dsh-web-plugin-manager / dshpm v0.4.2+ is also compatible: its quality gate now correctly allows @deepseek-ai/schemastery as a runtime dependency. The official DSH CLI above remains the recommended install path.

If you run DeepSeek Harness from a source checkout with pnpm, use the workspace script instead — dsh is not necessarily on your shell PATH:

cd deepseek-harness
pnpm dsh plugin --profile web add dsh-vision-router

If you already installed the DSH CLI globally and dsh is on PATH, the shorter dsh ... form works too. After installation, start or reload DSH Web as you normally do.

[!NOTE] If you install the plugin into a Web process that was already running long-term, let that DSH Web process reload once so the plugin bundle itself is discovered. After the plugin is loaded, adding/removing models or changing wrapper scope hot-updates without further DSH restarts.

2. Switch to a “+ Auto Vision” model group in chat

Once loaded, the plugin discovers the model groups enabled under Settings → Models and creates same-name auto-vision entries. For example:

opencode-go                 ← original model group, unchanged
opencode-go + Auto Vision   ← choose this when sending images

[!IMPORTANT] Before sending an image, open the model selector in the lower-right corner of the chat composer and choose a group marked “+ Auto Vision”.

Vision Router deliberately does not modify the original model group. If the conversation still uses the original text-only opencode / DeepSeek route, DSH can reject the image with “the current model does not support images” before Vision Router gets a chance to handle it. That is a model-entry selection issue, not a broken vision backend.

The auto-vision group follows the live DSH model catalog. Adding models or changing wrapper scope does not require a restart.

3. Paste or upload the image

After choosing the “+ Auto Vision” model group, paste or upload an image normally. By default the complete vision tool schema is stable from session start, so the agent can immediately use vision_describe, vision_ground, vision_crop, and the rest across multiple steps when needed.

The built-in anonymous OVH vision fallback is already configured, so normal image use needs no signup or API key. The lower-right chat picker selects only the brain/conversation model; vision backends do not belong there. Advanced options live under Settings → Plugins → Plugin config → 视觉路由(自动识图): each vision-backend row may select any callable generative user model already configured under Settings → Models. DSH image-capability metadata is advisory only: undeclared or text-only-labelled models remain selectable and show a warning. At runtime Vision Router always tries the provider's registered DSH adapter first — including WebSocket, RPC and private transports — and falls through on a real failure. The direct compatibility bridge is used only when an http(s) OpenAI Chat Completions endpoint is positively identified. Leaving every user row empty is valid; the OVH chain remains the final fallback. Vision HTTP is an internal transport route, not a model group users should select.

See it in action

Left: an image turn — the user sends a picture, the agent calls vision_describe through the free chain and answers. Right: the finished structured answer.

A conversation turn in which the agent looks at an uploaded image through vision_describe. The agent's structured answer describing the image content.

Free vision key channels

The built-in OVH fallback is anonymous by design, and OVH caps anonymous use at 2 requests/minute per IP per model. If that feels tight, every channel below offers free vision models with much higher quotas — all of them are free to register, and none charges for the free tier. Free policies rotate often; treat this table as an August 2026 snapshot and double-check each provider's console before relying on it.

Channel Free vision model(s) Free quota CN direct? Where to get the key
OVHcloud AI Endpoints (access key) Qwen2.5-VL-72B-Instruct — the same endpoint the built-in fallback uses 400 req/min per project per model (vs 2 anonymous) OVH account → Public Cloud project (attach a payment method; free models are not charged) → AI Endpoints access key
Zhipu (bigmodel.cn) glm-4.6v-flash · glm-4.1v-thinking-flash · glm-4v-flash — three permanently free models; chaining them triples capacity uncapped tokens open.bigmodel.cn → API keys
DashScope (Aliyun) qwen3-vl-flash (limited-time free) and the Qwen-VL series new users: 1M tokens per model series / 90 days bailian.console.aliyun.com
Intern AI (Shanghai AI Lab) internvl-latest · internvl3.5-latest 30 RPM, 90M tokens/month chat.intern-ai.org.cn
Groq meta-llama/llama-4-scout-17b-16e-instruct (native multimodal, up to 5 images) 30 RPM / 14,400 req/day, no card ❌ proxy console.groq.com
Google AI Studio gemini-2.5-flash · gemini-2.5-flash-lite 10–30 RPM / 500–1,500 req/day ❌ proxy aistudio.google.com
NVIDIA NIM meta/llama-3.2-11b-vision-instruct · nvidia/nemotron-nano-12b-v2-vl 40 RPM, no card ⚠️ build.nvidia.com
OpenCode Zen mimo-v2.5-free (vision + code) 30 RPM / 500 req/day ⚠️ opencode.ai/zen
OpenRouter google/gemma-4-26b-a4b-it:free · google/gemma-4-31b-it:free 50 req/day on unpaid accounts ❌ proxy openrouter.ai

Any of these channels can join the vision chain as an httpProviders entry (key in the matching environment variable or ~/.dsh/.credentials.yaml), and the chain tries your entries before the anonymous fallback.

[!NOTE] Free-tier policies change without notice — Cerebras retired its free tier in July 2026 (now a one-time $5 credit), SambaNova's free tier is down to 20 requests/day, and Hugging Face's is $0.10/month. Third-party “:free relay” aggregators are deliberately not listed: they rotate quickly, lack SLAs, and some resell quota in ways that violate upstream terms.

Highlights

  • Original pixels, real answers. The vision chain reads the image at original resolution (auto-downscaled only to protect latency/quota); the agent's question travels with the image, so answers are about your question, not a generic description.
  • Automatic failover with classified errors. Region blocks, ToS filtering, 402 quota, 429 rate limits, context overflow, network failures — the chain walks providers one by one and only reports after all of them failed, with actionable advice. A 429 immediately advances to the next backend and opens a Retry-After-aware cooldown instead of sleeping inside the request.
  • Image memory. Vision answers are cached by attachment content hash; later text turns substitute the recorded description (marked as untrusted evidence), so DeepSeek genuinely remembers earlier images without re-spending vision calls.
  • A verifiable pixel loop. Reference → vision_html_screenshotvision_pixel_diff (ratio + red heatmap + worst-region ranking) → fix → repeat until the mismatch converges. UI restoration becomes measurable instead of eyeballed.
  • Stable tool schema. All fourteen deep tools are registered from session start by default, avoiding a mid-conversation tool-list expansion that can invalidate long-context KV/prefix caches. progressiveTools: true remains an advanced boot-time opt-in; only then does vision_activate mount the tools on demand. See docs/progressive-tools-cache.md.
  • Selective proxy. Only the configured vision provider hosts go through your local proxy; DeepSeek stays direct.

Pixel loop in practice

Reference design and final agent rebuild, verified with vision_pixel_diff at 2.54% final difference.

Click the image to open the full-resolution original.

The agent rebuilt the UI from the reference image, then verified the final result with vision_pixel_diff: 2.54% final diff (32,939 / 1,296,000 differing pixels, threshold 16/channel).

How it works

How DSH Vision Router keeps DeepSeek as the brain and vision tools as the eyes.

The vision model is only the eyes; DeepSeek is always the brain. An image turn is never hijacked by a one-shot vision answer — the agent drives the tools itself and can keep operating on the image across as many steps as the task needs.

Tools

Default progressiveTools: false: all fourteen deep tools stay registered from plugin startup, so text and image turns can call them immediately. If you explicitly set progressiveTools: true in the profile/composition cordis.patch.yml, progressive mode is restored: only vision_activate is exposed initially, the full tool set mounts on first use, and the vision-tools skill is registered. This is a boot-time switch; restart DSH after changing it. Built on sharp / potrace / tesseract / system Chrome — no Python:

Eleven image-processing tools available in DSH Vision Router.

The diagram covers the eleven image-processing tools. vision_present (durable image delivery) and vision_bootstrap (the optional 1+x structured first pass) bring the default deep-tool set to fourteen. Enabling the privacy-gated vision_screenshot at boot adds an optional fifteenth tool.

Tool What it does Artifact
vision_bootstrap Optional 1+x structured first visual pass; establishes task-independent evidence before at least one follow-up vision call
vision_describe Image Q&A / multi-image compare / structured-evidence JSON mode (summary + layout regions + entity inventory + verbatim transcription)
vision_materialize Copy an authorized attachment into the session workspace and return a filesystem path for local OCR/parser fallbacks; no vision/network call image copy
vision_ground Locate a target → original-pixel box x1/y1/x2/y2 annotated PNG (optional)
vision_detect Numbered inventory of every element of a kind (buttons/inputs/links…) with original-pixel boxes annotated PNG with numbered boxes
vision_crop Crop and zoom into a pixel box PNG
vision_present Publish a generated or edited local image as a durable chat attachment so the user can see it image attachment
vision_pixel_diff Per-pixel comparison: diff ratio + worst 8×8-grid regions red heatmap PNG + JSON report
vision_colors Dominant colors (hex + share)
vision_ocr Text transcription: local tesseract (chi_sim+eng) first, vision model fallback
vision_trace SVG vectorization (potrace posterization; icons/logos) SVG
vision_extract_foreground Cutout via border flood fill (uniform backgrounds) transparent PNG
vision_html_screenshot Screenshot a local HTML file (headless system Chrome); fullPage: true captures the whole page and reports pageHeight PNG
vision_screenshot Disabled by default; explicit opt-in required. Capture the Windows virtual screen, macOS main display, or Linux root display. Windows uses PowerShell CopyFromScreen, macOS uses screencapture, and Linux requires ImageMagick import or scrot; optional identify=true tries enabled local recognition backends in order and returns the description with the path PNG / + description
vision_long_screenshot_ocr Long-screenshot transcription: overlapping chunks, tesseract first / vision model fallback, stitched Markdown chunk PNGs + Markdown + manifest

Formats are sniffed from magic bytes, so extensionless content-addressed attachment files work everywhere (no .png renaming needed).

Common workflows

vision_ground image="ref.png" target="the send button"
vision_detect image="page.png" target="input fields"
vision_crop   image="ref.png" region="1067,841,1108,881"
vision_present path="rebuilt.png"
vision_describe paths=["ref.png","impl.png"] question="list the differences" json=true
vision_pixel_diff original="ref.png" rebuilt="screenshot.png"
vision_ocr image="screenshot.png"
vision_colors image="ref.png" top=8
vision_trace image="icon.png" steps=4
vision_extract_foreground image="logo.png"
vision_html_screenshot source="page.html" width=1200 height=720
vision_html_screenshot source="page.html" width=1200 height=720 fullPage=true
vision_long_screenshot_ocr image="chat-log.png" chunkHeight=1200 overlap=120

Provider fallback chain

The vision tools try backends in order and surface an error only after all of them fail:

  1. User vision models: one per settings row, top to bottom; active providers remain visible even when model enumeration is partial, callable generative models stay selectable, image metadata is advisory, and actual support is verified at runtime;
  2. Local Ollama (optional, off by default): localOllama.enabled adds keyless, offline recognition through your local Ollama (for example qwen2.5vl);
  3. Local LM Studio (optional, off by default): localLmStudio.enabled follows Ollama and requires the real model identifier shown in LM Studio Developer or returned by /v1/models;
  4. Advanced custom HTTP vision endpoints: legacy/advanced httpProviders, when present, run after the local backends;
  5. Built-in anonymous OVH fallback: always last and never exposed in a model picker. The current quality-first chain is Qwen3.5-397B-A17BQwen2.5-VL-72B-InstructQwen3.6-27BMistral-Small-3.2-24B-Instruct-2506Qwen3.5-9B. OVH anonymous limits are 2 requests/minute per IP per model. The five models have independent buckets, so spreading requests across them is about 10 RPM in theory, subject to OVH's actual rate limiting. No signup or API key is required. Want more headroom? See Free vision key channels — a free OVH access key lifts this same endpoint to 400 requests/minute.

View on GitHub

DSH Plugins is an independent community directory of DeepSeek Harness plugins. Not affiliated with or endorsed by DeepSeek. Third-party plugins are not security-audited — review the source before installing.

New DeepSeek Harness plugins, weekly. No spam.