fix(web-access): 门槛降回 10.0.98——#77 让新装客户端整个失去浏览器能力 (#78)

真机测试发现的回归,由 #77 引入。

## 现象

全新安装的 10.0.99 客户端上,`BrowserManage` / `BrowserAct` / `BrowserSnapshot`
**完全不存在**——Agent 用 `ToolSearch` 也找不到。它们是 hidden 工具,靠 web-access
技能解锁,而该技能压根没被装上。

## 因果

`sync/builtin-skill.ts:171`:本地不存在 + 客户端版本低于 `required_client_version` →
记 `skippedIncompatible` 直接 return,**不新装**。

#77 把门槛提到 10.0.100,而 **10.0.100 尚未发布**——于是所有新装的 10.0.99 及以下客户端拿不到整个
web-access,连带失去全部内置浏览器能力。

已装 2.1.1 的老用户不受影响(`:207` 那条分支保留本地兼容旧版,不更新成用不了的新版)。

## 判断失误

#77 的理由是「不提门槛老客户端会拿到教它们用不存在能力的说明」。顾虑本身成立,但两害量级差了一个数量级:

| | 后果 |
|---|---|
| 门槛低 | 文档里几条说明超前,Agent 试一次失败、换个路子——**能力还在** |
| 门槛高 | **整个技能不存在**,Agent 连试都没得试 |

## 修法

门槛降回 10.0.98,超前的四条能力改用行内「需
10.0.100+」标注,并写明老版本上的替代做法。老客户端既拿得到技能,也不会被文档误导。`version` 2.2.0 → 2.2.1。

---

Regression from #77 found during real-machine testing: raising
`required_client_version` to an unreleased version made the whole skill
fail to install on fresh clients, taking all built-in browser tools with
it.

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
2026-08-07 22:15:07 +08:00
committed by yi-ge
parent f104d18165
commit 2e15720442
2 changed files with 8 additions and 5 deletions

View File

@@ -16,7 +16,7 @@ description: >-
新闻、网址、URL、找一下、搜一下、查一下、小红书、B站、微博、飞书、Twitter、 新闻、网址、URL、找一下、搜一下、查一下、小红书、B站、微博、飞书、Twitter、
推特、X、知乎、公众号、已登录、登录状态。 推特、X、知乎、公众号、已登录、登录状态。
license: Complete terms in LICENSE.txt license: Complete terms in LICENSE.txt
version: 2.2.0 version: 2.2.1
type: procedural type: procedural
risk_level: low risk_level: low
status: enabled status: enabled
@@ -79,7 +79,7 @@ market:
fill-opacity="0.12"/><path d="M20.5 20.5l2 2" stroke="#34C759" fill-opacity="0.12"/><path d="M20.5 20.5l2 2" stroke="#34C759"
stroke-width="1.8" stroke-linecap="round"/></svg> stroke-width="1.8" stroke-linecap="round"/></svg>
category: research category: research
required_client_version: 10.0.100 required_client_version: 10.0.98
maintainer: maintainer:
name: DesireCore Official name: DesireCore Official
verified: true verified: true

View File

@@ -178,6 +178,9 @@ BrowserImport:
## 截图:像素直接给你,通常不需要再 Read ## 截图:像素直接给你,通常不需要再 Read
> **需要客户端 10.0.100+。** 更老的版本上截图只回元数据;
> 若需要画面信息请改用 `semantic` / `accessibility` 快照,或回落 Jina / Playwright。
`BrowserSnapshot` `mode: visual``BrowserAct` `page.screenshot` 会把截图像素作为 `BrowserSnapshot` `mode: visual``BrowserAct` `page.screenshot` 会把截图像素作为
image 块**直接放进工具结果**——视觉模型当场就能看,不必再调 `Read` image 块**直接放进工具结果**——视觉模型当场就能看,不必再调 `Read`
@@ -198,11 +201,11 @@ image 块**直接放进工具结果**——视觉模型当场就能看,不必
| **截图前必须 `tab.activate`** | 标签页默认停在 `(-10000,-10000,1x1)`,没有合成表面。直接截图会卡满 30 s deadline**并把标签页宿主打掉**,之后全部报 `BROWSER_TAB_HOST_NOT_FOUND` | | **截图前必须 `tab.activate`** | 标签页默认停在 `(-10000,-10000,1x1)`,没有合成表面。直接截图会卡满 30 s deadline**并把标签页宿主打掉**,之后全部报 `BROWSER_TAB_HOST_NOT_FOUND` |
| **同时只有一个可见标签页** | `tab.activate` 绑定主窗口、全局互斥。多 Space 可以并发导航/快照/输入,但截图必须逐个 activate 串行 | | **同时只有一个可见标签页** | `tab.activate` 绑定主窗口、全局互斥。多 Space 可以并发导航/快照/输入,但截图必须逐个 activate 串行 |
| **`page.evaluate` 基本不可用** | 每次调用需人工审批;返回的字符串/对象被替换为 `[REDACTED:browser-runtime-value]`(只有 number/boolean/null 穿透);反调试站点会把它挂起几十秒。读页面用 `BrowserSnapshot` | | **`page.evaluate` 基本不可用** | 每次调用需人工审批;返回的字符串/对象被替换为 `[REDACTED:browser-runtime-value]`(只有 number/boolean/null 穿透);反调试站点会把它挂起几十秒。读页面用 `BrowserSnapshot` |
| **`cdp.raw` 需人工审批** | `browser.raw_cdp.*` 属于永远人工闸门的能力,无人值守流程用不了。**元素级裁剪不必走它**——`BrowserSnapshot``options.clip={x,y,width,height,scale}` 直接支持(`scale` 最大 4先用 `semantic` 快照拿到元素坐标,再截那一块并放大。验证码、小按钮在整页截图里只有几十像素,看不清时用它 | | **`cdp.raw` 需人工审批** | `browser.raw_cdp.*` 属于永远人工闸门的能力,无人值守流程用不了。**元素级裁剪不必走它**(需 10.0.100+——`BrowserSnapshot``options.clip={x,y,width,height,scale}` 直接支持(`scale` 最大 4先用 `semantic` 快照拿到元素坐标,再截那一块并放大。验证码、小按钮在整页截图里只有几十像素,看不清时用它 |
| **没有批量取文通道** | `semantic` 不含正文,`accessibility` 在真实页面上超限,`page.evaluate` 被审批+脱敏。要正文请回落 Jina / Playwright | | **没有批量取文通道** | `semantic` 不含正文,`accessibility` 在真实页面上超限,`page.evaluate` 被审批+脱敏。要正文请回落 Jina / Playwright |
| **单条命令 30 s deadline** | 超时即判 `browser.host.gone`,会话作废 | | **单条命令 30 s deadline** | 超时即判 `browser.host.gone`,会话作废 |
| **用户真实操作会抢控制权** | 在可见标签页上**点击、按键、滚轮、触摸**会触发 `trusted-user-input` 并递增 control epoch打断 Agent 的租约。**鼠标只是划过不会**(默认策略 `intentional-input`),所以用户看着页面移动光标是安全的 | | **用户真实操作会抢控制权** | 在可见标签页上**点击、按键、滚轮、触摸**会触发 `trusted-user-input` 并递增 control epoch打断 Agent 的租约。**鼠标只是划过不会**(默认策略 `intentional-input`,需 10.0.100+;更老版本上划过也会打断),所以用户看着页面移动光标是安全的 |
| **artifact 不要走 `/save`** | 该接口会弹系统「另存为」对话框等人点。**用回执里的 `result.artifact.absolutePath`**(工具会把它登记进本次会话的可读白名单),不要自己拼路径——`${DESIRECORE_ROOT}` 这类变量在路径展开里不认(只认 `~` / `$HOME` / `$USERPROFILE`),拼出来是相对路径、`Read` 会报「文件不存在」。默认保留 24 小时 | | **artifact 不要走 `/save`** | 该接口会弹系统「另存为」对话框等人点。**用回执里的 `result.artifact.absolutePath`**需 10.0.100+;更老版本没有这个字段,只能放弃直接读,改用页面内提取)(工具会把它登记进本次会话的可读白名单),不要自己拼路径——`${DESIRECORE_ROOT}` 这类变量在路径展开里不认(只认 `~` / `$HOME` / `$USERPROFILE`),拼出来是相对路径、`Read` 会报「文件不存在」。默认保留 24 小时 |
## SitePatternRead / SitePatternWrite ## SitePatternRead / SitePatternWrite