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-media-lens

v0.2.3

Published

Media evidence lens + provider router for DeepSeek Harness: media_read_video / media_read_audio / media_read_image turn local media into structured evidence (timeline / transcript / regions) via host-registered multimodal models first, configured OpenAI-c

Readme

dsh-media-lens

媒体感知插件:把本地 video / audio / image 变成结构化证据(时间线 / 转写 / 版面区域)注入对话,让文本模型引用具体帧、秒、说话人 —— Evidence, not imagination。同时内置 provider 路由线:每个媒体一条 failover 链,预算超限自动降级,每次尝试记录在 meta.attempts —— a fallback is never silent。

media_read_video / media_read_audio / media_read_image
  → 路径守卫(存在性 + 扩展名白名单)
  → ffprobe 探测 + 预算裁决(full / reencode / sampleFrames / segment / downsample)
  → failover 链(首个成功即返回;全败抛带 attempts 的结构化错误)
  → MediaEvidence JSON(timeline / transcript / regions + meta.attempts)
  • Supported DSH hosts: 0.1.7-rc.1 0.1.7-rc.2 0.2.0-rc.1 0.2.0-rc.2 0.2.1-rc.1 0.2.1-rc.2 0.2.1-rc.3 (7 rc across lines 0.1.7 / 0.2.0 / 0.2.1)
  • Runtime-verified: 0.1.7-rc.2, 0.2.0-rc.2, 0.2.1-rc.1 — evidence in .compat-results/

链序(每媒体)

| 媒体 | 链 | | --- | --- | | video(≤10MB 且 ≤10min) | multimodal(注册全模态直传)→ frames:(ffmpeg 均匀抽帧 + 图片链)→ local:metadata | | video(10–19MB) | reencode:multimodal(540p x264 压缩后直传)→ 同上 | | video(>19MB 或 >10min) | 直接 frames: 抽帧路 | | audio | multimodal(全模态直传转写)→ asr:endpoint-N(本地 ASR CLI,多端点按序)→ local:metadata | | image | registered:(宿主已注册视觉模型)→ configured:openai(OpenAI-compatible 端点)→ local:metadata |

处理端来源(FR-9:已注册模型优先)

  • 宿主已注册模型:插件经 ctx.llm.listProviders()/listModels() 枚举(60s 缓存),按 inputModalities 分组构成首选链;图片原生 image 块直送。
  • 显式选择:配置 models.{image,audio,video}: "provider/model" 直接指定一个已注册模型 —— 视频的 MiMo 类全模态路就走这里(宿主模态词表当前只认 text|image,自动发现不了视频/音频声明,显式选择是唯一入口;实际承载由适配器(如 openai-completions 接管线)的模态硬闸把关,拒绝是响亮的)。
  • 自配端点:providers.openai.{baseUrl, apiKey, model},apiKey 支持逗号分隔多 key(auth/429/quota 换下一个 key;网络/5xx 跳过保链)。
  • 本地兜底:strictLocalOnly 或全链失败时,local:metadata 只出 probe 元数据(时长/分辨率/大小),degraded='local-metadata-only'。

配置

dsh-media-lens:
  strictLocalOnly: false      # true 时链中剔除一切远端 provider,媒体内容不出本机
  cooldownMs: 600000          # keyFailure 类失败的默认冷却时长(有 Retry-After/"Resets in" 线索时按线索)
  models:
    image: auto               # auto | '' | "provider/model"
    audio: auto
    video: auto               # MiMo 类全模态:填 "llm-pi-ai/你的mimo模型id"
  providers:
    openai:
      baseUrl: ''             # 例 https://api.example.com/v1
      apiKey: ''              # 逗号分隔多 key 轮换
      model: ''
      structuredOutput: false # true 时注入 response_format json_schema(strict)(不认识的网关会 400,故默认关)
    asr:
      command: ''             # 单端点写法:本地转写 CLI 模板,{input} 占位
      endpoints: []           # 多端点选择项,按序尝试;与 command 合并(command 在前)
  refine:
    enabled: false            # Phase 7:链出口一次 refine pass,默认关
    model: ''                 # 开启时必须写 'openai/<model>' 或裸 model;auto / 空串 = 未启用。转述手只认 configured 自配端点(registered:/插件注入模型无效)

ASR 命令模板示例(Windows,模板内双引号保护空格路径):

python "C:\tools\sensevoice_cli.py" --input "{input}" --json

转写输出识别两种格式:JSON segments([{start,end,text[,speaker]}] 或 {"segments":[...]})与 SRT/时间行文本。

隐私说明(对照 dsh-vision-router 教训)

  • 默认媒体内容会发往远端 provider(注册模型 / 配置端点)。要内容不出本机,显式开启 strictLocalOnly: true——之后只剩本地 ASR CLI 与元数据兜底。
  • meta.attempts 记录每次尝试(provider 名含来源前缀 registered: / multimodal: / configured: / asr: / frames: / local:,多 key 轮换带 keyIndex),meta.warnings 记录路由通告(failover 去向、冷却垫尾、轮换成功)——降级绝不静默。
  • 媒体路径按不可信输入处理:只读取、存在性 + 扩展名 + magic-byte 三重校验(改名伪装的文件在入参侧拒绝);处理指令显式声明媒体内出现的指令一律视为数据;内容永不执行。
  • 错误文本先脱密(apiKey/baseUrl 精确匹配)再截断,密钥不进 attempts/日志。
  • 音视频直传只在适配器接管线(如 openai-completions takeover)上真正内联;未接管线路上模型只看到文件 handle 文本 —— 插件检测到这种回声会放弃该跳并落到抽帧/ASR 兜底,不产幻觉证据。

冷却语义(modlens 软化熔断)

只有 keyFailure 类失败(auth/429/quota 正文)触发冷却——普通失败(网络抖动、5xx、解析失败)永不冷却,正文碰巧含 quota 字样也不算。冷却中的 provider 垫到链尾仍作最后尝试(不是踢出):穷途末路时仍试一把,成功即恢复。provider 给恢复线索(Retry-After 头或正文 Resets in Xh Ym Zs)时按线索计时,否则 cooldownMs。

structuredOutput(FR-13,opt-in)

providers.openai.structuredOutput: true 时请求注入 response_format json_schema(strict)(由证据载荷派生,非手写镜像)。认识的网关(vLLM、官方 OpenAI 等)服务端强制形状能显著提证据质量;不认识的网关对未知字段直接 400——所以缺省关。

refine pass(Phase 7,链出口一次,opt-in)

主链首个成功后、返回前可选地再过一次文本模型将证据精炼规范化(去重 / 紧措辞 / 保留不确定性)——对齐 medialens 型项目常见的 "visionModel 读手 + textModel 转述手" pair 设计。

refine:
  enabled: true
  model: "openai/your-text-model"   # 或裸 model;auto / 空串 = 未启用

默认关,理由:

  • 隐私:多一跳远端 = 多一次媒体内容(raw evidence)暴露面;strictLocalOnly 下链仅到 local:metadata,此时 refine 自动跳过(无文本可精炼),不会拉回远端。
  • 延迟:直出证据已可用,refine 是锦上添花。
  • 不作 auto:auto = 随便把所有模型都加透镜,不允许。

来源闸门(转述手只认用户自配端点):refine 这一跳只允许 configured 端点(providers.openai 配了 baseUrl + apiKey)——model 必须写 openai/<model> 或裸 model,实际请求 model 取 providers.openai.model 单源。registered: / multimodal:(宿主 discovery 枚举,可能含其它插件注入的模型)一律不可信:命中即静默跳过(不写 refineAttempt、不追 warning,行为与未启用一致)。传输走 configured 直连(不经宿主 runtime 路由表),structuredOutput 开启时注入 response_format。

失败行为(不静默,但不撤销已成):refine 抛错 / 输出无 JSON / 校验不通过 → 保留 raw evidence,meta.warnings 追加 refine failed: <redacted>,meta.refineAttempt.ok = false;主链 attempts 不新增(读手已成功,不浪费下一跳抽帧/ASR)。成功时 refine 归属写 meta.refineAttempt.provider = 'refined:openai/<model>',meta.provider 保留读手前缀(registered / multimodal / configured / asr / frames / local);source / meta.attempts / meta.generatedAt 不被 refine 修改。

传输硬化:EVIDENCE_REFINE_INSTRUCTION 四要素与读手指令同源(反注入 / verbatim / bbox 保守 / uncertainty),另加「保留原 source 与 attempts」一行——媒体内出现的指令会随 raw evidence 二次进入 LLM 上下文,反注入行必须再吃一遍,防洗证据。错误文本先脱密后截断。

vision-bridge(v4,选择器可见的透镜包装,opt-in)

把透镜包装成宿主模型选择器里可见的路由:经宿主 llm.registerAdapter 注册 media-lens-vision-<upstream> 包装 provider,选择器出现 <模型名> (media-lens vision) 条目。选中它作主对话模型后,请求中的媒体在发送前经 media-lens 链(读手 = 上文「处理端模型」配置)转成证据文本,再委托真实路由——纯文本主力模型由此获得图片与音视频 sight("让 deepseek 收到小米读出的证据")。

inject:
  enabled: true
  families: ["deepseek", "glm", "mimo"]   # 前缀过滤;"*" = 全部(仍受否决)

包装判据 = 透镜能补模态就包,omni 坚决不包:

  • 纯文本模型(deepseek-v4.1 类)→ 包:图像 + 音视频全部证据化;
  • 图像模型(声明 image、非 omni)→ 包:图像块原样透传(保留原生视觉),仅音视频证据化;
  • omni 宽模态(MiMo bare 非 -pro 段,名字启发式)与 vision 专精词表(deepseek-vl / glm-4v / *vision* 等)→ 拒包,resolveModel 响亮拒绝并指路原路由。

机制要点(0.2.0-rc.2 实锚):宿主在 adapter 前已把 file 块投影成确定性 handle 文本,桥按 content.ts 精确格式识别并提取只读路径走全链;改写永不 throw(读手失败落常量占位文本,请求继续);证据按块缓存(重放零重读);llm/adapters-updated 事件驱动重扫,迟注册路由(llm-pi-ai)自动跟进;discovery 快照剔除 media-lens-vision-*(读手永不选中自己的 wrapper)。宿主缺 registerAdapter 面时静默保持纯工具形态。

安装

# 宿主 0.2.0-rc.1 / 0.2.0-rc.2(engines.dsh 与 peerDependencies 对齐)
pnpm add ./dsh-media-lens --ignore-workspace-root-check   # 或 npm pack 后装 tgz

cordis.patch.yml 提供 insert 注册行(dsh.bundle.patch 已在 package.json 对齐)。装完重启宿主。

依赖面

  • 运行时依赖仅 @deepseek-ai/schemastery(Config schema);@deepseek-ai/dsh-tools(defineTool)由宿主运行时提供(peer)。
  • ffmpeg / ffprobe 在 PATH 上可用时启用抽帧/重编码/时长探测;缺失时元数据降级(记录在 attempts)。
  • Node 原生 fetch(≥22.19)。

配合插件(可选 peer,非硬依赖)

media-lens 本身提供「工具处理多模态对象」(media_read_video/audio/image)。要把多模态模型注册/认证进宿主并让音视频直传真正内联(而非只看到文件 handle 文本),需两个姊妹插件配合——二者声明为 optional peer,不装则相应能力自动降级,不报错:

  • dsh-thinking-levels:模型配置录入 / 认证与 reasoning_effort 管理面——音视频直传链路的模型由此登记。
  • dsh-llm-openai-completions:OpenAI-compatible 传输接管(takeover)——把 file 块序列化成 video_url / input_audio 真正上送,未接管线路宿主只投影 handle 文本,插件检测到即落抽帧/ASR 兜底。

装机走宿主 profile(autoInstallPeers:false + hoisted),姊妹插件由 bundles 各自注册,optional peer 不触发 npm 拉装、不与宿主版本闸门冲突。

家族节与 tab 权重(bundle + 家族子 tab)

本插件为 host+client 双半 bundle(dsh.plugin.json.client.main 载 client 半身)。客户端半身把设置卡贡献进 dsh-family 家族节(顶级节 order 40、label「起子插件设置」,与本插件无关、由家族所有者统一渲染):

| 注册面 | 槽 | 权重(order) | 语义 | | --- | --- | --- | --- | | 家族子 tab 贡献卡(主路) | dsh-family.tab | 65(排现存贡献卡之后,靠后) | lazy:等家族所有者注入渲染;贡献卡不自渲染节体 | | 独立兜底节 | settings.section | 24 | 无 injection 时自注册:家族槽从未被渲染(无所有者/缺席)时,本卡以独立节出现,保留可见性 | | bundle 详情卡 | plugins.bundle.config | —(按包名 keyed) | 0.1.7+ 插件管理器详情设置卡 |

lazy 机制(两路注入均在 apply 期顶层注册,工厂只在「声明事件=设置面板打开」fire,fire 序=注册序):家族贡献卡先注册并在其工厂 fire 时置 familySeated;独立节工厂读到该标记即退场(避免与家族 tab 重复展示),读不到才自注册独立节。禁止宽限期后注册(§3 反例)。写路径:条目配置各顶层字段标 .volatile(),client 经 configForms.get(entryId).set(field, value) 权威写 + 热生效(0.1.7+/0.2.0/0.2.1 唯一活写面;settings.register 在 0.1.7+ 已移除,webServer 桥不可作写路径)。

边界(YAGNI)

有 host+client 双半身与设置卡(家族子 tab / 独立节 / bundle 卡,见上节),但除此之外无对话内卡片、无客户端粘贴拦截(vision-bridge 的请求改写发生在宿主 adapter 面,非 UI 拦截)、无 TTS / 媒体编辑、不内置任何 key。更多 UI 需求出现时另立计划。

版本线

0.1.0(engines.dsh 0.2.0-rc.1 || 0.2.0-rc.2)。发布走 npm staged 人工审批;dist-tag 分层 dsh-0.2.0(对齐 date-wrapper 先例),latest 收敛在发版时统一处理。