🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

视觉截图电脑操作 xie129716/computer-user-vision

DeepSeek Harnessv0.4.0
xie12971649 天前有提交已提供中文文档扫描:含敏感能力

截图直传视觉模型,精准换算坐标并操控鼠标键盘

29.9/100
综合分
1
GitHub 星标
320
npm 周下载
—/5
用户评分

数据截至 2026/9/16 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add computer-user-vision
npm 源 · computer-user-vision 的发布者账号已校验与本仓库一致

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · vision
装得上吗
本站已在 dsh 0.2.1-rc.5 下真实安装成功
非静态推断
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 49 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查✓ 自动检查通过
展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✓npm 包computer-user-vision @ 0.4.0
✓Node 引擎要求 ^22.19 || >=24 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/9/30 17:16:36

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 73 处,展示前 73 条)
  • 读取本地文件
    src/index.js:48
    return JSON.parse(readFileSync(joinPath(here, '..', 'package.json'), 'utf8')).version ?? '0.0.0';
  • 写入本地文件
    src/index.js:196
    mkdirSync(dir, { recursive: true });
  • 写入本地文件
    src/index.js:197
    appendFileSync(joinPath(dir, 'route.log'), `${new Date().toISOString()} ${message}\n`, 'utf8');
  • 发起网络请求
    client.js:427
    fetch(CONTROL_API, { headers: { accept: "application/json" } })
  • 发起网络请求
    client.js:452
    fetch(CONTROL_API, {
  • 读取本地文件
    src/tools.js:650
    const data = await readFile(res.path);
  • 执行外部命令固定命令
    src/ps.js:26
    const child = spawn(
  • 写入本地文件
    src/overlay.js:58
    try { writeFileSync(pausePath, '1', 'utf8'); } catch { return false; }
  • 删除本地文件
    src/overlay.js:65
    try { rmSync(pausePath, { force: true }); } catch { }
  • 读取本地文件
    src/overlay.js:71
    if (!existsSync(stopPath)) return null;
  • 读取本地文件
    src/overlay.js:72
    const raw = readFileSync(stopPath, 'utf8').trim();
  • 删除本地文件
    src/overlay.js:87
    try { rmSync(stopPath, { force: true }); } catch { }
  • 写入本地文件
    src/overlay.js:92
    mkdirSync(dir, { recursive: true });
  • 写入本地文件
    src/overlay.js:93
    writeFileSync(heartbeatPath, String(Date.now()), 'utf8');
  • 写入本地文件
    src/overlay.js:103
    mkdirSync(dir, { recursive: true });
  • 删除本地文件
    src/overlay.js:104
    rmSync(stopPath, { force: true });
  • 删除本地文件
    src/overlay.js:105
    rmSync(pausePath, { force: true });
  • 执行外部命令固定命令
    src/overlay.js:128
    const probing = spawn('powershell.exe', [
  • 删除本地文件
    src/overlay.js:167
    try { rmSync(heartbeatPath, { force: true }); } catch { }
  • 删除本地文件
    src/overlay.js:168
    try { rmSync(pausePath, { force: true }); } catch { }
  • 读取本地文件
    src/approvals.js:35
    const parsed = JSON.parse(readFileSync(file, 'utf8'));
  • 写入本地文件
    src/approvals.js:48
    mkdirSync(dirname(file), { recursive: true });
  • 写入本地文件
    src/approvals.js:49
    writeFileSync(file, JSON.stringify(state, null, 2), 'utf8');
  • 执行外部命令来自配置/变量
    verify/doctor-heal.mjs:19
    const r = spawnSync(process.execPath, [DOCTOR, ...args], { encoding: 'utf8' });
  • 写入本地文件
    verify/doctor-heal.mjs:23
    await copyFile(INDEX, BACKUP);
  • 读取本地文件
    verify/doctor-heal.mjs:24
    let source = await readFile(INDEX, 'utf8');
  • 写入本地文件
    verify/doctor-heal.mjs:40
    await writeFile(INDEX, source, 'utf8');
  • 读取本地文件
    verify/doctor-heal.mjs:42
    const broken = await readFile(INDEX, 'utf8');
  • 执行外部命令来自配置/变量
    verify/doctor-heal.mjs:61
    const reg = spawnSync(process.execPath, [join(import.meta.dirname, 'registration.mjs')], { encoding: 'utf8', cwd: PROFILE });
  • 写入本地文件
    verify/doctor-heal.mjs:67
    await copyFile(BACKUP, INDEX);
  • 删除本地文件
    verify/doctor-heal.mjs:68
    await rm(BACKUP, { force: true });
  • 执行外部命令固定命令
    verify/element-refs.mjs:179
    const child = spawn('notepad.exe', [], { detached: true, stdio: 'ignore' });
  • 执行外部命令固定命令
    verify/general-workflows.mjs:95
    const p = spawnSync('powershell.exe', ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', script],
  • 执行外部命令固定命令
    verify/general-workflows.mjs:130
    spawnSync('powershell.exe', ['-NoProfile', '-Command', 'Start-Sleep -Milliseconds 120'], { stdio: 'ignore' });
  • 执行外部命令固定命令
    verify/general-workflows.mjs:179
    const notepad = spawn('notepad.exe', [], { detached: true, stdio: 'ignore' });
  • 执行外部命令固定命令
    verify/general-workflows.mjs:211
    const calcProc = spawn('calc.exe', [], { detached: true, stdio: 'ignore' });
  • 执行外部命令固定命令
    verify/general-workflows.mjs:426
    spawnSync('powershell.exe', ['-NoProfile', '-Command',
  • 执行外部命令固定命令
    verify/general-workflows.mjs:430
    if (/notepad|记事本/i.test(w.class + w.title)) spawnSync('taskkill', ['/PID', String(w.pid), '/F'], { stdio: 'ignore' });
  • 执行外部命令固定命令
    verify/overlay-hit.mjs:63
    const ps = spawnSync('powershell.exe', ['-NoProfile', '-Command',
  • 执行外部命令固定命令
    verify/overlay-hit.mjs:71
    spawnSync('powershell.exe', ['-NoProfile', '-Command',
  • 执行外部命令固定命令
    verify/overlay-hit.mjs:183
    const ps = spawnSync('powershell.exe',
  • 删除本地文件
    verify/overlay-hit.mjs:191
    rmSync(stopFile, { force: true });
  • 删除本地文件
    verify/overlay-hit.mjs:192
    rmSync(heartbeat, { force: true });
  • 删除本地文件
    verify/overlay-hit.mjs:193
    rmSync(pauseFile, { force: true });
  • 执行外部命令固定命令
    verify/overlay-hit.mjs:212
    const overlay = spawn('powershell.exe',
  • 删除本地文件
    verify/overlay-hit.mjs:295
    rmSync(stopFile, { force: true });
  • 读取本地文件
    verify/overlay-hit.mjs:300
    const wrote = existsSync(stopFile);
  • 读取本地文件
    verify/overlay-hit.mjs:306
    const why = readFileSync(stopFile, 'utf8').trim();
  • 删除本地文件
    verify/overlay-hit.mjs:314
    rmSync(stopFile, { force: true });
  • 删除本地文件
    verify/overlay-hit.mjs:315
    rmSync(heartbeat, { force: true });
  • 执行外部命令固定命令
    verify/overlay.mjs:41
    const ps = spawnSync('powershell.exe', ['-NoProfile', '-Command',
  • 执行外部命令固定命令
    verify/overlay.mjs:55
    try { spawnSync('powershell.exe', ['-NoProfile', '-Command',
  • 读取本地文件
    verify/overlay.mjs:73
    check('activity() writes the heartbeat', existsSync(heartbeat));
  • 读取本地文件
    verify/overlay.mjs:74
    if (existsSync(heartbeat)) {
  • 读取本地文件
    verify/overlay.mjs:75
    const age = (Date.now() - statSync(heartbeat).mtimeMs) / 1000;
  • 读取本地文件
    verify/overlay.mjs:78
    check('no stop marker is written by the plugin itself', !existsSync(stopFile));
  • 读取本地文件
    verify/overlay.mjs:83
    check('shutdown() removes the heartbeat', !existsSync(heartbeat));
  • 读取本地文件
    verify/overlay.mjs:84
    check('shutdown() leaves no stop marker', !existsSync(stopFile));
  • 读取本地文件
    verify/plugin-exports.mjs:18
    const profilePkg = JSON.parse(await readFile(join(PROFILE, 'package.json'), 'utf8'));
  • 读取本地文件
    verify/plugin-exports.mjs:33
    try { entries = await readdir(dir, { withFileTypes: true }); } catch { return out; }
  • 读取本地文件
    verify/plugin-exports.mjs:51
    try { await stat(dir); } catch { continue; }
  • 读取本地文件
    verify/plugin-exports.mjs:57
    try { src = await readFile(file, 'utf8'); } catch { continue; }
  • 读取本地文件
    verify/ps1-hygiene.mjs:40
    for (const entry of await readdir(dir, { withFileTypes: true })) {
  • 读取本地文件
    verify/ps1-hygiene.mjs:59
    const buf = await readFile(file);
  • 读取本地文件
    verify/ps1-hygiene.mjs:78
    const text = await readFile(file, 'utf8').catch(() => '');
  • 执行外部命令固定命令
    verify/ref-snapshots.mjs:96
    const np = spawn('notepad.exe', [], { detached: true, stdio: 'ignore' });
  • 执行外部命令固定命令
    verify/ref-snapshots.mjs:165
    const calc = spawn('calc.exe', [], { detached: true, stdio: 'ignore' });
  • 执行外部命令固定命令
    verify/ref-snapshots.mjs:224
    if (/notepad|记事本/i.test(w.class + w.title)) spawnSync('taskkill', ['/PID', String(w.pid), '/F'], { stdio: 'ignore' });
  • 读取本地文件
    verify/vision-screenshot.mjs:31
    const buf = await readFile(path);
  • 写入本地文件
    verify/vision-screenshot.mjs:60
    await writeFile(tmp, data);
  • 删除本地文件
    verify/vision-screenshot.mjs:62
    await rm(tmp, { force: true });
  • 写入本地文件
    verify/vision-screenshot.mjs:94
    await mkdir(WORK, { recursive: true });
  • 删除本地文件递归
    verify/vision-screenshot.mjs:173
    await rm(WORK, { recursive: true, force: true });
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

依赖的 DSH / Cordis 模块
@deepseek-ai/dsh-settings@deepseek-ai/schemastery
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 截图直传视觉模型
  • 图像屏幕坐标映射
  • 操控鼠标键盘

computer-user 的非官方分支:修复 DSH >= 0.1.2 上的静默加载失败,并把截图以真实图像返回给视觉模型,附带精确的图像→屏幕坐标映射。

v0.4.02026-09-15
· 改名为 computer-user-vision 包不再沿用上游的 npm 名字。它本来故意叫 computer-user,好让配置档把这个分支放到原版所在的位置,但共用一个名字会让所有按 npm 名查找的读取方都解析到上游: · 插件市场在这个分支的卡片上显示上游的 0.3.6 版本,以及「与 picturereader(image_scan/image_ocr)搭配」的描述,因为它按名字查找包。 · 按这个名字安装拿到的是上游代码,那个版本在当前 DSH 上加载不了。 独立的名字牺牲了即插即用,换来正确的身份。 · 随名字一起改的 没有留下改了一半的地方: · package.json 的 name,以及 cordis.patch.yml 的行 id 和加载器 specifier。 · 设置命名空间(computer-user → computer-user-vision)。不改的话,两个插件并排安装会注册同一个命名空间,其中一个加载失败。 · 控制路由(/computer-user/control → /computer-user-vision/control)和审批存储($DSH_HOME/computer-user-vision-approvals.json),同样是怕冲突。 · doctor 脚本(tools/computer-user-vision-doctor.mjs),以及 tools/install.mjs 和 verify/_profile.mjs 里的包路径。 · 升级 依赖键变了,所以先删再加: dsh plugin --profile web remove computer-user dsh plugin --profile web add computer-user-vision 设置和审批不会带过来。已发布的版本里这两个文件都不存在,没什么可迁移的。 · 资源 computer-user-vision.tgz 是标准的、不带版本号的资源。computer-user.tgz 内容相同,保留它是为了让改名之前写下的链接继续有效。 其余都没变:视觉适配、元素引用、控制指示器和停止锁存都和 0.3.32 里一样。
v0.3.322026-09-14
插件代码没改。verify/general-workflows.mjs 每次运行都会启动 calc.exe,而计算器已经在运行时,再启动 calc.exe 只会多开一个窗口,不会复用已有应用。跑完一轮会话后实测:只剩一个计算器进程,却有 38 个标题为「计算器」的顶层窗口。测试把自己要测的机器弄得一团乱,实在不厚道,也让下一个运行的人看到 computer_list_windows 输出嘈杂——插件自己的窗口列表变成一堵几乎一模一样的条目墙。现在它会复用已经开着的计算器,结束时只关掉自己启动的那个——只关这一个,因为关闭应用会连带关掉它的所有窗口,而用户原本开着的窗口不该由我们关。已验证:连续两次运行后留下 0 个窗口、0 个进程,两次都 18/18 全绿。
v0.3.312026-09-14
这两处问题都是把插件放进重启后的实时会话里跑出来的,而不是靠验证器跑出来的——重启而不是相信一套全绿的测试,意义就在这里。 快照 id 从来没给模型看过。computer_elements 和 computer_screenshot 自己渲染文本,不走通用的 key: value 渲染器,而 snapshot 字段只存在于 STRUCTURED 值里,模型根本看不到。看不见的 id 就永远没法固定,所以 snapshot: 参数实际上完全没法用。两个渲染器现在都会打印: snapshot: s2 (pass snapshot:"s2" to computer_click / computer_type to pin these refs to this enumeration) verify/ref-snapshots.mjs 现在断言渲染出来的文本,而不是断言对象——第一版测试恰恰错查了这一层。 用打包应用自己的 pid 激活它行不通。UWP 应用的 Windows.UI.Core.CoreWindow 是它进程拥有的最大窗口,所以按 pid 查找恰好选中 Windows 拒绝置于前台的那个窗口:结果是 activated: false,正确但没用。 先做了测量,结果否掉了那个显而易见的修法——GetAncestor(coreWindow, GA_ROOT) 返回的就是 CoreWindow 本身,说明它已经是根窗口,往上爬到根什么也改变不了。承载它的框架属于 ApplicationFrameHost,WindowHostingPid 本来就知道怎么找到它——但只在进程没有可用窗口时才去查,所以常见情况根本走不到。现在激活不生效时它会作为兜底。 替换会报告出来,而不是悄悄进行(resolved_from 加一条注明两个句柄的说明),因为只报 requested 会让调用方以为自己给的句柄被提到了前台。Root() 保留下来解决它确实能解决的问题:调用方指定的是真正的子窗口,而 SetForegroundWindow 会直接忽略这种窗口。 computer_activate_window 声称返回 {requested, foreground, activated},却只在失败时设置 activated,于是字段缺失兼作成功。现在它会报 activated: true。 verify/general-workflows.mjs 增加到 18 项检查(A6 reach-a-real-window、A7 report-the-substitution)。
数据来自仓库的 GitHub Release,可能与插件实际版本不一致。

README

由 DeepSeek 最新模型翻译生成
computer-user-vision(computer-user-vision 分支) 这是非官方分支。 原始插件由 jing-hy 开发(MIT)。 本分支修复了两件事: 1. 上游 0.3.6 在 DSH ≥ 0.1.2 上根本无法加载(具名导入 settingsNamespace 已不存在,整个模块加载即失败,且没有任何报错:工具、设置卡、/computer 命令全部静默消失)。 2. 截图不再只回传文件路径:模型声明图像输入能力时,截图作为真正的图片块直接返回,并附带权威的「图片像素 → 屏幕像素」换算倍率 screen_per_pixel,无需 picturereader。 英文说明(含安装、tools/ 自愈脚本、verify/ 回归套件、隐私边界)见 README.md,技术细节见 docs/adaptation-notes.md。 computer-user-vision 给 DeepSeek Harness(DSH,含 EAC 桌面客户端)的 Codex 式电脑操作插件:读屏幕并操作鼠标键盘 —— 截图 → 看图 → click/type/keypress/scroll/drag → 验证。仅支持 Windows。 - computer_screenshot 把整个虚拟屏(多显示器、DPI 感知)截成 PNG。
展开完整文档(README 剩余 1 节)
computer-user-vision(computer-user-vision 分支)

这是非官方分支。 原始插件由 jing-hy 开发(MIT)。
本分支修复了两件事:

1. 上游 0.3.6 在 DSH ≥ 0.1.2 上根本无法加载(具名导入 settingsNamespace 已不存在,整个模块加载即失败,且没有任何报错:工具、设置卡、/computer 命令全部静默消失)。
2. 截图不再只回传文件路径:模型声明图像输入能力时,截图作为真正的图片块直接返回,并附带权威的「图片像素 → 屏幕像素」换算倍率 screen_per_pixel,无需 picturereader。

英文说明(含安装、tools/ 自愈脚本、verify/ 回归套件、隐私边界)见 README.md,技术细节见 docs/adaptation-notes.md。

computer-user-vision

给 DeepSeek Harness(DSH,含 EAC 桌面客户端)的 Codex 式电脑操作插件:读屏幕并操作鼠标键盘 —— 截图 → 看图 → click/type/keypress/scroll/drag → 验证。仅支持 Windows。

- computer_screenshot 把整个虚拟屏(多显示器、DPI 感知)截成 PNG。模型具备视觉能力时(如 DeepSeek-V41-Flash / deepseek-flash)截图会作为图片直接附加在工具结果里,模型直接看图即可;只有纯文本模型才退回「返回路径 + 外部图像工具」的方式。
- 另外 8 个 computer_ 工具,通过内置 PowerShell + Win32 SendInput 操作鼠标键盘(零原生模块、无需编译,可在 DSH/EAC 宿主进程内运行)。
- 设置卡(「电脑操作」)顶部是模式下拉框 —— 禁用 / 只读 / 手动批准(/computer)/ 自动,其余收进默认折叠的 高级设置。
- 截图与输入全程本地:截图(PowerShell)、操作(Win32 SendInput)都不出本机。
视觉模式下图片会随对话请求发给模型服务(使用视觉能力的必然代价);纯文本模型走 picturereader 本地 OCR 时才真正全程不出本机。操作流程见 skills/computer-use.md(先定位目标窗口,确认后一击即中并截图验证)。
- 已验证兼容 DeepSeek Harness EAC 桌面端(与 Web 同一 DSH 宿主内核)。

English: README.md。

看屏的两种模式

1)视觉模式(推荐,默认) —— 当前路由声明了图像输入能力时自动启用:

computer_screenshot → 截图作为图片直接返回 # 看(无需任何外部工具) computer_click / type / ... # 做 computer_screenshot # 验证

截图随工具结果一起附加,模型直接观察画面。插件会把截图自动压到 vision_max_pixels (默认 640000,与 DeepSeek 视觉投影预算一致)以内,并按实际图片尺寸算出 screen_per_pixel 倍率,保证「图片像素 → 屏幕物理像素」换算精确:

screen_x = virtual_offset[0] + image_x screen_per_pixel[0]
screen_y = virtual_offset[1] + image_y * screen_per_pixel[1]

要读小字或定位小按钮时用 region 只截目标窗口——同样预算下,截得越小越清晰。

2)路径模式(降级) —— 模型不支持图像输入时自动退回:

computer_screenshot → path
picturereader image_scan / image_ocr # 看(本地 OCR) computer_click / type / ... # 做 computer_screenshot → image_compare # 验证

这条路线不需要多模态模型,也不需要外部视觉 API:picturereader 把 PNG 转成纯文本模型能读的结构化描述(image_scan 布局/颜色/regions、image_ocr 真实文字、image_sample 纹理),全程只有文本 token、零外部请求。

模式由插件读取当前路由的 inputModalities 自动判断,也可用设置项 vision_feedback 强制关闭视觉直返。详见 skills/computer-use.md。

工具

| 工具 | 作用 |
| computer_screenshot | 截取整虚拟屏(可选 region/scale)。视觉模式下直接返回图片并附 screen_per_pixel 换算倍率;否则只返回 {path,…} |
| computer_click | 在 [x,y] 点击(click / right_click / double_click) |
| computer_type | 输入任意 UTF-16 文本(含中文),走 SendInput Unicode |
| computer_keypress | 组合键,如 ["ctrl","c"]、["alt","tab"];字母/数字走虚拟键以触发快捷键 |
| computer_scroll | 在 [x,y] 滚轮:up / down / left / right,clicks 格 |
| computer_drag | 按下 → 分步移动 → 释放,可选 hold_keys |
| computer_move_mouse | 移动光标但不点击 |
| computer_wait | 等待 ms(让 UI 稳定) |
| computer_get_cursor_position | 读取当前光标位置 [x,y] |

坐标为「相对虚拟屏原点(所有显示器合并区域左上角)」的像素;computer_screenshot 返回的 virtual_offset 即该原点。执行器已把进程提升到 PerMonitorV2 DPI 感知,高分屏缩放下坐标仍与物理像素一致。

安装

npm install computer-user-vision

或在 DSH profile 里:

dsh plugin --profile web add computer-user-vision

然后重启 DSH(或到 EAC「设置 → 插件 → 管理」启用)。工具对所有会话生效;设置卡在「设置 → 电脑操作」。

闭环一览

视觉模式(模型支持图像输入,默认):

computer_screenshot → image # 看 computer_click / type / ... # 做 computer_screenshot # 验证

路径模式(纯文本模型,配合 picturereader):

computer_screenshot → path
picturereader image_scan / image_ocr # 看 computer_click / type / ... # 做 computer_screenshot → image_compare # 验证

设置卡

设置卡(「电脑操作」)采用 DSH settings-panel 设计语言:卡片分组 + 胶囊按钮 + 32px 输入框 + chevron 下拉 + 折叠箭头;scope.load() 兼容无 load 宿主(EAC 桌面壳)。

- 模式下拉框(卡片顶部):
- disabled 禁用 —— 所有 computer_ 工具一律拒绝。
- readonly 只读 —— 仅截图 / 读光标 / 等待可用。
- manual 手动批准 —— 有副作用工具需先在本会话输入 /computer 批准(一次批准,后续轮次持续有效)。
- auto 自动 —— LLM 自由调用所有工具。
- 「AI 可自行修改运行模式」开关(下拉框下方,不在高级设置里):默认关闭;开启后 AI 可用 computer_set_mode 切换模式,写入同一设置命名空间,设置卡下拉框双向同步。
- 高级设置(默认折叠):截图输出目录、默认缩放、视觉直返(vision_feedback,默认开)、视觉截图像素上限(vision_max_pixels,默认 640000)、逐字输入间隔、滚动刻度、代码输出打回(output guard,默认开)、调试日志。

代码输出打回:host 侧对 LLM 输出流的过滤器——若模型把伪工具调用/伪 XML 当对话文本输出(比如把 computer_click({…})、 直接打成了字而不是真正调用),该段会被剔除并替换为一句一次性提示;同一内容第二次原样输出时放行不拦截。需要故意在回复里展示代码片段时可到高级设置关掉。

安全

- 先定位目标窗口(DPI 感知 GetWindowRect,见 skills/computer-use.md)——桌面图标/壁纸会干扰判断与点击;只在目标窗口内工作。
- 动手前务必 computer_screenshot 并真正看图(视觉模式)或交给图像工具分析(路径模式),不要盲点盲输。
- 确认坐标后一击即中,点完截图验证,不要盲目连点(很多 UI 是点击开关)。
- 手动批准模式配合 /computer 命令,让人在环。

验证与已知限制

- node --test 单测 39/39 通过(工具注册、门禁、参数校验、output guard)。
- 实机安全窗口冒烟(一次性窗口 + cmd.exe,绝不碰用户应用):截图 PNG 正确;光标读/移往返精确;hello 中文 123! 逐字回读一致;keypress Home/End 导航+插入验证(HEADzzzTAIL);双击选词、单击取消、拖拽选区均通过控件状态断言。
- headless 集成:dsh --profile headless 真实会话中,模型成功调用 computer_screenshot 与 computer_get_cursor_position。
- headless 真实场景:模型在 dsh --profile headless 中自主完成 5 步任务(screenshot → image_scan → type "hello" → screenshot → image_ocr),协调 picturereader 与 computer-user-vision 工具,OCR 确认输入文字出现在屏幕上。
- 滚轮端到端验证通过:滚动条位置变化 + MouseWheel 事件触发均正常。注意:鼠标若落在搜狗输入法等置顶悬浮窗上,滚轮事件会被悬浮窗吸收——把光标移到空白处再滚(与任何基于光标的输入同理)。
- EAC 兼容:与 picturereader 在同一宿主内可并存加载(视觉模式下不再依赖它);对全部内置插件静态扫描,computer_ 工具名 / computer-user-vision 命名空间零冲突。
- 视觉直返实测:deepseek-flash(DeepSeek-V41-Flash)路由下 computer_screenshot 返回图片块 + screen_per_pixel,模型可直接读屏并换算坐标;纯文本路由自动退回路径模式。

开发

src/act.ps1 唯一执行器:截图 / 元素枚举(UIA)/ 鼠标键盘 / 窗口与前台 / 激活 src/ps.js PowerShell 运行器(base64 JSON、超时、取消) src/tools.js 13 个 computer_* 工具定义 + 模式门禁 + 元素引用解析 + 视觉直返 src/overlay.ps1 控制指示器(渐变光框 / 光标光晕 / 顶部横幅 + 停止按钮 + 全局热键) src/overlay.js 指示器生命周期(心跳 / 截图暂停 / 停止标记) src/approvals.js /computer 授权落盘(跨宿主重启保持) src/output-guard.js 把写成对话文本的伪工具调用打回 src/config.js 设置命名空间 schema src/index.js 插件入口(注册工具 + 设置热载 + 控制路由 + 用户消息重新授权) client.js Web 设置卡(ModuleLoader bundle,中英) skills/ 面向模型的技能文档(computer-use.md) tools/ 健康检查 doctor 与 profile 安装器 install.mjs verify/ 可移植验证脚本(纯 node,不需要浏览器) docs/ 适配说明

许可

MIT
预览分享卡片长什么样 ↓xie129716/computer-user-vision
分享 · DeepSeek Harness Hub
xie129716/computer-user-vision

截图直传视觉模型,精准换算坐标并操控鼠标键盘

这是你的仓库?认领条目

回到顶部