npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

dsh-vision-plugin

v1.4.0

Published

dsh-vision-plugin: give DeepSeek Harness text-only models a pair of eyes — pasted images are transcribed by a vision model before they reach a text-only main model, plus the vision_analyze tool and a bilingual settings page.

Readme

dsh-vision-plugin

给 DeepSeek Harness 的纯文本模型装上"眼睛"。

English | 中文

#dsh-plugin

v1.4.0 · MIT License · 兼容 dsh v0.1.0-rc.8(及 rc.7)


deepseek-v4 系列是纯文本模型:你可以在对话框里粘贴截图、照片,但它看不见。这个插件在中间加了一层——图片先交给视觉模型(qwen3.7-plus、kimi-k3 等)转写成文字描述,再把描述交给主模型。从此粘贴图片、切换任何文本模型,都能正常"看图"

效果

你:这是什么?                          (粘贴了一张 Clash Verge Logo)

助手:这是 Clash Verge 的标志(Logo)。左侧是一个黑色的猫头剪影,
     右侧是文字 "Clash Verge"。它是一款基于 Clash 内核的图形化
     代理客户端软件……

图片由视觉模型自动转写,主模型看到的是文字描述,回答和读图效果一样自然。

三个能力

  1. 粘贴图片直接问 —— 对话框粘贴或拖入图片,任意文本模型都能回答图片内容,不需要任何特殊指令。
  2. vision_analyze 工具 —— 模型可以主动调用它分析本地图片文件,还能指定问题("图中表格第三行数据是多少?")和具体视觉模型。
  3. 设置页配置视觉模型 —— DSH 设置面板新增"视觉模型"页:选默认视觉模型、看当前路由,中英双语、跟随界面语言。

快速开始

永久安装 —— 每次 dsh 启动自动载入

本仓库根目录就是一个 dsh bundle 包dsh-vision-plugin):宿主半部 lib/index.js、浏览器半部 lib/client.js、 插件行 cordis.patch.yml。把 bundle 注册进你的 profile, dsh 启动时就会自动挂载插件——不需要 cordis_define/cordis_run,重启也不丢。

① 用 dsh plugin 安装。 包已发布到 npm,一条命令搞定——dsh plugin 用 pnpm 装好包后,因为包声明了 dsh.bundle,会自动把它追加进 dsh.profile.bundles

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

正在开发插件本身?改用本地检出安装——下次重启 dsh 即生效,无需走 registry:

dsh plugin --profile web add /绝对路径/deepseek-harness-plug
# 或在检出目录里直接:
dsh plugin --profile web add .

然后确认行已合成:

dsh --profile web --dump-config        # 合成树里应出现 "vision" 行

② 声明图片能力。 宿主在消息进入会话前会检查当前模型的输入能力。为了让文本模型收下图片(收下后由插件转写),在 ~/.dsh/settings.yaml 里给它们声明:

llm-pi-ai:
  providers:
    opencode-go:
      apiKeyEnv: OPENCODE_GO_API_KEY
      modelOverrides:
        deepseek-v4-flash:
          input: [text, image]
        deepseek-v4-pro:
          input: [text, image]
        # 其他可能切换到的文本模型同理;原生视觉模型无需声明

文件会被自动热加载,不用重启。建议把每个你可能用到的文本模型都写上——否则切到未声明的模型后粘贴图片,会在插件转写之前就被拒绝。

dsh v0.1.0-rc.8 及以上另有原生方案:内置的 deepseek-official 路由(llm-deepseek)支持配置启用原生图片请求,DeepSeek 模型可以直接在它自己的配置里声明图片能力:

llm-deepseek:
  models:
    - id: deepseek-v4-flash
      inputModalities: [text, image]

插件信任这条路由:在该路由上声明图片能力的模型,设置页里会标记「原生视觉」、以兜底梯队加入自动选择、且图片不再转写(rc.8 适配器会自行强制校验所声明的能力)。pi-ai 路由的 modelOverrides 仍然只是"放行"机制——这类模型照旧转写,行为与之前完全一致。

③ 重启 dsh。 启动时 loader 会挂载 vision 行:注册 vision_analyze 工具、开启 llm/stream 图片转写瀑布、/vision/api/state 服务设置页,浏览器半部由 /plugins/dsh-vision-plugin/client.js 提供。验证:设置面板出现"视觉模型"页、工具列表里有 vision_analyze,然后粘贴图片开聊。

设置界面

打开 DSH 左下角 ⚙️ 设置 → "视觉模型"页:

  • 状态徽章显示运行状态和版本号
  • 下拉框选择默认视觉模型(自动选择,或指定某个模型)——保存立即生效,且选择会被记住(浏览器本地存储),下次启动自动恢复
  • 底部说明当前生效的模型和路由

界面语言跟随 DSH 设置(通用 → 语言),中英文自动切换。

常见问题

切到其他文本模型后粘贴图片被拒? settings.yaml 里没有给那个模型声明图片能力。按上面步骤 ② 补上即可,热加载立即生效。

没有配置 opencode-go 怎么办? 不影响。v1.1.0 起插件会遍历所有已配置的 provider,自动找到第一个带视觉模型的路由;一个都没有时才会降级(对话继续,提示图片不可用)。

**我的 provider 拒绝图片,报 unknown variant \image_url`, expected `text`?** 这个错误说明图片块被发给了只接受文本的模型。自动选择绝不会这么做:只会自动挑受信任的模型——原生视觉白名单(lib/engine.js里的NATIVE_VISION_MODELS),以及 dsh v0.1.0-rc.8 起在内置 deepseek-official路由上声明了图片能力的模型。但设置页会列出**所有 provider 上目录声明支持图片的全部模型**——受信任的和你在 settings.yaml 里用modelOverrides声明图片能力的都算,显式选择(设置页或vision_analyzemodel` 参数)会被采纳。如果选中的模型上游实际拒绝图片,调用会自动回退到受信任的视觉模型(一个都没有时降级为占位提示)。如果你用的模型确实支持原生视觉但还没进白名单,把它加进去,自动选择就会优先用它。

DSH 重启后插件还在吗? 会。永久安装把 bundle 注册进 profile 的 dsh.profile.bundles,每次启动都会自动载入——这正是它的目的。

会多花钱吗? 转写会调用一次视觉模型;同一张图、同一个问题有缓存,多轮追问不会重复调用。视觉模型优先级:工具显式参数(model/provider)> 设置页配置 > 自动选择。

我选的视觉模型会被记住吗? 会。v1.2.0 起设置页的选择保存在浏览器(localStorage),下次启动 dsh 自动恢复;自动转写瀑布也走同一路由。宿主侧的路由本身是进程内的。

视觉模型出错了会怎样? 不会中断对话:输出了一部分就保留一部分;完全失败就换备用模型再试一次;视觉调用挂起超过两分钟会被掐断并视为失败(从而触发备用模型重试);还不行就告诉模型"图片暂时不可用",对话照常继续。

Bundle 结构

  • lib/engine.js —— 共享引擎,单一事实源vision_analyze 工具、llm/stream 转写瀑布、路由发现、缓存与超时。刻意零 import(pnpm 不会为 link: profile 插件安装依赖)。
  • lib/index.js —— bundle 宿主适配器(组合插件行 vision):注册工具与瀑布;/vision/api/state/vision/api/model JSON 接口通过 ctx.inject(['webServer'], …) 条件注册,因此没有 Web 服务的栈(headless——rc.8 的启动审计会直接判挂起等待缺失服务的行)也能正常激活。
  • lib/client.js —— bundle 浏览器半部(dsh.client 名册条目):"视觉模型"设置页,由 web shell 在 /plugins/dsh-vision-plugin/client.js 提供。
  • cordis.patch.yml —— 挂载该 bundle 的 loader 补丁行(dsh.bundle.patch)。
  • scripts/check.js —— 一致性检查(npm run check):校验版本号在各处一致、lib/engine.js 保持零 import。
  • test/engine.test.js —— 引擎测试套件(npm test):路由发现、override 优先级、缓存/去重、超时、瀑布、工具。

开发插件本身:改 lib/engine.js(宿主逻辑)或 lib/client.js(界面),然后 npm run check && npm test

深入细节(可选阅读)

工作流程:图片进入会话 → llm/stream 监听器判断目标模型——原生视觉模型直接看原图;文本模型则先由视觉模型转写成文字再派发。"原生视觉"指任意路由上的白名单模型,或(dsh v0.1.0-rc.8 起)宿主自有 deepseek-official 路由上目录声明支持图片的模型——该路由的适配器会自行强制校验声明的能力。图片检测是递归的(与宿主一致):嵌套在 tool-result 里的图片、以及助手消息里的图片(来自视觉模型会话的历史)同样会被转写或替换,保证任何图片块都不会到达纯文本模型。转写请求带 Symbol 标记防递归,结果按"图片 + 问题"缓存(TTL + FIFO 上限,并发同图共享一次在途调用)。

设置页会列出所有 provider 上目录声明支持图片的全部模型——不限于 opencode 路由:受信任的原生视觉模型(白名单 + rc.8 deepseek-official),以及你通过 modelOverrides 声明图片能力的模型都显示。只有自动选择走信任门控:resolveVisionRoute 只会挑受信任的模型,因为 pi-ai 路由上仅凭目录的"图片能力"无法和 modelOverrides 广告区分,纯文本模型会在上游直接拒绝图片块(unknown variant \image_url``)。显式选择则信任用户配置;若所选模型上游失败,现有重试逻辑会自动回退到受信任的视觉模型。

可调常量都在 lib/engine.js 顶部:DEFAULT_MODEL(兜底模型)、NATIVE_VISION_MODELS(自动选择用的原生视觉白名单)、DEEPSEEK_OFFICIAL_PROVIDER(rc.8 声明图片能力即受信任的路由)、MODEL_PRIORITY(自动选择顺序)、STREAM_TIMEOUT_MS(视觉调用挂起超时)、CACHE_TTL_MS / CACHE_MAX(转写缓存)、CATALOG_TTL_MS(模型目录缓存)。

License

MIT