Introduction

When using text models to chat in DSH (DeepSeek Harness), if you want to paste a screenshot, an error interface, or a photo of a table, there are usually only two ways: switch to a native multimodal model to take over the entire conversation, or manually describe the image as text outside the conversation and paste it in. The former is equivalent to changing the conversation brain, while the latter requires repeating the operation every time.

DSH’s philosophy is “Everything is a plugin,” and this issue can also be solved by a plugin. The dsh-vision-recognizer introduced below does exactly that: keeps DeepSeek as the conversation brain, allows attaching images anytime, and allows switching vision providers anytime in Settings → Plugins.

What is this

dsh-vision-recognizer is a DSH vision plugin maintained by kaixinbaba, under the MIT license. Current version 0.2.0, requires node >= 22.19.0, dsh >= 0.1.0-rc.8.

It registers an adaptive provider route (default id is vision-recognizer, displayed as “DeepSeek + Intelligent Vision Recognition” in the model selector), wrapping the configured chat provider, with DeepSeek being the default wrapped provider. This route always passes image attachments, then routes based on the actually selected model:

Paste Image ─▶ vision-recognizer route ─▶ Selected model supports image input?
                                        ├─ Yes → Native image request, directly pass through the image block
                                        └─ No → Call the configured vision model to translate into text,
                                                the pure text model receives [Image Translation] result

In other words, native multimodal models see the original image block, while pure text models receive the text translated by the recognition model; the conversation brain remains unchanged.

Core Features

Providers and Protocols

Built-in 15+ domestic and international providers: OpenAI, Anthropic Claude, Google Gemini, OpenRouter, Azure OpenAI, Ollama (local), Alibaba DashScope, QwenCloud (Intl), Zhipu GLM, Baidu Qianfan, iFlytek Spark, Moonshot Kimi, Tencent Hunyuan, Volcengine Doubao, SiliconFlow; any OpenAI compatible endpoint can be accessed via a custom provider.

Protocol-wise, it supports OpenAI compatible (/chat/completions) and native Anthropic Messages simultaneously; Claude works out of the box.

Anti-Hang and Fallback Chain

  • Local / Anonymous endpoints have a hard 20s timeout limit;
  • HTTP 429 fails fast;
  • Failed endpoints are cooled for 60s;
  • Fast failure when no key and no local Ollama, with actionable guidance instead of hanging the request.

After the main model fails, the plugin tries each entry in fallbackModels in order (each item can point to a different vendor), reporting an error only after all fail, and listing every attempt.

Caching and Local Paths

  • Content hash caching: The same image is translated at most once per process (in-process cache, max 200 entries);
  • autoLocalOllama (enabled by default) probes http://localhost:11434, placing the running Ollama at the front of the fallback chain, keeping images off the host machine.

Installation and Activation

Installation requires only one command; the plugin has no build scripts and is completely dependency-free (no sharp approval needed):

dsh plugin --profile web add dsh-vision-recognizer

If the npm source is slow, you can specify a mirror:

dsh plugin --profile web add dsh-vision-recognizer --registry=https://registry.npmmirror.com

Local development installation:

dsh plugin --profile web add file:/path/to/dsh-vision-recognizer

Note that the file: prefix is required. Writing add . or add link: bare will cause pnpm to install the package via a symlink, causing the plugin’s schemastery dependencies to resolve from the source directory and fail to find them. This is a common issue with pnpm symlink installation, not a bug in the plugin itself.

After restarting dsh web, do three things:

  1. Select “DeepSeek + Intelligent Vision Recognition” in the model selector;
  2. Open Settings → Plugins → Vision, select a fallback vision provider, fill in the API key, and save;
  3. Paste an image in the conversation—the native multimodal selected model receives the original image directly, while the pure text selected model receives the [Image Translation] result.

No fallback key is needed when a native multimodal model is selected; for pure text models, when there is neither a key nor local Ollama, that round of conversation will fail fast and provide guidance instead of hanging.

Configuration Entry and Storage

All configuration can be done in Settings → Plugins → Vision: select provider, fill in API key, override model / endpoint / token limit / timeout / marker. Changes take effect immediately after saving, no restart required.

Configurations saved by the UI are written to $DSH_HOME/vision-recognizer.json; they are merged over the packaged defaults at startup; cordis.patch.yml only carries factory defaults; user overrides in cordis.patch.yml can still serve as fallbacks during the composition phase.

Pay attention to one patch semantic: the - insert: included in the plugin package will append this line to the entry list. If you write another - insert: with the same id (dsh-vision-recognizer) in your own cordis.patch.yml, the adapter will be registered twice (undefined behavior). To override individual keys, you should write a single top-level - id: dsh-vision-recognizer entry; a better approach is to use the Settings UI directly.

The order of key resolution is: key filled in UI → provider environment variable → $VISION_API_KEY / $DASHSCOPE_API_KEY.

Additionally, the default models for each provider are just starting points; model IDs drift over time and can be overridden in the Settings UI.

Scope and Known Limitations

Adaptive fallback only takes effect when the wrapping route “DeepSeek + Intelligent Vision Recognition” is selected; selecting other provider routes will call that route directly. rc8 does not expose a public decorator hook that can add fallback behavior to all existing routes uniformly.

rc8 also has two known limitations: capability lookup and target preparation distribution are separate public operations; adapters targeted during this small window may race with route decisions due to HMR replacement. Nested target delegation also enters the llm/stream waterfall (the README description at that point is truncated; refer to the repository for details).

Use Cases and Pre-installation Notes

Suitable for:

  • Users who mainly use DeepSeek as the conversation brain but want to be able to paste images anytime;
  • Users who want to switch between multiple vision providers anytime, or prioritize using local Ollama to keep images off the host machine;
  • Users who only use a single native multimodal model do not need this wrapping route; simply select that provider route directly.

Pre-installation note: The plugin runs with the permissions of the current dsh process; it is recommended to check the source code and license on the GitHub repository (this project is MIT) before installing.

Summary

dsh-vision-recognizer solves the problem of “wanting to paste images but not wanting to change the conversation brain” with an adaptive wrapping route: multimodal models receive images directly, pure text models automatically fall back to vision translation, and providers can be switched anytime in settings, with local Ollama working out of the box.

  • Plugin directory page: https://www.skillhub.cn/plugins/kaixinbaba/dsh-vision-recognizer
  • GitHub repository: https://github.com/kaixinbaba/dsh-vision-recognizer

The directory page is a community-maintained independent site with no official affiliation to DeepSeek / Huafan.