Back to home

ariesy

dsh-vision

DeepSeek Harness (DSH) dynamic Cordis plugin: global image upload button + configurable vision-model recognition with fallback

Stars
0
Language
JavaScript
Created
Aug 16, 2026
Updated
Aug 16, 2026

Introduction

dsh-vision

一个运行在 DeepSeek Harness (DSH) 上的动态 Cordis 插件:为所有会话提供图片上传能力,并用可配置的视觉模型自动识别图片,支持 fallback 回退链。

源码整理为独立项目,存放在 /app/dsh-vision/

功能

能力说明
📎 全局上传按钮每个会话的输入框工具行出现上传按钮;选图后图片作为草稿缩略图附加到消息,同时文件保存到该会话工作区的 uploads/ 目录
自动图片识别消息中的图片由视觉模型识别,识别结果以文字笔记注入模型上下文([uploaded image recognized by vision model <model>])
任意视觉模型选择设置页自动列出所有声明支持 image 输入的模型,可任选其一作为主识别模型
Fallback 回退主模型识别失败(报错或空结果)时自动切换备用模型;可独立开启/关闭
无配置默认行为未配置时按名称优先(vl/vision/image 匹配)自动选择识别模型,避免误选不支持识别的模型

设计要点

  • Host halfsrc/host.js):拦截 llm/stream waterfall。请求含图片时,先对每张图片调用视觉模型识别(不带 system 消息 —— 某些网关只认同一条用户消息内的图片),再把图片块替换为文字笔记。识别请求本身通过 inFlight 防重入保护。
  • Client halfsrc/client.js):注册两个 Slot —— conversation.input.left(上传按钮)与 settings.plugins.tab("图片识别"设置页)。Client 与 Host 之间仅通过包私有 JSON RPC(host.call)通信。
  • 配置存储:动态插件是进程内的,配置保存在进程内存中(主模型/fallback/开关),随插件生命周期;DSH 重启后需重新定义并运行插件。

安装

方式一:动态插件(推荐,无需重启 DSH)

src/host.jssrc/client.js 正是动态插件定义所需的 code.host / code.client 函数体,可直接使用:

  1. 获取源码:
git clone https://github.com/ariesy/dsh-vision.git
# 或直接用本机路径 /app/dsh-vision
  1. 在 DSH 中定义动态插件(可通过 GUI 的插件运行卡片,或会话内 cordis_define):
    • plugin 前缀任取(如 dsv),插件名 dsh-vision
    • code.hostsrc/host.js 内容
    • code.clientsrc/client.js 内容
  2. 运行该插件并在运行卡片上批准
  3. 刷新浏览器页面(动态插件的 Client half 在页面加载时注入):
    • 输入框工具行左侧出现 📎 上传按钮
    • 设置 → 插件 → 图片识别 出现配置页

注意:动态插件是进程内的 —— DSH 重启后需重新定义并运行(步骤 2–4)。

方式二:作为标准 Cordis 插件行

需要把两文件包装为标准插件模块后放入预设的 cordis.yml

// host-plugin.js —— 包装示例
module.exports = {
  apply(ctx) {
    return /* 粘贴 src/host.js 中 `return { ... }` 的内容 */;
  },
};
// client-plugin.js —— 包装示例(同理,返回 src/client.js 中的 `return { ... }` 内容)
module.exports = {
  apply(ctx) { ... },
};
# cordis.yml 或预设 composition
- id: dsh-vision-host
  name: ./host-plugin.js
- id: dsh-vision-client
  name: ./client-plugin.js

方式三:由 DSH 自主阅读并安装

在任意 DSH 会话中直接下达指令,让 agent 读取本项目源码并完成定义、运行:

阅读 /app/dsh-vision 项目(或 git clone https://github.com/ariesy/dsh-vision.git),
把 src/host.js 与 src/client.js 分别作为 code.host / code.client 定义并运行同名动态插件。

agent 会自主完成:读取源码 → cordis_define 定义插件(名称 dsh-vision)→ cordis_run 运行。之后同样需要你在运行卡片上批准,并刷新浏览器页面使 Client half 生效。

该方式与方式一本质相同,只是由 agent 代为读取和提交代码,适合不想手动复制粘贴的场景。

使用

  1. 在 DSH 中定义并运行此插件的 Host + Client 代码(通过动态插件运行卡片,批准后生效)。
  2. 刷新浏览器页面。
  3. 任意会话:点击输入框工具行左侧的 📎 上传图片 → 图片附加为缩略图 → 发送消息 → 自动识别并回复。
  4. 配置:设置 → 插件 → 图片识别
    • 主识别模型:下拉选择任意视觉模型(或"自动选择")
    • Fallback 模型:下拉选择备用模型(或"不使用 fallback")
    • 勾选"主模型失败时启用 fallback"
    • 保存配置 / 刷新模型列表

项目结构

/app/dsh-vision/
├── package.json     # 项目元数据(npm 项目壳)
├── README.md        # 本文档
└── src/
    ├── host.js      # Host half:llm/stream 拦截、识别链、配置与上传 RPC
    └── client.js    # Client half:上传按钮 + 设置页 UI

验证

cd /app/dsh-vision && npm run check   # node --check 两个源码文件

运行时验证样例(2026-08 环境):用户上传一张《帝港海湾豪园缴费通知单》图片,模型识别并给出准确描述(期间费用区间、金额 198.64 元、制单日期等字段全部正确)。

依赖的 DSH 接口

  • ctx.get('llm')listProviders()listModels(provider)stream(options)
  • 事件:llm/stream(waterfall,ctx.on
  • harness.handle(method, handler):包私有 RPC
  • Client:slots.inject/slots.registerhost.call、React(无 JSX)
  • ctx.get('agents') / ctx.get('subprocess') / ctx.get('fs'):上传文件落盘