dsh-vision-ocr

September 12, 2026 · View on GitHub

纯文本模型的"视觉替身"插件:通过调用本机 CLI 工具(默认 tesseract,可选 YOLO 风格检测器),让模型从本地图片里读文字、检出物体。所有子进程调用都走一条可注入的 runCommand(seam),因此单元测试完全确定性、永不真正启动二进制进程;无网络、无模型调用、无常驻进程(每次调用是一次超时会杀掉的短命 spawn)。

三个工具

工具参数说明
ocr_imageimagePath,可选 languages执行 [ocrCommand, imagePath, 'stdout', '-l', langs],返回 { ok, text, exitCode, stderrTail, error }。OCR 可执行文件缺失(ENOENT)时优雅返回 error: 'ocr executable not found',不抛异常。
detect_objectsimagePath,可选 threshold未配置 detectCommand 时直接返回 { ok:false, skipped:true, reason:'no detector configured', objects:[] }(不 spawn)。否则执行稳定契约 [detectCommand, '--source', imagePath, '--json'],把 JSON stdout 解析为 objects:[{label, confidence, box:[x,y,w,h]}];输出不可解析时返回 error: 'detector output not JSON'
describe_sceneimagePath,可选 languages组合调用:先走 OCR 路径,若配置了检测器再走检测路径,产出纯文本摘要 summary,形如 OCR found 123 chars; 2 objects detected: cat, remote

三个工具均 isConcurrencySafe() === true,可并行调度。

配置(YAML)

字段类型默认值说明
ocrCommandstringtesseractOCR 可执行文件
detectCommandstring''可选目标检测器可执行文件;空串 = 禁用检测
ocrLanguagesstringeng传给 -l 的语言列表(如 eng+chi_sim
timeoutMsnumber15000每次 spawn 的硬超时(毫秒)
maxOutputCharsnumber20000返回给模型的 OCR 文本上限(字符)

依赖与可用性

  • 要真正可用,需要在主机 PATH 上安装 tesseract(推荐同时装对应语言包,如 tesseract-ocr-chi-sim)。
  • 目标检测为可选项:需要自备一个符合契约的 YOLO 风格 CLI——入参 --source <图片> --json,stdout 输出 JSON(顶层数组或 { objects: [...] } 信封均可),每条含 labelconfidencebox:[x,y,w,h]
  • 二进制缺失不会让插件报错:相关工具会以 ok:false + 说明性 error 优雅降级。

安装

npx -y @deepseek-ai/dsh plugin --profile web add @qingshanjiluo/dsh-vision-ocr

测试注入缝(对宿主/测试可见)

apply(ctx, config) 接受可选的 config.runCommand(不属于 YAML 配置,由宿主或测试注入):

type RunCommand = (argv: readonly string[], timeoutMs: number) =>
  { code: number | null; stdout: string; stderr: string; error?: string }

缺省实现 defaultRunCommand 使用 node:child_processspawnSync(无 shell、带超时、绝不抛出,ENOENT 映射为 error: 'ENOENT')。单元测试注入假 runner,因此从不真正调用 tesseract 或任何真实二进制

开发

npm install --no-audit --no-fund
npm run build        # tsc + tsdown → lib/
npx vitest run       # 行为测试(全假进程)
node scripts/load-smoke.mjs