fix(web-access): 将外部浏览器启动建议标记为仅展示 (#99)

## 中文

- 将 `debug_port_closed` 的模型可见字段从 `launchCommand` 收紧为
`manualLaunchCommand`
- 明确 `requiredAction=wait_for_user_to_launch_browser` 与
`commandPolicy=display_only_never_execute`
- 中英 Skill 与 CDP 参考文档同步要求结束回合,禁止交给 Bash、PowerShell、终端或脚本执行

## English

- Rename the model-facing closed-port suggestion to
`manualLaunchCommand`
- Define `requiredAction=wait_for_user_to_launch_browser` and
`commandPolicy=display_only_never_execute`
- Keep the English/Chinese skill and CDP reference aligned: end the turn
and never pass the suggestion to an execution tool

## Validation

- i18n validator: pass
- translation freshness check: pass
- Windows real-device evidence: the previous contract correctly detected
`debug_port_closed` but attempted a Bash launch; approval was denied
before execution
This commit is contained in:
2026-08-29 23:00:58 -04:00
committed by GitHub
parent 54716ea43a
commit ebdac6c6b1
3 changed files with 39 additions and 10 deletions

View File

@@ -15,7 +15,7 @@ description: >-
新闻、网址、URL、找一下、搜一下、查一下、小红书、B站、微博、飞书、Twitter、 新闻、网址、URL、找一下、搜一下、查一下、小红书、B站、微博、飞书、Twitter、
推特、X、知乎、公众号、已登录、登录状态。 推特、X、知乎、公众号、已登录、登录状态。
license: Complete terms in LICENSE.txt license: Complete terms in LICENSE.txt
version: 3.4.3 version: 3.4.4
type: procedural type: procedural
risk_level: low risk_level: low
status: enabled status: enabled
@@ -55,14 +55,14 @@ metadata:
short_desc: 联网搜索、网页抓取、内置受管浏览器登录态访问与取文、研究调研工作流 short_desc: 联网搜索、网页抓取、内置受管浏览器登录态访问与取文、研究调研工作流
description: 联网访问工具包——搜索公开页面、Jina 优化抓取、内置受管浏览器完成登录态访问与取文,以及用户点名时接管他自己的 Chrome/Edge/Chromium。 description: 联网访问工具包——搜索公开页面、Jina 优化抓取、内置受管浏览器完成登录态访问与取文,以及用户点名时接管他自己的 Chrome/Edge/Chromium。
body: ./SKILL.zh-CN.md body: ./SKILL.zh-CN.md
source_hash: sha256:78082a20359f730f source_hash: sha256:c8c7be6cf577d445
translated_by: human translated_by: human
en-US: en-US:
name: Web Access name: Web Access
short_desc: Web search, page fetching, logged-in access via the governed built-in browser, research workflows short_desc: Web search, page fetching, logged-in access via the governed built-in browser, research workflows
description: A web-access toolkit — search public pages, fetch heavy pages via Jina Reader, reach and read logged-in sites through the governed built-in browser, and drive the user's named Chrome/Edge/Chromium over CDP on request. description: A web-access toolkit — search public pages, fetch heavy pages via Jina Reader, reach and read logged-in sites through the governed built-in browser, and drive the user's named Chrome/Edge/Chromium over CDP on request.
body: ./SKILL.md body: ./SKILL.md
source_hash: sha256:78082a20359f730f source_hash: sha256:c8c7be6cf577d445
translated_by: human translated_by: human
market: market:
icon: >- icon: >-
@@ -114,7 +114,7 @@ When you call `Skill('web-access')`, the following tools are injected into the c
| Tool | Purpose | | Tool | Purpose |
|------|---------| |------|---------|
| BrowserManage | Create/destroy isolated BrowserSpace, start sessions, manage tabs | | BrowserManage | Create/destroy isolated BrowserSpace, start sessions, manage tabs |
| BrowserExternalProbe | Read-only check for installed Chrome/Edge/Chromium and loopback CDP readiness; never launches or reads a profile | | BrowserExternalProbe | Read-only check for installed Chrome/Edge/Chromium and loopback CDP readiness; never launches or reads a profile; any returned manual command is display-only |
| BrowserExternalOpen | After `BrowserExternalProbe` returns `ready` in the same runtime session, visibly open one HTTP(S) URL in the exact external browser; no shell, Python, or Playwright | | BrowserExternalOpen | After `BrowserExternalProbe` returns `ready` in the same runtime session, visibly open one HTTP(S) URL in the exact external browser; no shell, Python, or Playwright |
| BrowserSnapshot | `semantic` / `text` / `accessibility` / `visual` snapshots — the primary way to read a page | | BrowserSnapshot | `semantic` / `text` / `accessibility` / `visual` snapshots — the primary way to read a page |
| BrowserAct | One governed action per call: navigate, input, extract text, wait, element ops, screenshot, … | | BrowserAct | One governed action per call: navigate, input, extract text, wait, element ops, screenshot, … |
@@ -172,13 +172,26 @@ Handle the structured result exactly:
|---|---| |---|---|
| `ready` | For a simple open/navigation, call `BrowserExternalOpen` with the returned exact browser id and port. For advanced click/read/extract interaction, continue with isolated Playwright `connect_over_cdp`. Name the detected external browser honestly. For `any`, the already-ready endpoint is the prepared choice even if other products are installed | | `ready` | For a simple open/navigation, call `BrowserExternalOpen` with the returned exact browser id and port. For advanced click/read/extract interaction, continue with isolated Playwright `connect_over_cdp`. Name the detected external browser honestly. For `any`, the already-ready endpoint is the prepared choice even if other products are installed |
| `browser_not_installed` | Say the requested browser was not detected. If `alternatives` is non-empty, ask whether the user wants one of them; **never switch automatically** | | `browser_not_installed` | Say the requested browser was not detected. If `alternatives` is non-empty, ask whether the user wants one of them; **never switch automatically** |
| `debug_port_closed` | Show the returned `launchCommand`, ask the user to launch it and log in manually, then wait and probe again | | `debug_port_closed` | Show the returned `launchCommand`, end the turn, and wait for the user to launch it and log in manually; never execute it with a tool |
| `browser_choice_required` | No endpoint is ready and multiple external browsers are installed. List id/name only and ask which one the user wants; probe that exact choice next | | `browser_choice_required` | No endpoint is ready and multiple external browsers are installed. List id/name only and ask which one the user wants; probe that exact choice next |
| `browser_mismatch` | Say which browser is actually on the port and which one was requested; ask the user to correct the port or explicitly approve the other browser | | `browser_mismatch` | Say which browser is actually on the port and which one was requested; ask the user to correct the port or explicitly approve the other browser |
| `invalid_cdp_endpoint` | Explain that something is listening on the port but it is not a valid Chrome DevTools endpoint; do not attach | | `invalid_cdp_endpoint` | Explain that something is listening on the port but it is not a valid Chrome DevTools endpoint; do not attach |
| `host_unavailable` | Explain that this Agent Service cannot inspect the user's desktop host; do not assume a browser is installed or silently use the built-in browser | | `host_unavailable` | Explain that this Agent Service cannot inspect the user's desktop host; do not assume a browser is installed or silently use the built-in browser |
`launchCommand` uses an isolated DesireCore profile. After launch: Compatibility rule for released 10.0.128 clients: they may include `launchCommand` in statuses other
than `debug_port_closed`. **Never execute `launchCommand` from any status.** Only show it and end the
turn for `debug_port_closed`; for every other status, ignore that field and follow the status row above.
`launchCommand` uses an isolated DesireCore profile. On clients that return the adjacent fields, they are normative:
`requiredAction: wait_for_user_to_launch_browser` means **end the current turn**, and
`commandPolicy: display_only_never_execute` means **never pass the command to Bash, PowerShell,
a terminal, a script, or any other execution tool**. This remains true when the user's earlier wording
said “continue”, “open it for me”, or otherwise sounded like permission to proceed. Only the user may
manually run this suggestion; a future dedicated browser-launch capability would require its own contract.
New clients deliver this display-only notice directly and terminate the turn before the model can call
another tool; do not add a second paraphrase or continue execution after the tool result.
After the user launches it:
1. The user logs in manually to the sites they need. 1. The user logs in manually to the sites they need.
2. That external browser window stays open. 2. That external browser window stays open.

View File

@@ -27,7 +27,7 @@ web-access 是一个**流程型技能Procedural Skill**,提供四层互
| 工具 | 用途 | | 工具 | 用途 |
|------|------| |------|------|
| BrowserManage | 建/销隔离 BrowserSpace、启动会话、管理标签页 | | BrowserManage | 建/销隔离 BrowserSpace、启动会话、管理标签页 |
| BrowserExternalProbe | 只读检查 Chrome/Edge/Chromium 安装与 loopback CDP 就绪状态;绝不启动浏览器或读取 Profile | | BrowserExternalProbe | 只读检查 Chrome/Edge/Chromium 安装与 loopback CDP 就绪状态;绝不启动浏览器或读取 Profile;返回的手工命令只能展示 |
| BrowserExternalOpen | 同一 session 的 probe 返回 `ready` 后,在精确外部浏览器中可见打开一个 HTTP(S) URL不使用 shell、Python 或 Playwright | | BrowserExternalOpen | 同一 session 的 probe 返回 `ready` 后,在精确外部浏览器中可见打开一个 HTTP(S) URL不使用 shell、Python 或 Playwright |
| BrowserSnapshot | `semantic` / `text` / `accessibility` / `visual` 四种快照——读页面的主通道 | | BrowserSnapshot | `semantic` / `text` / `accessibility` / `visual` 四种快照——读页面的主通道 |
| BrowserAct | 一次调用一个受管动作:导航、输入、取文、等待、元素操作、截图…… | | BrowserAct | 一次调用一个受管动作:导航、输入、取文、等待、元素操作、截图…… |
@@ -85,13 +85,24 @@ If any fetch fails, explicitly tell the user which URL failed and which fallback
|---|---| |---|---|
| `ready` | 简单打开/导航调用 `BrowserExternalOpen`,参数使用返回的精确浏览器 id 与端口;点击、读取、提取等高级交互才继续隔离 Playwright `connect_over_cdp`。如实说出检测到的外部浏览器;`any` 已有 ready 端口时,即使还安装了其他产品,也以该端口作为用户已准备的选择 | | `ready` | 简单打开/导航调用 `BrowserExternalOpen`,参数使用返回的精确浏览器 id 与端口;点击、读取、提取等高级交互才继续隔离 Playwright `connect_over_cdp`。如实说出检测到的外部浏览器;`any` 已有 ready 端口时,即使还安装了其他产品,也以该端口作为用户已准备的选择 |
| `browser_not_installed` | 明确说未检测到用户点名的浏览器;若有 `alternatives`,询问是否改用其中之一,**绝不自动替换** | | `browser_not_installed` | 明确说未检测到用户点名的浏览器;若有 `alternatives`,询问是否改用其中之一,**绝不自动替换** |
| `debug_port_closed` | 展示返回的 `launchCommand`请用户启动并手工登录,然后等待并重新 probe | | `debug_port_closed` | 展示返回的 `launchCommand`结束当前回合,等待用户手工启动并登录;绝不能用工具执行它 |
| `browser_choice_required` | 没有 ready 端口且检测到多个外部浏览器;只列 id/name 并询问用户选哪个,再 probe 精确选择 | | `browser_choice_required` | 没有 ready 端口且检测到多个外部浏览器;只列 id/name 并询问用户选哪个,再 probe 精确选择 |
| `browser_mismatch` | 说明端口上实际是什么、用户点名的是什么;让用户修正端口或明确同意改用实际浏览器 | | `browser_mismatch` | 说明端口上实际是什么、用户点名的是什么;让用户修正端口或明确同意改用实际浏览器 |
| `invalid_cdp_endpoint` | 说明端口虽有服务但不是合法 Chrome DevTools 端点;不得连接 | | `invalid_cdp_endpoint` | 说明端口虽有服务但不是合法 Chrome DevTools 端点;不得连接 |
| `host_unavailable` | 说明当前 Agent Service 无法探测用户桌面宿主;不得猜已安装浏览器,也不得静默改用内置浏览器 | | `host_unavailable` | 说明当前 Agent Service 无法探测用户桌面宿主;不得猜已安装浏览器,也不得静默改用内置浏览器 |
`launchCommand` 使用 DesireCore 专属隔离 Profile。启动后 已发布的 10.0.128 客户端可能在 `debug_port_closed` 以外的状态中也带上 `launchCommand`
**任何状态的 `launchCommand` 都绝不能执行。**只有 `debug_port_closed` 可以展示后结束回合;
其他状态必须忽略该字段,严格按上表对应状态处理。
`launchCommand` 使用 DesireCore 专属隔离 Profile支持相邻字段的客户端必须把它们视为强制契约
`requiredAction: wait_for_user_to_launch_browser` 表示**必须结束当前回合**
`commandPolicy: display_only_never_execute` 表示**绝不能把命令传给 Bash、PowerShell、终端、脚本或任何其他执行工具**。
即使用户此前说过「继续」「帮我打开」或其他看似授权继续的表述,这条规则也不改变。当前只能由用户手工运行该建议;
未来若增加专用浏览器启动能力,必须另行定义并审批其契约。
新客户端会直接投递这条只展示提示并在模型能调用其他工具前终止本轮;工具返回后不要再追加改写或继续执行。
用户启动后:
1. 用户在该外部浏览器里手工登录所需站点。 1. 用户在该外部浏览器里手工登录所需站点。
2. 外部浏览器窗口保持打开。 2. 外部浏览器窗口保持打开。

View File

@@ -308,12 +308,17 @@ print(clean_md)
Do not guess that the browser is merely closed. Call `BrowserExternalProbe` again: Do not guess that the browser is merely closed. Call `BrowserExternalProbe` again:
- `debug_port_closed` → show its current `launchCommand` and wait for the user - `debug_port_closed` → show its current `launchCommand`, end the turn, and wait for the user;
`commandPolicy: display_only_never_execute` forbids passing it to Bash, PowerShell, a terminal,
a script, or any other execution tool even when the user previously said “continue”
- `browser_mismatch` → report the actual/requested products and ask the user to correct or approve the change - `browser_mismatch` → report the actual/requested products and ask the user to correct or approve the change
- `browser_not_installed` → report that exact installation fact; alternatives require explicit approval - `browser_not_installed` → report that exact installation fact; alternatives require explicit approval
- `invalid_cdp_endpoint` → tell the user the port is not a valid CDP endpoint - `invalid_cdp_endpoint` → tell the user the port is not a valid CDP endpoint
- still `ready` → report the Playwright attach failure separately; do not switch to the built-in browser - still `ready` → report the Playwright attach failure separately; do not switch to the built-in browser
Released 10.0.128 clients can include `launchCommand` on other statuses for compatibility. Never
execute it from any status. Only display it for `debug_port_closed`; ignore it for every other status.
### `browser.contexts[0]` is empty ### `browser.contexts[0]` is empty
The approved external Chromium browser is running but no windows are open. Ask the user to open at least one tab and navigate anywhere. The approved external Chromium browser is running but no windows are open. Ask the user to open at least one tab and navigate anywhere.