- click/click_ref: pre-click allowlist gate on resolvable anchor href
(same check as navigate; miss refuses before the click executes);
click/click_ref/click_at: post-click landing URL check.
click_at has no pre-click gate by design (coordinates name no
element); JS-driven navigation, evaluate, meta refresh and popups
are documented as unintercepable with the Tinyproxy 403 backstop.
- Tenant script upgrade is now safe: only proven-unmodified scripts
(manifest match, 2a569ac known-shipped SHA-256, missing, or
current) auto-merge; tenant-modified scripts are never overwritten,
are reported as skipped, and get one deduped audit record. The
manifest never learns a tenant hash (else the next upgrade would
mistake a modified file for untouched). Idempotent reruns.
- Activation candidate = deployed Tinyproxy programming set encoded
with leading-dot entries (plain entries would regress
docs.python.org); npmjs.org per the deployed filter, not npmjs.com.
Host activation itself is NOT performed this round: only the plan,
validation tests and rollback are delivered.
Tests: 28 new (click 13, upgrade 8, activation 7), all fake/no-network;
98 browser-related tests pass including prior suites.
(cherry picked from commit e4a93f5748ec815f163d0bc096ff4dc4b8c651f5)
125 lines
6.8 KiB
Markdown
125 lines
6.8 KiB
Markdown
---
|
||
name: browser-automation
|
||
description: >
|
||
Use when a task needs a real browser: pages that render with
|
||
JavaScript, clicking through pagination or forms, filling and
|
||
submitting input, or taking a screenshot of what a page
|
||
actually looks like. For a plain static page or a quick fact,
|
||
use web_fetch / web_search first; open the browser only when
|
||
static fetch cannot see the content.
|
||
---
|
||
|
||
## 工具
|
||
|
||
`browser_navigate`(打开 URL,返回最终 URL 与标题)、
|
||
`browser_snapshot`(当前页标题、URL、正文,超 8000 字截断并标记)、
|
||
`browser_click`(按 CSS 选择器或 `text=...` 点击)、
|
||
`browser_fill`(按选择器填表)、
|
||
`browser_evaluate`(在页内跑 JS 表达式,返回字符串,限 4000 字)、
|
||
`browser_screenshot`(把当前页存成工作区内的 PNG,返回绝对路径与字节数)、
|
||
`browser_click_at`(按视口坐标点击,坐标系为 1280x800、原点左上角,
|
||
是 live 视图里用户点击的落点)、
|
||
`browser_live_shot`(把当前画面存成固定文件 browser-live.png,
|
||
附带 browser-live.json 状态:URL、标题、时间戳,供 watcher 轮询)、
|
||
`browser_close`(关闭浏览器,可重复调用)。
|
||
|
||
浏览器是单页的:一次 navigate,之后 snapshot / click / fill /
|
||
screenshot 都针对同一页;要换页再 navigate。
|
||
|
||
## live 视图(第一期)
|
||
|
||
有人在看浏览器时,每次 navigate / click / fill / click_at 之后
|
||
都要调一次 `browser_live_shot`,让 browser-live.png 保持最新;
|
||
不要只在最后截图一次。用户在 live 图上点的坐标会以 x/y 到达
|
||
`browser_click_at`,点完必须再 snapshot 一次确认变化,再调
|
||
`browser_live_shot` 刷新画面。
|
||
|
||
## 远控接管(第二期)
|
||
|
||
用户可以在控制台接管浏览器:接管期间(holder=user)你的
|
||
所有 browser_* 工具都会直接报错“user holds browser control”,
|
||
不要重试、不要 close 浏览器,停下来等用户交还;交还后
|
||
(holder 回到 agent)下一条继续消息会让你续跑,续跑前先
|
||
snapshot 一次看清用户改动到哪了。
|
||
|
||
新工具:`browser_snapshot_refs`(带 ref 的元素清单,点
|
||
`browser_click_ref` 比 CSS 选择器稳,页面重渲染后先重新
|
||
snapshot_refs 再点);`browser_mouse_move` / `browser_key_press` /
|
||
`browser_type_text`(键盘与鼠标,远控输入与 agent 工具同源)。
|
||
|
||
## 规则
|
||
|
||
1. 先 navigate,再 snapshot 看实际渲染结果;click / fill 后
|
||
必须再 snapshot 一次确认变化,不要凭猜测汇报。
|
||
2. 截图产出后用 shell / PIL 重新打开验证(格式、尺寸、非 0
|
||
字节)再交给用户;失败时贴出工具报错,不要换一张别的图顶替。
|
||
3. 网络走 egress 代理:不在 Tinyproxy 白名单里的域名会报
|
||
代理 403,这时如实说明,不要绕过白名单。
|
||
4. file:// URL 可用于打开工作区内已写好的测试页(验证 JS
|
||
执行、表单行为),是比外网更可靠的自测手段。
|
||
5. 不要用浏览器做静态抓取能做的事;不要用 evaluate 绕过
|
||
click / fill 的正常路径去改页面状态,除非 snapshot 已证明
|
||
正常路径走不通。
|
||
|
||
## 多页与域名白名单(本期新增)
|
||
|
||
多页工具:`browser_new_page`(开新页并切到它,每次
|
||
new_page 都是全新 Playwright context,cookie 与存储天然
|
||
隔离,适合同时登录两个账号或对照两个页面)、
|
||
`browser_list_pages`(列出全部页:index、URL、标题、
|
||
哪一页是当前页;浏览器未启动时不启动,只返回空列表)、
|
||
`browser_switch_page`(按 index 切到指定页,之后
|
||
navigate / snapshot / click / fill / screenshot 都针对该页;
|
||
切到不存在的 index 会明确报错,不会崩掉 MCP,当前页不变;
|
||
切换后旧页的 snapshot_refs 全部失效,要重新 snapshot_refs)、
|
||
`browser_close_page`(关一页,缺省关当前页;关当前页后
|
||
自动切到上一页;关最后一页会明确报错,改用
|
||
`browser_close` 关整个浏览器)。
|
||
|
||
域名白名单:环境变量 `BROWSER_ALLOWED_HOSTS`(逗号列表,
|
||
如 `example.com,.python.org`)。未设置时行为完全不变,
|
||
只靠 egress 代理白名单;设置后 navigate 在启动浏览器之前
|
||
就检查:`file://` 一律放行,`http(s)` 的 host 必须命中列表
|
||
(前导点条目做后缀匹配:`.python.org` 同时放行
|
||
`python.org` 与 `docs.python.org`,不放行
|
||
`notpython.org`;注意:不带前导点的 `python.org` 只精确
|
||
匹配自身,不放行 `docs.python.org`),大小写与端口不影响
|
||
匹配,未命中直接报错且不启动 Chromium。`localhost` /
|
||
`127.0.0.1` 没有特殊待遇:本地开发服务器要自己把它列进
|
||
变量,否则会被挡。
|
||
|
||
页内点击白名单(本轮补齐,与 navigate 同款检查):
|
||
`browser_click` / `browser_click_ref` 点到带 href 的链接时,
|
||
先解析 href(相对链接按当前页 URL 展开)再检查:未命中
|
||
直接报错、点击根本不执行;点到没有 href 的目标(按钮、
|
||
JS 处理函数)时事前无从得知目的地,只能在点击后检查落点
|
||
URL、命中 blocked host 时报错(此时点击已发生,只是事后
|
||
发现,不是事前拦截)。`browser_click_at` 是坐标点击,坐标
|
||
本身对应不了任何元素,所以没有事前检查,只有事后落点检查。
|
||
真正拦不住的路径(不要假装已拦):页内 JS 自行跳转
|
||
(`location.href`、表单提交、SPA 路由、回车提交)、
|
||
`browser_evaluate` 里跑的任意 JS、meta refresh、弹窗新页。
|
||
这些路径没有“点击前已知目的地”可供检查,只能靠 egress
|
||
代理 403 兜底——白名单与代理白名单取同一域名集合时,被挡
|
||
域名在代理层就加载失败,不会真的打开目标页;但 evaluate
|
||
与 shell 同权,白名单从来不是它的沙箱边界,不要把它当
|
||
成防绕过手段。
|
||
|
||
老租户脚本升级(本轮改动):播种器只对已证明未改动的
|
||
租户脚本自动合并新版(播种 manifest 命中,或命中
|
||
2a569ac 已发布版本的哈希,或文件缺失/已是最新);租户
|
||
改过的脚本绝不覆盖,原样不动、记一条审计
|
||
(租户 codex-home 里的 `playwright_scripts_audit.jsonl`),
|
||
留待人工处理——下次任务播种时它仍会被跳过,不会悄悄
|
||
被新版盖掉。
|
||
|
||
清理:`browser_close` 会关掉全部页,并尽力删除工作区里的
|
||
`browser-live.png` 与 `browser-live.json`(删不掉也不报错),
|
||
所以 close 之后不要再拿旧 live 文件当“当前画面”汇报;
|
||
单个截图(`browser_screenshot` 的 `shot-*.png`)不受影响。
|
||
|
||
不在本轨范围:下载没有落盘清单(下载仍只落工作区文件,
|
||
无统一清单可查);没有持久 profile(每次 MCP 进程结束
|
||
cookie 即丢);没有登录保险库(账号密码仍不进浏览器工具)。
|
||
需要这些时不要假装已有,先如实说明缺口。
|