dsh-see-now

visiontested: passnpmApache-2.0

Lets a text-only agent watch a live screen or camera feed: every frame is scored by how much the picture changed, only the ones that matter are packed into one numbered sheet with an audio envelope, so the model looks at what actually changed instead of a screenshot every few seconds.

下载量 / Downloads
6,403
依赖体积 / node_modules
1.98 MB
测试时间 / Tested
2026-11-06
DSH 版本 / Version
0.2.2-rc.1

Install

dsh plugin --profile web add dsh-see-now

Sandbox test results

StageResult
1 install✓
2 list✓
3 mount✓
4 boot—

Four stages run in an isolated sandbox: install (network on) → list → mount → boot (last three with no network).

README

See Now · 让 AI 实时看见你的屏幕

AI 不再"听你描述屏幕",而是自己看 —— 而且只传"画面变了"的那几帧。

一个给 DSH 用的实时视觉插件:把你的屏幕(或摄像头 / 视频文件)变成一串按变化量筛选过的画面,压进一张几帧拼成的图,交给模型。

静止的屏幕几乎不花钱;一镜到底的视频按"运动量"给帧;硬切幻灯片每切一次留一帧。


授权说明 / License

Apache License 2.0 —— 随便用。个人、公司内部、闭源产品、SaaS、二次分发都可以,

不需要问我要授权,也不收费。只要保留 [LICENSE](./LICENSE) 和 [NOTICE](./NOTICE) 这两份文件。

如果你觉得它替你省了时间,欢迎扫码打赏 —— 纯自愿,不影响上面任何一个字:

<p align="center">

<img src="./docs/images/reward-qr.png" alt="赞赏码(微信 / 支付宝)" width="240">

</p>

提交 PR 前读一下 [CONTRIBUTING.md](./CONTRIBUTING.md) —— 现在不需要签 CLA 了,

按 Apache-2.0 的规矩来就行。


看看它长什么样

调试窗(开发期用,不在发布包里):左边是抓到的每一帧,留下的带缩略图和格号,没留下的只剩一根分数条;右边是正在拼的那张图,按真实像素位置摆,新帧落格会亮一下,重排时格子会滑动。

逐场景模式(scene:true):每换一次画面单独出一张满幅图,右下角「已出图」每条都标着 1 帧 100%。

悬浮窗:AI 说的话在这里出现并被念出来(say 是唯一通道)。

外观可以在设置 › 看你看的东西 › 悬浮窗样式里换:实时玻璃(跟着桌面模糊,吃 CPU)、

静态磨砂(不抓屏,CPU 接近 0 —— 觉得卡就选它)、纯色、自动。改完立刻生效,

不用重开 DSH;它和陪看共用同一份 ~/.dsh/watch-window.json。


它解决什么问题

想让 AI 陪你看屏幕,最直觉的做法是"定时截全屏喂过去"。两个死结:

做法 · 问题

每 2 秒截一张全屏 · 一分钟 30 张图,全是重复画面,token 直接烧穿

每隔 30 秒截一张 · 中间发生了什么全丢了,AI 只会说"看起来你在用电脑"

See Now 换了个思路:先判断这一帧值不值得看,再决定传不传。

  • 每个画面帧先打一个 0–255 的"变化分"(HSV 三通道加权差,在 64×36 网格上算,约 0.2ms)
  • 只有"画面突然换了一张"或"一直在动、攒够了量"才留下来
  • 留下来的几帧拼进同一张图,一张图的固定成本摊到 4~8 帧上

结果:同样一段 30 秒的操作,别人烧 30 张图,这里常常只要 2~3 张。


有多省

场景 · 表现

静止屏幕(看文档、发呆) · 几乎不出图。20 秒给一张兜底帧,让你知道"确实没变"

滚网页、切窗口 · 变化剧烈 → 留几帧 → 每 15 秒左右给你一张

一镜到底的视频 · 没有切点,靠"积分"攒够一个采样点才出帧

硬切幻灯片(每张停 2 秒) · 每切一次留一帧,6 张照片 → 6 帧

成本口径(按宿主 DeepSeek-V4 的 patch 网格算:14px patch 向上对齐 → 42px 一格 → rows×(cols+1)+2):

档位 · 画布(画面 + 音轨条) · 每张 token

low(默认) · 798×450 + 12px = 798×462 · 222

standard · 1050×600 + 30px = 1050×630 · 392

high · 1260×720 + 36px = 1260×756 · 560

ultra · 1596×900 + 24px = 1596×924 · 860

一张图里塞 4 帧还是 8 帧,价格一样 —— 所以"多留一帧"几乎免费,"漏掉一帧"才贵。

宽度故意不对齐 16:9,而是对齐 42(800→798、1066→1050、1280→1260、1600→1596):

800 会被 pad 到 812 = 19.3 格,白算一整列;798 正好 19 列,面积只少 0.25%,每张省 11~24 token。

这是整个链路里唯一零代价的降本点(storyboard 那边也是这么干的)。

音轨条不额外花钱:token 是按 42px 一行算的阶梯函数,450 高的画面占 11 行、上界 462 ——

底下空着 12px 也照样收 11 行的钱。条就用这 12px(其余档位同理:600 余 30、720 余 36、900 余 24)。

所以"加条"和"不加条"的 token 完全一样,关掉它只是图干净一点,省不到钱。

看久了会变贵 —— 但原因不在这个插件

每张 222 token 只是编码成本。真正吃钱的是累积:图在会话历史里是一段 base64,

一张 798×450 的 PNG 约 130 KB,base64 之后约 173 KB。

DSH 有个「图片省略」机制:**单个请求里保留的 base64 图片总量超过 maxRequestImageBytes

(默认 20 MiB)时,它会把最老的图片永久替换成一段「附件路径」占位文字,然后重试。**

关键词是永久 —— 它改的是会话历史本身。历史一改,DeepSeek 的前缀缓存从被改的那个

位置往后全部对不上:每省略一张老图,那一段上下文就重新计费一次。

(社区实测:图片从第 43 万 token 处才开始出现,每省略一张,后面 14 万 token 重新算钱。)

换算:20 MiB ÷ 173 KB ≈ 120 张。dense 档 110 秒出 6 张(社区实测),一小时约 200 张 ——

半小时出头就撞线;默认节奏 15~40 秒一张,也在 1 小时上下。

这个插件拦不住它:省略发生在宿主发请求之前,插件只看得到自己交付的那张图。能做的只有:

  • 长会话分段:陪看一两小时后开个新会话,比让老图被反复省略便宜得多;
  • 别一直挂 dense:出图频率是默认档的两三倍;
  • 静止画面本来就不出图 —— 那段时间是真的免费。
真要根治得在宿主侧:让省略从最前面开始(连同更早的历史一起截),而不是在历史中间
挖一个洞 —— 那样前缀缓存仍然连续。这不在本插件的范围里。

快速开始

在 DSH 里用

已经发布到 npm,用 DSH 自带的 dsh plugin 装(它本质是 profile 维度的 pnpm 包装器 +

插件登记器,会在装前预检 engines/peer、装后自动把 dsh.bundle 写进 profile):

dsh plugin --profile web add dsh-see-now
  • web 是浏览器里用的那个 profile;桌面版换成 --profile desktop(那个 profile 需要先开过一次桌面端才会被初始化)。
  • 装完重启 DSH 生效(插件树在进程启动时组合)。
  • 重启之后不用新开会话:工具表是每一步重新组装的,旧会话下一轮就能看到 see_now

(宿主还会插一条 tool-addition 告诉模型多了这个工具)。所以「工具表在会话开头就定死了」

不成立 —— 挂不上多半是没重启,或者装的是旧副本。

  • 卸载:dsh plugin --profile web remove dsh-see-now
  • 升级:dsh plugin --profile web update dsh-see-now

关掉悬浮窗之后想再打开:点 × 只是这一次不看,插件不会自己弹回来。手动叫:

npx dsh-see-window            # 开窗(已经开着就什么都不做)
npx dsh-see-window --status   # 只看它在不在
npx dsh-see-window --force    # 杀掉重开
npx dsh-see-window --close    # 关掉

<details>

<summary>从源码装(改代码时用)</summary>

git clone https://github.com/SAOS-3624/dsh-see-now.git
cd dsh-see-now
node scripts/install-dev.mjs      # 拷进本机 DSH 的 desktop profile
install-dev 是复制不是软链(Node 解析裸包名要走真实路径,软链会找不到宿主的
@deepseek-ai/dsh-tools)。装完同样要重启 DSH。

</details>

平台

平台 · 屏幕引擎 · 要额外做的

Windows · ddagrab,不行退 gdigrab(自动探测) · 无

macOS · avfoundation · 系统设置 → 隐私与安全性 → 屏幕录制,勾上跑 DSH 的 App

Linux · — · 还没接(要补 x11grab / PipeWire)

「看屏幕」和「悬浮窗」是两件事,上表说的是采集引擎。悬浮窗(Tk)在 0.1.4 之前
在 macOS/Linux 上必崩(ctypes.windll,issue #40),现在能起来了:Windows 专有的
DPI/WDA 调用都按平台收口,没有 WDA 的系统改走"抓到自己就填掉"那条路。
Retina 上窗口坐标是逻辑像素、和 mss 的物理像素会差一个缩放倍数,背景可能对不齐 ——
那类机器在设置里选 frost(静态磨砂)或 solid(纯色),这两档都不抓屏,不吃这个亏。

ffmpeg 不用进 PATH:插件会按 DSH_FFMPEG_PATH / FFMPEG_PATH / DSH_FFMPEG_DIR /

~/.dsh/tools/ffmpeg/bin / ~/.dsh/bin 的顺序自己找(DSH 桌面版把 ffmpeg 装在第四个位置)。

然后让模型调:

see_now({ action: "watch" })          // 阻塞到你攒够一张图,然后把图交回来
see_now({ action: "watch", say: "…" }) // 同时说一句话(只有 say 会进悬浮窗、会被念出来)

第一次调用约 1 秒返回当前屏幕;之后每次返回"这段时间里发生的事"。

不进 DSH,当普通 Node 库用

包本身不依赖 DSH,capture / pipeline / png 都是独立导出的:

import { spawnFrames } from 'dsh-see-now/capture';
import { createPipeline } from 'dsh-see-now/pipeline';

const p = createPipeline({ width: 800, height: 450, fps: 12, queueDepth: 0 });
const run = spawnFrames({
  source: { kind: 'screen' },           // 或 { kind:'file', path:'x.mp4' }
  width: 800, height: 450, fps: 12,
  onFrame: (f) => p.push(f),
});

setInterval(() => {
  const sheet = p.take();               // 一张 PNG + 每帧的时间戳/档位/来源
  if (sheet) require('fs').writeFileSync(`sheet-${sheet.at}.png`, sheet.png);
}, 200);

声音

核心不内置任何 TTS 引擎,只 dynamic import 一个你指定的模块。配好之后,

say 会进悬浮窗并且被念出来;普通回复永远只有字。

// ~/.dsh/voice.json
{ "adapter": "/绝对路径/examples/voice-say-mac.mjs" }

自定义模型:适配器自己的配置走 options,原样交给 attach(api, options) ——

换自己训的模型不用改适配器源码:

// ~/.dsh/voice.json
{ "adapter": "D:/my-voice/index.mjs", "options": { 

…(truncated)

Rendered from the README published on npm. Formatted only, not edited.

Versions

Published on npm::16,最后更新 2026-11-06

Links

GitHub · Homepage · npm

Same category