Back to home

Seryta

dsh-image-bridge

No description

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

Introduction

dsh-image-bridge — 图片理解桥接

DSH(DeepSeek Harness)插件:把用户在 Web GUI 里附加到消息中的图片,用视觉模型 (默认智谱 GLM-4V-Flash,免费)转成文字描述后注入对话,让 DeepSeek 这类纯文本 模型也能"看见"图片。

原理(挂载点)

  • 拦截点:agent/pre-step 瀑布事件。它在模型请求组装前运行,返回的 PreStepDecision.messages 就是进入本步的消息列表,可在进入前替换。
  • 图片数据结构:消息内容块里 { type: 'image', attachment: ImageAttachmentRef }; 图片字节由附件服务(ctx.attachments.readImage)按内容寻址引用取出。
  • 成功时把图片块替换为 [图片描述] … 文本块,文本块原样保留。
  • 图片准入:若所选模型声明 inputModalities: ['text'],harness 会在消息进入 循环前拒绝图片。需要配套一个补 image 模态声明的插件(见 llm-deepseek-image-admit, 或任何同类 provider 包装)。

韧性策略

  1. 单模型重试:429/503 指数退避重试(默认 2 次:1s、2s);
  2. 模型回退:404、重试耗尽、其他 5xx 换下一个模型;默认免费档降级链 glm-4.6v-flash → glm-4.1v-thinking-flash → glm-4v-flash;thinking 模型的 <think> 推理块自动剥离;
  3. 失败降级:全部失败时图片块替换为 [图片识别失败] … 说明文本——本轮 继续跑,模型如实告知用户;不放过图片块触发 UNSUPPORTED_CONTENT 整轮失败。

功能特性

  • attachmentId 转译缓存(单图消息):同一张图在后续步骤不再重复识别;
  • 体积/分辨率上限:超 maxImageBytes(默认 10MB)或 maxImagePixels (默认 40MP)直接失败说明,不送重试链;
  • tool-result 嵌套图片递归转录;
  • content parts 数组健壮性:网关返回 [{text}] 数组时按序拼接;
  • 四点式逐字转写 prompt:逐字文字 → 版面结构 → 视觉元素 → 其他细节, 完整优先于简洁;
  • 多厂商凭证 env 名:ZHIPU_API_KEY / ZHIPUAI_API_KEY / VISION_API_KEY / DASHSCOPE_API_KEY 依次尝试。

配置

环境变量默认说明
模型IMAGE_BRIDGE_MODELglm-4v-flash主模型名
回退模型IMAGE_BRIDGE_FALLBACKSglm-4.6v-flash,glm-4.1v-thinking-flash,glm-4v-flash逗号分隔,依次尝试
重试次数IMAGE_BRIDGE_RETRIES2单模型在 429/503 上的额外重试次数
描述语言IMAGE_BRIDGE_LOCALEzhzh 中文 / 其他英文
端点IMAGE_BRIDGE_BASE_URL智谱 OpenAI 兼容端点换任意 OpenAI 兼容 VLM(配对应 key env 名)
图片字节上限IMAGE_BRIDGE_MAX_IMAGE_BYTES10485760(10MB)超限直接失败说明
图片像素上限IMAGE_BRIDGE_MAX_IMAGE_PIXELS40000000(40MP)width×height 超限直接失败说明
单次请求超时—(仅 cordis config attemptTimeoutMs)30000 ms
总预算—(仅 cordis config budgetMs)75000 ms单条消息识别总时间上限

凭证读取顺序:环境变量 → ctx.credentials.resolve~/.dsh/.credentials.yaml 兜底解析(极简 KEY: value 行)。key 绝不进入日志。

安装

dsh plugin --profile web add github:Seryta/dsh-image-bridge

安装后重启 dsh web。纯手写 JS,零构建、零第三方依赖,仅用 Node 内置模块。

验证

# 单元自检(无网络、不读真实凭证,12 条路径)
node index.test.mjs

覆盖:成功替换、503 退避重试、404 回退、重试耗尽降级+notice、空响应降级、 无图片放行、无 key 降级、单图缓存命中、体积超限、<think> 剥离、 parts 数组拼接、tool-result 嵌套递归。

与同类插件的差异

项目形态本插件的取舍
dsh-vision-proxyprovider-route 包装 + 请求流内转录本插件挂 agent/pre-step 重写消息,不改 provider 路由;多模型统一生效
dsh-visionview_image 工具工具形态模型需主动调用;本插件自动转录、模型无感
modlensread_image 工具 + 模型变体 + 结构化 evidence本插件不引入模型变体与 schema 约束,零配置零构建

已知限制

  • 一次消息里多张图片合并为一次视觉 API 调用、一段描述;转译缓存按有序 attachmentId 组合键命中(同组同序的图片每步不重复识别;换序视为不同 组合、重新识别)。
  • 缓存按 attachmentId 存描述文本(上限 100,FIFO 淘汰);失败结果不缓存。
  • 图片不做压缩/缩放预处理;超限图片直接失败说明而非自动压缩。
  • 免费档 VLM 可能限流;重试/回退后仍失败走失败说明路径,对话不受影响。

License

MIT