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 — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: 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★ 4103
Vision bridge for text-only models: paste an image, get structured JSON evidence (OCR, layout, semantics).
ysr666/dsh-vision-router★ 1127
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★ 887
Vision for text-only models: paste an image and the model switches to a Vision Toolkit variant for image Q&A, multi-image comparison, long-screenshot OCR, screenshot-to-UI reproduction, element grounding, and pixel diff. No API key by default — images are processed by the author-hosted free service, 100 per machine per day; configurable to your own provider.
dickpy/dsh-imagegen★ 99
AI image generation for the DSH Web GUI: text-to-image and image-to-image through a configurable OpenAI-compatible endpoint (gpt-image-2 / gpt-image-1 / dall-e-3), with an api_url/api_key settings card and a sidebar split-pane generation studio.
fandc520/dsh-comfyui★ 93
Drive a local or remote ComfyUI server from DeepSeek Harness: comfyui_run / comfyui_object_info / comfyui_workflow tools generate and edit images and videos, with a workflow library (graph extraction: per component / main flow / all), a load area with resolution auto-match, a live queue, SDXL and Wan 2.1 templates, a companion skill, and a same-origin media proxy.
sunxin-ai/dsh-design-qa★ 44
Design-fidelity QA for text-only models: a `deepseek_vision` tool borrows an eye from any OpenAI-compatible vision route, so the model can judge whether an implementation matches its mock — shipped with the benchmark behind that judgement (four fixtures, 23 injected defects, raw transcripts) and the questioning discipline it depends on.
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.