Adds vision capability to DeepSeek Harness text
$ dsh plugin --profile web add github:oil-oil/dsh-visionRun the command above in your terminal to install this plugin via the dsh CLI. You can switch Profile in the top-right corner. New to dsh? Read the beginner tutorial
Give text-only models in DeepSeek Harness (like deepseek-official) the ability to see images pasted by users and answer based on visual content; models that already support images continue using native vision without any detours.
@deepseek-ai/dsh-llm-deepseek (target adapter being replaced), @deepseek-ai/dsh-attachment (image attachment reading), @deepseek-ai/dsh-credentials (API Key parsing), @deepseek-ai/schemastery (configuration schema)llm-deepseek via cordis.patch.yml, inject as dsh-vision; using LlmAdapter subclass VisionBridgeAdapter to take over deepseek-official routing, first determines original model input modality before deciding to bypass or bridge; also registers "Vision Recognition" settings card for Web Profilesrc/index.ts (server-side apply hook), frontend extension in src/client/index.tsxWhen you're using text-only models like DeepSeek but want them to understand pasted screenshots (interface errors, design mockups, tables, code screenshots, etc.), this plugin gives the chat window an experience close to native vision models; if you commonly use other image-supporting models already available in Harness, the bridge will automatically step aside and won't conflict with native paths.
| Dependency | Minimum Version | Notes |
|---|---|---|
| DeepSeek Harness | = 0.1.0-rc.6 | Fixed to this exact version via peerDependencies, DSH is still in Developer Preview |
| Node.js | >= 22.19 | From package.json engines field |
| Operating System | macOS / Windows / Linux | Cloud bridge and UI have no platform limits; macOS local OCR uses system Vision, other systems require pre-installed Tesseract with language packs |
| Native Modules | None | No locally compiled dependencies like node-pty, sqlite |
| Tesseract | Optional | Only needed for local fallback on non-macOS systems; will report "no language data" when built-in language data is insufficient |
dsh plugin --profile web add github:oil-oil/dsh-vision
| Config | Type | Description | Default |
|---|---|---|---|
| visionBackend | string (zenmux / bailian / tokendance / openrouter) | Primary vision platform for text model; empty means "auto-select", tries Harness other vision → see config → local OCR in sequence | Not set |
| visionBackendModel | string | Model ID for primary vision platform; empty uses platform default model | Platform default (ZenMux/OpenRouter use qwen/qwen3.7-plus, Bailian/TokenDance use qwen3.7-plus) |
| visionBackendBaseURL | string | API address for vision platform (http/https), for private gateways or proxies | Platform default address |
| visionProvider | string | Fix a specific image-supporting model in Harness as the vision route; must be filled together with visionModel, and cannot select deepseek-official | Not set |
| visionModel | string | The selected Harness vision model ID | Not set |
| visionConfigFile | string | see compatible config file path, empty reads ~/.config/see/config.env or SEE_CONFIG_FILE env var | ~/.config/see/config.env |
| visionTimeoutMs | integer (ms, ≥ 1) | Maximum wait time for single external vision call | 600000 |
| maxImages | integer (1–32) | Maximum images for joint analysis in one request; exceeding throws error directly | 8 |
| cacheEntries | integer (1–1024) | Memory cache entry limit for repeated vision recognition requests, evicted by LRU | 64 |
These fields all fall under the
llm-deepseeksection in$DSH_HOME/settings.yaml; the first 4 items (visionBackend, visionBackendModel, visionBackendBaseURL, maxImages) can be directly edited in the UI under "Settings → Plugins → Plugin Config → Vision Recognition" card, the rest need manual editing in the config file.
Q: Do I need to apply for a vision model API Key myself after installation?
A: Not by default. Leaving "Vision Platform" as "Auto-select" works fine; the plugin will first try models already configured in Harness that declare image support, then read see private config, and finally fall back to local OCR; only when manually specifying ZenMux / Bailian / TokenDance / OpenRouter do you need to fill in the corresponding platform's API Key in the card.
Q: If the current main model already supports images, will the plugin still interfere?
A: No. VisionBridgeAdapter calls the native adapter's resolveModel to check input modality before forwarding; if it contains image, it directly passes the entire message (including images) through to the DeepSeek adapter, with bridge code not participating at all.
Q: Are multiple images recognized separately or analyzed jointly?
A: Joint analysis. All images in a single request are packaged into the same external vision call, making it suitable for before/after comparisons, combined evidence, and other scenarios requiring seeing multiple images at once; this also means exceeding the limit throws an error directly rather than processing one by one.
Q: Can images be recognized offline on macOS?
A: Yes. On macOS, local fallback uses the built-in system Vision OCR without additional installation; when system OCR fails, it tries Tesseract. Windows / Linux users need to install Tesseract and corresponding language packages themselves, otherwise it will report "local vision unavailable".
Q: What's the maximum number of images per request?
A: Default 8, adjustable between 1–32. Exceeding the limit throws VISION_IMAGE_LIMIT error rather than silent truncation, so check maxImages setting before pasting screenshots.
Q: Where are API Keys saved? Are they secure?
A: Saved through Harness official credential service; after writing, you can only see "whether it exists", it's never read back to chat, settings page, or session logs; you can also use see's private ~/.config/see/config.env or same-named environment variable. This repository and build artifacts never write any Keys.
Q: Do I need to restart after changing configuration?
A: No. Changes in $DSH_HOME/settings.yaml's llm-deepseek section or UI card take effect automatically; restarting Web Profile is only occasionally needed when switching Provider/Model to refresh the model list.
Q: How to uninstall or disable?
A: Uninstall with dsh plugin --profile web remove github:oil-oil/dsh-vision; to temporarily disable, mark the dsh-vision section as disabled: true in cordis.patch.yml then restart Profile.
Beginner — One-line install command enables it immediately; default "Auto-select" mode requires no extra configuration to use local OCR; to use cloud vision, just select a platform and fill in a Key in the settings card.
visionProvider and visionModel must be configured together, and cannot select deepseek-official as external vision model (src/harness-vision.ts:58-79)image input modality, otherwise treated as text model (src/harness-vision.ts:74-79)visionBackendModel, visionBackendBaseURL, visionTimeoutMs, visionConfigFile, cacheEntries, visionProvider, visionModel are not in settings card, need manual editing in llm-deepseek section of $DSH_HOME/settings.yaml (README.md:51-61)0.1.0-rc.6, DSH mainline version changes require waiting for plugin sync (README.md:37)
English | 中文
dsh-vision is a plugin for DeepSeek Harness. Vision-capable models keep receiving images natively. When the selected main model is text-only, the plugin asks a separate vision model to observe the original images, then lets the original DeepSeek model produce the final answer.
| Main model | Image path | Final answer |
|---|---|---|
| Supports images | Original images are sent directly, without preprocessing or OCR | Current model |
deepseek-official or another text-only model | A configured vision model observes the original images; its output is injected as untrusted attachment context | DeepSeek |
| Cloud vision unavailable | Falls back to macOS Vision or Tesseract | DeepSeek |
The plugin does not replace the main model selected in Harness. Multiple image attachments are analyzed together, so comparisons and combined evidence work naturally. The user's task is forwarded unchanged instead of being wrapped in a fixed report template.
Use the plugin manager built into DeepSeek Harness:
npx @deepseek-ai/dsh plugin --profile web add github:oil-oil/dsh-vision
Restart Harness, then paste or drag images into the composer as usual. The plugin replaces the official deepseek-official adapter while preserving its model catalog, settings, and credentials. It also adds a Vision Recognition card to Settings → Plugins → Plugin configuration.
DeepSeek Harness is still in Developer Preview. This release targets
0.1.0-rc.6exactly.
Open Settings → Plugins → Plugin configuration → Vision Recognition. Select ZenMux, Alibaba Cloud Model Studio, TokenDance, or OpenRouter, then enter its API key. The same card lets you change the model ID, API endpoint, and image limit.
The API key is stored through Harness's official credential service. It is write-only in the browser: the plugin can report whether a key exists, but never reads it back into the page, chat, settings document, or session log.
Routing follows the user's choice. A provider selected in Vision Recognition is primary for text-only models. Other enabled Harness vision routes, an existing see configuration, and local OCR are failover only. When the current main model supports images, the original images pass through natively and none of these bridge routes are used.
Choose Automatic to skip plugin-managed cloud credentials. The bridge then tries image-capable models already configured in Harness, followed by see-compatible private configuration and local OCR. A Harness custom model must declare image as an input modality or it remains a text model.
Most setups should use the UI. The equivalent non-secret fields live in the existing llm-deepseek section of $DSH_HOME/settings.yaml:
llm-deepseek:
visionBackend: zenmux
visionBackendModel: qwen/qwen3.7-plus
visionBackendBaseURL: https://zenmux.ai/api/v1
maxImages: 8
Do not put API keys in this file. Save them in the Vision Recognition card or provide the matching environment variable. Changes apply without a restart.
If Harness has no usable vision model, the plugin also reads ~/.config/see/config.env. It supports ZenMux, Alibaba Cloud Model Studio, OpenRouter, and TokenDance. Environment variables override the private config file.
export SEE_PROVIDER=zenmux
export ZENMUX_API_KEY=your-key
SEE_PROVIDER selects the primary provider. Other providers with configured keys are failover routes only. If no provider is selected and only one is configured, that provider is used.
When no cloud key is available, or every cloud route fails, the plugin tries local capabilities:
Local fallback is primarily OCR and is not equivalent to full multimodal understanding.
pnpm install
pnpm check
The project is available under the MIT License. Cloud routing, joint multi-image analysis, and local fallback behavior are based on the MIT-licensed oil-oil/see-skill. The DeepSeek icon comes from the official deepseek-ai/deepseek-harness repository.