dsh-multimodal
Multimodal eyes and hands for DeepSeek Harness: vision transcription, OCR, and text-to-image via OpenAI-compatible backends, with an in-conversation generated-image card.
AI Analysis
核心用途是为 DSH 引入多模态视觉理解和绘图能力。适合需要图像识别、OCR 提取或通过兼容 API 进行 AI 绘图任务的用户。
Install
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:MC5lan/dsh-multimodalREADME
Read the full README ↗Usage
- Fastest path (recommended, 0.7+): Settings → Multimodal → 快速接入 → paste your API key — platform auto-detected and connected in one step (endpoint + allow-list + credential + model list; 识图/画图 enabled automatically). If the key can't be recognized, the hint says why; then pick a platform card or use a custom endpoint.
- Manual path: tap a preset card (Zhipu / Bailian / Xfyun / ModelScope / SiliconFlow / Qianfan / local Ollama) and paste the key, or declare any OpenAI-compatible endpoint in
extraProviders; optionally fillproviders.deepseek.modelsto advertise models on the built-in DeepSeek route slot. - In the Web UI model picker choose a
deepseek-visionmodel — that route's sessions get the "eye". - Chat normally; paste/drag an image and ask to have it read, or just say "draw me a …" to generate one.
Configuration (optional, ~/.dsh/settings.yaml)
dsh-multimodal:
# 0.2.1+ security: only these env/credential names may be used as API keys
allowedApiKeyEnvs:
- DEEPSEEK_API_KEY
# - MY_PROVIDER_API_KEY # add your custom provider's key env here
# 0.2.1+ security: extra vision hosts allowed to receive credentials
trustedBaseUrls:
# - https://my-vision.example.com # add your custom provider's host here
providers:
deepseek:
models: [] # optional: advertise models on the DeepSeek route slot
vision:
watchProvider: deepseek-vision # sessions on this route get the "eye"
transcribeProvider: '' # the provider that "sees" (blank = transcription off)
fallbackProviders: [] # 0.2.2+: providers tried in order when the primary rate-limits/fails
transcribeMode: auto # auto | verbatim | structured | ocr | describe | error-fix | chart-sql | design-code
parallelImages: false # 0.2.5+: transcribe each image in its own parallel call
costProvider: '' # 0.2.5+: cheap provider used for small images (cost routing)
costModel: ''
costMaxPixels: 1000000 # images ≤ this many pixels go to costProvider
sceneHints: true # 0.2.5+: append diagnosis hint to screenshot transcriptions
customModes: {} # 0.2.4+: custom mode name → prompt pairs (plugin-in transcribers)
redactSensitive: false # 0.2.4+: mask phone/ID/email in transcription output
auditLog: false # 0.2.4+: log a line per transcription (time/images/bytes/ms/provider)
ocr:
provider: '' # OCR tool engine (blank = disabled; any registered vision provider works)
model: ''
image:
backends: {} # add backends in the UI; nothing is preloaded
activeBackend: '' # image backend key (blank = no image generation)
failoverOrder: [] # 0.2.5+: backend keys tried in order when the active backend fails
verifyChineseText: true # 0.2.3+: check generated Chinese text for garbling via a vision model
verifyProvider: '' # vision provider used for the garbling check (blank = check disabled)
transcribePrompt: ... # custom transcription instruction
transcribeTimeoutMs: 90000 # transcription timeout
# Any OpenAI-compatible vision platform (just add the key; shows up in the model picker & Models page)
extraProviders:
xfyun-vision: # Xfyun MaaS
displayName: 讯飞星辰视觉
baseURL: https://maas-api.cn-huabei-1.xf-yun.com/v2
apiKeyEnv: XFYUN_API_KEY
models:
- id: xoppaddleocrv16 # free OCR (PaddleOCR-VL-1.6)
name: PaddleOCR-VL-1.6
siliconflow-ocr: # SiliconFlow (free hosted DeepSeek-OCR)
displayName: 硅基流动 OCR
baseURL: https://api.siliconflow.cn/v1
apiKeyEnv: SILICONFLOW_API_KEY
models:
- id: deepseek-ai/DeepSeek-OCR
name: DeepSeek-OCR
modelscope-vision: # ModelScope (2000 free calls/day)
displayName: 魔搭视觉
baseURL: https://api-inference.modelscope.cn/v1
apiKeyEnv: MODELSCOPE_API_TOKEN
models:
- id: Qwen/Qwen3-VL-8B-Instruct
name: Qwen3-VL-8B
Image backends (OpenAI-compatible /images/generations and DashScope protocols) example — add them in the UI or write them here:
dsh-multimodal:
image:
backends:
z-image: # Aliyun Z-Image family (new multimodal-generation sync protocol)
kind: dashscope-v2
baseURL: https://dashscope.aliyuncs.com
apiKeyEnv: DASHSCOPE_API_KEY
model: z-image-turbo
defaultSize: 1024*1024 # supports 512*512 ~ 2048*2048
modelscope-t2i:
kind: openai-images
baseURL: https://api-inference.modelscope.cn/v1
apiKeyEnv: MODELSCOPE_API_TOKEN
model:
activeBackend: z-image
Custom image backends (0.2.6+)
Anything that is not OpenAI-compatible or DashScope can be plugged in with a
small adapter file — no plugin code changes. Write an ES module exporting a
default object with a generate() function:
dsh-multimodal:
image:
backends:
my-api:
kind: custom
adapterFile: D:/my-adapters/my-api.mjs # absolute or relative path
baseURL: https://api.example.com/v1 # passed to the adapter
apiKeyEnv: MY_API_KEY
model: my-image-model
defaultSize: 1024*1024
activeBackend: my-api
failoverOrder: [z-image] # fall back to another configured backend
The adapter receives { prompt, size, n, negative_prompt, reference_image, apiKey, baseURL, model, signal, fetch, log } and returns
{ urls: string[], b64s: string[] }. See
scripts/adapters/example-custom.mjs
for a template. Only point adapterFile at files you trust — the adapter
runs with full process privileges. Polling backends can tune
pollIntervalMs / pollTimeoutMs per backend.