dsh-periscope
文件与数据 活跃维护

dsh-periscope

lmh-2026/dsh-periscope

可自动识别请求是否携带图片,纯文本请求直连DeepSeek V4-Flash/V4-Pro,带图请求自动路由至官方视觉模型,无需手动切换模型配置,使用过程无需额外操作。

0
Stars 标星
0
Forks 分支
0
Watchers 关注
0
Open Issues
JavaScript
主要语言
MIT
开源协议
19 KB
仓库大小
1 个月前
最后推送
一键安装扩展 / 插件指令
dsh plugin --profile web add github:lmh-2026/dsh-periscope
git clone https://github.com/lmh-2026/dsh-periscope.git
git clone git@github.com:lmh-2026/dsh-periscope.git
README.md main

English | 简体中文

🔭 dsh-periscope

DSH plugin
license
version
node

🎯 Like a periscope, dsh-periscope lets a text-only DeepSeek model "see"
the imagery without ever switching models.

📎 Keep deepseek-v4-flash / deepseek-v4-pro as the session default and
automatically route every request that carries image content to the
official vision-capable model deepseek-v4-flash-vision-exp on the same
provider. Text-only requests stay on the text model. No manual switching, no
third-party vision model, no OCR — the image is sent raw to DeepSeek's own
vision model. ✨

🤔 Why

Most DSH "vision" plugins bridge a third-party vision language model (GLM /
Qwen / Gemini / Zhipu …) that transcribes the image to text, then hand the
description to DeepSeek. That needs an extra API key, adds a lossy
image→text step, and often requires picking a different provider. 😮‍💨

dsh-periscope takes the transparent route instead: it keeps your session on
a text model and swaps the wire model to deepseek-v4-flash-vision-exp
only for turns that actually contain images, using your existing
deepseek-official route and API key. The vision model sees the original
pixels. 🔍

⚙️ How it works

Two gates stand between pasting an image and it reaching a vision-capable
provider in a text-only session; this plugin clears both:

  1. 🚪 Host image admission — when you submit a message with an image, the
    host's prompt handler rejects it unless the session model declares image
    input (MODEL_DOES_NOT_SUPPORT_IMAGES). The plugin wraps
    llm.resolveModelInfo so every configured text model reports image input,
    letting the prompt (and its image) into the conversation.
  2. 🔀 Stream routing — every request funnels through
    llm.streamWithRegistration. The plugin wraps it: if messages contain an
    image block and the request is routed to one of the configured text models,
    it re-dispatches on the configured vision model, so the image blocks are
    actually sent (no [image omitted because this model accepts text only]
    projection, no UNSUPPORTED_CONTENT refusal).
text-only session (flash/pro)
  │  attach an image 📷
  ▼
host admission   ── resolveModelInfo wrapped → image admitted ✅
  ▼
llm.stream       ── streamWithRegistration wrapped
  │   messages contain an image?
  │     ├─ no  → pass through on deepseek-v4-flash / deepseek-v4-pro (zero-cost) ⚡
  │     └─ yes → re-dispatch on deepseek-v4-flash-vision-exp (official vision API) 🎯
  ▼
wire request     ── same provider + API key, image sent raw 📤

📦 Install

# from npm
dsh plugin --profile web add dsh-periscope

# from a local tarball
dsh plugin --profile web add .\dsh-periscope-0.2.0.tgz

Then restart the DSH app (the bundle list is read at startup). 🔄

🛠️ Configuration

Defaults work out of the box for the official DeepSeek setup:

Field Default Meaning
provider deepseek-official LLM route provider owning the models
textModels ["deepseek-v4-flash", "deepseek-v4-pro"] Text-only models whose image-bearing requests are routed to the vision model
visionModel deepseek-v4-flash-vision-exp Model used for requests with images

Override in the profile's cordis.patch.yml (user layer replaces the whole
row config):

- id: periscope
  config:
    provider: deepseek-official
    textModels: [deepseek-v4-flash, deepseek-v4-pro]
    visionModel: deepseek-v4-flash-vision-exp

The provider's catalog must contain the text models and the vision model whose
entry declares image input (the DeepSeek catalog already does). ✅

📝 Notes

  • The switch is per-request and content-driven: image turns run on the vision
    model (including the conversation history), text turns run on the text model.
  • The request-header log and token metering still record the text model (the
    header is written before the stream starts); this is a known cosmetic
    inaccuracy.
  • The read_image tool's own capability gate is not affected; it still uses
    the session route's declared input.

📄 License

MIT