Native image attachments for text-only DeepSeek in the Web GUI: pasted or dropped images appear as thumbnails in the session, and before dispatch the host reads them with the free Zhipu GLM-4V-Flash vision API (glm-4v-flash fallback chain) and substitutes the description, so DeepSeek answers about the image while the original is kept in history.
Install
# from npm (prebuilt)
dsh plugin --profile web add dsh-dseyes
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:Okkay712/DSH-dseyes
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. Only install sources you trust, and pin a commit (github:owner/repo#sha).
README
中文 | English
DSH-dseyes gives text-only DeepSeek models a native image-attachment experience in DeepSeek Harness:
Paste or drop an image into the Web GUI composer, and it behaves like a normal AI chat:
- The image shows up as a thumbnail attachment (kept in history, click to zoom);
- Before the request reaches DeepSeek, the host reads the image with the free Zhipu GLM-4V-Flash vision model (
glm-4v-flash→glm-4.6v-flash→glm-4.1v-thinking-flashautomatic fallback chain); - DeepSeek receives the text description and answers based on the image content.
No extra commands, no manual conversion, no model changes.
How it works: DSH's
session.promptimage admission rejects images for text-only models (the DeepSeek adapter declaresinputModalities: ["text"]→MODEL_DOES_NOT_SUPPORT_IMAGES). DSH-dseyes does two things on the host:
- Admits the image — patches
llm.resolveModelInfoso the routed model claims image input, letting the image into the session (thumbnail, history and zoom all work natively);- Substitutes before dispatch — patches
llm.streamWithRegistration(the single choke point behind bothllm.streamandprepareCall().stream), replacing every image content block with a GLM description. DeepSeek only ever receives text, while the session keeps the real image.
Features
- 🖼️ Native upload UX: paste/drop image → thumbnail attachment → send → DeepSeek understands it.
- 🆓 Free:
glm-4v-flashis a free Zhipu model — register and use. - 🔒 Key never reaches the browser: the GLM key lives in env / secrets file, host-side only.
- 🔁 Automatic fallback chain:
glm-4.6v-flash→glm-4.1v-thinking-flashon failure. - 🗂️ Images preserved: originals stay in the session (thumbnail + click-to-zoom); descriptions feed the model.
- ⚡ Result cache: reuses the first description for repeated images across turns.
- 🩺 Self-check:
GET /dsh-dseyes/diagreports key presence and Zhipu connectivity.
Install
Prerequisite: a free Zhipu GLM API key
- Register/login at open.bigmodel.cn;
- API Keys → create one (format
id.secret;glm-4v-flashis free, no payment required).
Configure the key (either of these, priority top-down):
# Option 1: environment variable
set GLM_API_KEY=your-key # current shell
setx GLM_API_KEY "your-key" # permanent (Windows user env)
# Option 2: secrets file (shared with dsh-media-skills; takes effect immediately)
# Create %USERPROFILE%\.dsh\secrets\media-tools.env with one line:
GLM_API_KEY=your-key
ZHIPU_API_KEYis treated as an alias ofGLM_API_KEY; on Windows the plugin also readsHKCU\Environment\GLM_API_KEYlive.
Install the plugin
# Recommended: install from npm (published as dsh-dseyes)
dsh plugin --profile web add dsh-dseyes
# Or local development:
cd %USERPROFILE%\.dsh\profiles\web
pnpm add "file:D:\path\to\DSH-dseyes"
# then append "dsh-dseyes" to dsh.profile.bundles in package.json
Then restart the DSH Web GUI (fully quit and reopen).
Usage
- Paste (Ctrl+V) or drop an image into the chat input — a thumbnail rail appears above the input.
- Type a question (optional) and press send.
- DeepSeek understands the image and answers.
The original image stays in the history (click to zoom).
Real-world example
Paste an anime illustration and ask "What's in this image?":
🖼️ [image attachment thumbnail] What's in this image? Answer briefly.
🤖 DeepSeek:
According to the image description, this is a pixel-art anime illustration of a
cute girl with blue twin tails, big eyes, eating a yellow food (possibly ice
cream or cake). She's centered in the frame, dressed in white and black with
small golden accents and a little whale pattern on her clothes.
The image itself is kept as an attachment in the conversation history (click to zoom); DeepSeek answers from the host-side GLM-4V-Flash description — you never see the reading step.
Troubleshooting
If reading an image fails (e.g. no key configured), the message DeepSeek
receives contains a [图片内容无法识别:原因] placeholder and the conversation
continues. To self-check key presence and Zhipu connectivity, open in your
browser:
http://127.0.0.1:<dsh-port>/dsh-dseyes/diag
Example: {"ok":true,"diag":{"keyFound":true,"apiStatus":200,"apiOk":true}}
How it works
paste / drop image
│ (Web GUI native: thumbnail attachment)
▼
session.prompt (with image part)
│ ┌────────────────────────────────────────────┐
│ │ DSH-dseyes (host half) │
│ │ ① patch llm.resolveModelInfo │
│ │ → model claims image input → admission │
│ │ → image saved into session │
│ │ ② patch llm.streamWithRegistration │
│ │ → image blocks replaced with GLM text │
│ └────────────────────────────────────────────┘
▼
DeepSeek receives plain text → answers about the image
Development
npm install # or pnpm install (rollup dev dependency)
npm run build # produces lib/index.js
npm run watch # rebuild on change
Configuration
| Variable | Description |
|---|---|
GLM_API_KEY / ZHIPU_API_KEY |
Zhipu key (required) |
~/.dsh/secrets/media-tools.env |
Optional secrets file, shared with dsh-media-skills |
Privacy
- Images are sent only to Zhipu's official API (open.bigmodel.cn) for recognition.
- The key is never committed, never sent to the browser.
- Descriptions are used only in the model request; nothing is uploaded elsewhere.
License
MIT
Links
More in this category
liustack/modlens★ 3133
Vision bridge for text-only models: paste an image, get structured JSON evidence (OCR, layout, semantics).
ysr666/dsh-vision-router★ 770
Free vision for text-only agents: built-in keyless vision chain plus pixel tools (Q&A, grounding, crop, pixel diff, colors, OCR, SVG trace, cutout, screenshots); paste an image to use it.
Anionex/dsh-vision-toolkit★ 710
Vision tasks for text-only models: intent-aware image Q&A, long-screenshot OCR, UI reproduction, grounding, and pixel diff.
jing-hy/picturereader★ 22
Image "reading" for text-only models: downscale + reduce color depth + structure/color fingerprints into text grids fed back to the conversation, letting the model zoom, sample and OCR autonomously like a multimodal model; fully local with zero external model dependency, ships an image-reading methodology skill and optional PaddleOCR.
linenxi-ctrl/dsh-vision★ 12
External vision plugin for DeepSeek Harness: whale-button config panel, image recognition with auto-reply, and agent screenshot/recognize tools.
Flyvhidbwo/dsh-vision-proxy★ 11
DeepSeek brain + automatic image transcription: attach images in the GUI and each one is transcribed to text via any OpenAI-compatible VLM before reaching the text-only DeepSeek — a keyed fast path (default qwen3.7-flash; DashScope/Zhipu/OpenRouter or any OpenAI-compatible endpoint) with your own key, or local Ollama auto-detected with zero config.