@anweat/dsh-browser 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +103 -0
- package/README.en.md +153 -0
- package/README.md +99 -568
- package/assets/skills/dsh-browser/SKILL.md +13 -11
- package/assets/skills/dsh-browser/references/files.md +36 -0
- package/assets/skills/dsh-browser/references/observe.md +2 -2
- package/assets/skills/dsh-browser/references/policy.md +32 -0
- package/cordis.patch.yml +10 -3
- package/lib/actions/errors.js +7 -2
- package/lib/actions/errors.js.map +1 -1
- package/lib/actions/index-view.d.ts +4 -1
- package/lib/actions/index-view.js +16 -3
- package/lib/actions/index-view.js.map +1 -1
- package/lib/actions/inspect.js +15 -0
- package/lib/actions/inspect.js.map +1 -1
- package/lib/actions/observe.js +1 -1
- package/lib/actions/observe.js.map +1 -1
- package/lib/actions/opencli.d.ts +1 -1
- package/lib/actions/opencli.js +4 -4
- package/lib/actions/opencli.js.map +1 -1
- package/lib/actions/policy.d.ts +15 -0
- package/lib/actions/policy.js +131 -0
- package/lib/actions/policy.js.map +1 -0
- package/lib/actions/registry.js +6 -5
- package/lib/actions/registry.js.map +1 -1
- package/lib/actions/runtime.js +2 -2
- package/lib/actions/runtime.js.map +1 -1
- package/lib/actions/target.js +35 -3
- package/lib/actions/target.js.map +1 -1
- package/lib/actions/types.d.ts +1 -1
- package/lib/actions/types.js.map +1 -1
- package/lib/approval-policy.d.ts +10 -1
- package/lib/approval-policy.js +42 -1
- package/lib/approval-policy.js.map +1 -1
- package/lib/auth-profiles.d.ts +4 -1
- package/lib/auth-profiles.js +3 -0
- package/lib/auth-profiles.js.map +1 -1
- package/lib/automation-assets-rpc.js +60 -4
- package/lib/automation-assets-rpc.js.map +1 -1
- package/lib/browser-service.d.ts +165 -4
- package/lib/browser-service.js +505 -55
- package/lib/browser-service.js.map +1 -1
- package/lib/client/SettingsCard.d.ts +10 -8
- package/lib/client/SettingsCard.js +12 -137
- package/lib/client/SettingsCard.js.map +1 -1
- package/lib/client/auth-profiles-form.d.ts +23 -0
- package/lib/client/auth-profiles-form.js +64 -0
- package/lib/client/auth-profiles-form.js.map +1 -0
- package/lib/client/card-frame.d.ts +22 -0
- package/lib/client/card-frame.js +61 -0
- package/lib/client/card-frame.js.map +1 -0
- package/lib/client/field-rows.d.ts +59 -0
- package/lib/client/field-rows.js +63 -0
- package/lib/client/field-rows.js.map +1 -0
- package/lib/client/field-rules.d.ts +17 -0
- package/lib/client/field-rules.js +68 -0
- package/lib/client/field-rules.js.map +1 -0
- package/lib/client/form.d.ts +108 -7
- package/lib/client/form.js +255 -11
- package/lib/client/form.js.map +1 -1
- package/lib/client/group-access.d.ts +14 -0
- package/lib/client/group-access.js +97 -0
- package/lib/client/group-access.js.map +1 -0
- package/lib/client/group-advanced.d.ts +11 -0
- package/lib/client/group-advanced.js +32 -0
- package/lib/client/group-advanced.js.map +1 -0
- package/lib/client/group-assets.d.ts +13 -0
- package/lib/client/group-assets.js +50 -0
- package/lib/client/group-assets.js.map +1 -0
- package/lib/client/group-browser.d.ts +9 -0
- package/lib/client/group-browser.js +27 -0
- package/lib/client/group-browser.js.map +1 -0
- package/lib/client/group-common.d.ts +10 -0
- package/lib/client/group-common.js +21 -0
- package/lib/client/group-common.js.map +1 -0
- package/lib/client/group-context.d.ts +20 -0
- package/lib/client/group-context.js +76 -0
- package/lib/client/group-context.js.map +1 -0
- package/lib/client/group-downloads.d.ts +10 -0
- package/lib/client/group-downloads.js +33 -0
- package/lib/client/group-downloads.js.map +1 -0
- package/lib/client/group-limits.d.ts +9 -0
- package/lib/client/group-limits.js +57 -0
- package/lib/client/group-limits.js.map +1 -0
- package/lib/client/group-prompts.d.ts +13 -0
- package/lib/client/group-prompts.js +136 -0
- package/lib/client/group-prompts.js.map +1 -0
- package/lib/client/index.d.ts +21 -1
- package/lib/client/index.js +10 -4
- package/lib/client/index.js.map +1 -1
- package/lib/client/locales-policy.d.ts +83 -0
- package/lib/client/locales-policy.js +46 -0
- package/lib/client/locales-policy.js.map +1 -0
- package/lib/client/locales-prompts.d.ts +57 -0
- package/lib/client/locales-prompts.js +41 -0
- package/lib/client/locales-prompts.js.map +1 -0
- package/lib/client/locales-ui.d.ts +223 -0
- package/lib/client/locales-ui.js +157 -0
- package/lib/client/locales-ui.js.map +1 -0
- package/lib/client/locales.d.ts +359 -67
- package/lib/client/locales.js +68 -22
- package/lib/client/locales.js.map +1 -1
- package/lib/client/policy-fields.d.ts +31 -0
- package/lib/client/policy-fields.js +66 -0
- package/lib/client/policy-fields.js.map +1 -0
- package/lib/client/policy-status-client.d.ts +91 -0
- package/lib/client/policy-status-client.js +64 -0
- package/lib/client/policy-status-client.js.map +1 -0
- package/lib/client/prompts-form.d.ts +33 -0
- package/lib/client/prompts-form.js +87 -0
- package/lib/client/prompts-form.js.map +1 -1
- package/lib/client/prompts-status-client.d.ts +21 -1
- package/lib/client/prompts-status-client.js +36 -4
- package/lib/client/prompts-status-client.js.map +1 -1
- package/lib/client/properties-form.d.ts +90 -0
- package/lib/client/properties-form.js +187 -0
- package/lib/client/properties-form.js.map +1 -0
- package/lib/client/property-docs.d.ts +18 -0
- package/lib/client/property-docs.js +78 -0
- package/lib/client/property-docs.js.map +1 -0
- package/lib/client/size-units.d.ts +12 -0
- package/lib/client/size-units.js +29 -0
- package/lib/client/size-units.js.map +1 -0
- package/lib/client/styles.d.ts +47 -31
- package/lib/client/styles.js +59 -20
- package/lib/client/styles.js.map +1 -1
- package/lib/client/ui-kit.d.ts +173 -0
- package/lib/client/ui-kit.js +112 -0
- package/lib/client/ui-kit.js.map +1 -0
- package/lib/client.js +5291 -834
- package/lib/client.js.map +1 -1
- package/lib/config-rules.d.ts +40 -0
- package/lib/config-rules.js +103 -0
- package/lib/config-rules.js.map +1 -0
- package/lib/config.d.ts +64 -2
- package/lib/config.js +106 -0
- package/lib/config.js.map +1 -1
- package/lib/context-options.d.ts +85 -0
- package/lib/context-options.js +206 -0
- package/lib/context-options.js.map +1 -0
- package/lib/deps.d.ts +42 -5
- package/lib/deps.js +219 -9
- package/lib/deps.js.map +1 -1
- package/lib/downloads.d.ts +79 -0
- package/lib/downloads.js +189 -0
- package/lib/downloads.js.map +1 -0
- package/lib/index.d.ts +3 -2
- package/lib/index.js +7 -3
- package/lib/index.js.map +1 -1
- package/lib/policy-keys.d.ts +39 -0
- package/lib/policy-keys.js +21 -0
- package/lib/policy-keys.js.map +1 -1
- package/lib/policy-overlay.d.ts +189 -0
- package/lib/policy-overlay.js +649 -0
- package/lib/policy-overlay.js.map +1 -0
- package/lib/prompts-yaml.d.ts +11 -0
- package/lib/prompts-yaml.js +121 -0
- package/lib/prompts-yaml.js.map +1 -0
- package/lib/prompts.d.ts +2 -0
- package/lib/prompts.js +7 -3
- package/lib/prompts.js.map +1 -1
- package/lib/system-browser.d.ts +61 -0
- package/lib/system-browser.js +109 -0
- package/lib/system-browser.js.map +1 -0
- package/lib/tools.js +9 -1
- package/lib/tools.js.map +1 -1
- package/lib/usage-policy.d.ts +3 -1
- package/lib/usage-policy.js +2 -0
- package/lib/usage-policy.js.map +1 -1
- package/package.json +47 -40
- package/scripts/check-docs-links.mjs +115 -0
- package/scripts/dump-prompts.mjs +13 -3
package/README.md
CHANGED
|
@@ -1,620 +1,151 @@
|
|
|
1
1
|
# dsh-browser
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[English](https://github.com/anweat/dsh-browser/blob/master/README.en.md) | 中文
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)(DSH)的浏览器运行时插件:让模型打开网页、读取内容、操作页面、截图、下载文件,也为 `dsh-web-search-pro` 提供 `browser` 服务。插件自带 Playwright / Patchright 驱动,**浏览器本身不随插件下载**:装了 Google Chrome 或 Microsoft Edge 就直接用。
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## 亮点
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
- **两个常驻工具**:`browser_index`(看目录)+ `browser_call`(执行动作),常驻上下文约 325 token;41 个动作分成 9 组,按需查看单个动作的 schema。
|
|
10
|
+
- **不用先下载浏览器**:自动检测系统 Chrome / Edge;都没有时才用 `runtime.install` 安装 Playwright Chromium。可选 Patchright 内核。
|
|
11
|
+
- **严格定位与结构化观察**:`role` / `name` / `label` / `text` / `testId` 语义定位,匹配多个元素时不执行并列出候选;`observe.read` 可直接给出可用于 `act.*` 的 controls / links / tables。
|
|
12
|
+
- **按 session 隔离、四档自动化自由度**:每个 session 独立的浏览器 context;`read-only` / `standard` / `autonomous` / `unrestricted` 决定能做什么、哪些要走 DSH 原生审批。
|
|
13
|
+
- **登录态、下载与限流**:按域名限定的 `authProfile`,下载落盘带 sha256,`usagePolicy` 限制并发与突发;模型可通过策略动作收紧或(经审批)放宽。
|
|
14
|
+
- **可复用自动化(实验性)**:recipe / UserScript 资产的积累、检索、测试与手动激活;OpenCLI 站点 adapter 可选。
|
|
10
15
|
|
|
11
|
-
|
|
16
|
+
安全边界与 2026-09 的审查记录见 [AUDIT.md](https://github.com/anweat/dsh-browser/blob/master/AUDIT.md)(基于 0.1.12,部分内容已过时):`allowedDomains` 只限制登录态装载,不是网络防火墙或 Agent 隔离边界。
|
|
17
|
+
|
|
18
|
+
## 兼容性
|
|
19
|
+
|
|
20
|
+
| 插件 | DSH | peer 范围 |
|
|
12
21
|
|---|---|---|
|
|
13
|
-
| `0.
|
|
14
|
-
| `0.1.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
| `0.2.0` | `dsh-v0.2.0-rc.2` | 第一个面向 DSH 桌面版 0.2.0 线的正式版,也是后续开发的基底。**只支持 `dsh-v0.2.0-rc.2` 这一条线**(peer `>=0.2.0-rc.2 <0.2.1-0`):去掉为更旧宿主保留的兼容分支(`settings.register` 的 live scope 回退等),并去掉对 `settings` 服务的必需依赖(只声明 `inject: ['tools']`,没有 Settings 服务的组合里也能启动);不改工具、动作、schema、文本与审批规则。在 `0.2.0-rc.2` 上完成 327 项测试、64 项真实浏览器 e2e 与 peer 双解析模式检查。旧宿主(0.1.7 线,`dsh-v0.1.7-rc.2`)继续使用 `0.1.17` |
|
|
18
|
-
| `0.2.1` | `dsh-v0.2.0-rc.2`(不变) | 相对 `0.2.0` 的补丁版,DSH 基线与 peer 范围(`>=0.2.0-rc.2 <0.2.1-0`)不变,只含两项:(1) 参数无效的调用不再先弹审批:审批钩子先判断动作是否被当前 `automationMode` 禁用(禁用仍直接拒绝),再用与 `runAction` 相同的校验检查参数,无效则不询问,执行层再校验一次并返回带精简 schema 的 `INVALID_ARGS`,不执行任何页面动作;参数有效时的审批规则与理由不变。(2) “探索转草稿”(`draft_from_journal`)的指导文本补充。不改动作、参数 schema 与审批规则。在 `0.2.0-rc.2` 上完成 337 项测试与 66 项真实浏览器 e2e |
|
|
19
|
-
|
|
20
|
-
`0.1.17` 把 DSH 运行时依赖由精确锁定改为范围声明(`^0.1.7-rc.2 || >=0.2.0-rc.1 <0.2.1-0`),
|
|
21
|
-
使同一份包可装在 `0.1.7-rc.2` 与 `0.2.0-rc.2` 两代宿主上。`0.2.0-rc.1` 起的新功能(动作体系、skill、recipe v2、
|
|
22
|
-
资产版本、提示文本配置等)只在 `0.2.0-rc.2` 上验证过,没有在 `0.1.7-rc.2` 上跑过,所以 `0.2.0` 把范围收成**只覆盖
|
|
23
|
-
`0.2.0-rc.2` 这条线**:`>=0.2.0-rc.2 <0.2.1-0`,正式版 `0.2.0` 起即采用这个范围。`0.1.17` 的范围不变,旧宿主继续用它。
|
|
24
|
-
|
|
25
|
-
这个写法同时满足两种解析,缺一不可:
|
|
26
|
-
|
|
27
|
-
- 宿主的组装期校验用的是 `semver.satisfies(host, range, { includePrerelease: true })`,所以「单范围能不能过宿主」不是关键。
|
|
28
|
-
真正决定装机成败的是 npm/pnpm 的**默认** semver:预发布版本只有在某个比较符自带同号(同 major.minor.patch)预发布时才被判为满足。
|
|
29
|
-
于是 `>=0.1.7-rc.2 <0.2.1-0` 这种写法过得了宿主校验,却会让 `dsh plugin add` 报 ERESOLVE(下界 tuple 是 0.1.7,接不住 0.2.0-rc.2);
|
|
30
|
-
`>=0.2.0-rc.2` 这个比较符自带 `0.2.0` 的预发布,是**承重**的,必须保留。
|
|
31
|
-
- 上界是 `<0.2.1-0` 而不是 `<0.2.1`:后者放行 `0.2.1-alpha.1` 这类 0.2.1 的预发布。收口后,若 0.2.1 真出现破坏,
|
|
32
|
-
会在**组装期**直接报 `is incompatible with dsh 0.2.1` 并点名,而不是拖到用户机器上变成运行期怪错
|
|
33
|
-
(`0.1.5 → 0.1.7` 曾一次性打断所有按 `0.1.5-alpha.1` 构建的插件)。
|
|
34
|
-
- 范围只表示「测过哪些」,不等于承诺不破坏;真正的防线是每换一个 DSH 版本重跑一遍这套验证。
|
|
35
|
-
`pnpm run test:peers`(已并入 `pnpm verify`)用两种解析模式逐个断言受管 peer:`0.2.0-rc.2` 必须通过,
|
|
36
|
-
`0.1.7-rc.2`、`0.2.0-rc.1`、`0.2.1-alpha.1` 必须被拒绝;并自带 `--selftest` 已知行为自校验。
|
|
37
|
-
|
|
38
|
-
`0.1.15` 使用 DSH 新客户端分包:状态存储来自
|
|
39
|
-
`dsh-client-store`,设置契约来自 `dsh-client-ui-settings`,客户端 Context
|
|
40
|
-
来自 Cordis。npm 上 `0.1.15-alpha.2` 仍声明旧版 DSH peer,不能与本版混用。
|
|
41
|
-
|
|
42
|
-
设置的读取不再对宿主版本做适配:Host 半边直接使用 Loader 传给 `apply` 的条目配置(设置页由条目的 `Config` schema 派生,
|
|
43
|
-
条目 id 为 `browser`),浏览器设置卡片使用 `ConfigForm`/`ctx.configForms`,`devDependencies` 锁定 `0.2.0-rc.2`。
|
|
44
|
-
可编辑字段都是 `.volatile()`:保存后新值写入运行中的引用,但浏览器进程、工具暴露与审批规则在启动时一次读取,
|
|
45
|
-
所以保存后仍需重启 profile 才生效(只有提示文本覆盖里的目录、错误提示等按调用实时读取,见「自定义提示文本」)。
|
|
46
|
-
|
|
47
|
-
插件只声明 `inject: ['tools']`,**不依赖宿主的 `settings` 服务**:Cordis 4.0.4 把声明了的 `inject` 一律当作必需,若声明 `settings`,
|
|
48
|
-
在没有该服务的组合(如 sdk-minimal,或关了 settings 行的 profile)里插件会一直挂起。插件的 Host 半边从不读取 `ctx.settings`,
|
|
49
|
-
配置来自 Loader 条目;没有 Settings 服务时按 `Config` 默认值运行,设置卡片只是不显示(客户端只在宿主提供 `browser` 命名空间时才挂载它)。
|
|
22
|
+
| `0.2.3`(当前) | `0.2.0-rc.2`、`0.2.1-rc.2` ~ `rc.5`、`0.2.2-rc.1` 起的 0.2.2 线(实测 0.2.0-rc.2、0.2.1-rc.3、0.2.1-rc.4、0.2.1-rc.5、0.2.2-rc.1;0.2.2 与 0.2.3 正式版靠 rc.1 的验证放行,尚未实测) | DSH 包 `>=0.2.0-rc.2 <0.2.1-0 \|\| >=0.2.1-rc.2 <0.2.2-0 \|\| >=0.2.2-rc.1 <0.2.3-0`;`@deepseek-ai/cordis` `~4.0.4 \|\| ~4.1.0` |
|
|
23
|
+
| `0.1.17`(0.1.7 线宿主固定用这一版) | `dsh-v0.1.7-rc.2` | 旧的 `browser_*` 工具体系 |
|
|
24
|
+
|
|
25
|
+
范围之外的宿主版本未经验证。历史版本、升级说明见 [CHANGELOG](https://github.com/anweat/dsh-browser/blob/master/CHANGELOG.md);peer 范围为什么写成两段见 [docs/dev/host-compat.md](https://github.com/anweat/dsh-browser/blob/master/docs/dev/host-compat.md)。
|
|
50
26
|
|
|
51
27
|
## 安装
|
|
52
28
|
|
|
29
|
+
**DSH CLI**(以 `web` profile 为例):
|
|
30
|
+
|
|
53
31
|
```bash
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
# 宿主仍是 0.1.7 线(dsh-v0.1.7-rc.2)时,固定安装 0.1.17(旧的 browser_* 工具体系):
|
|
32
|
+
dsh plugin --profile web add @anweat/dsh-browser@0.2.3
|
|
33
|
+
# 宿主仍是 0.1.7 线(dsh-v0.1.7-rc.2)时,固定安装 0.1.17:
|
|
57
34
|
dsh plugin --profile web add @anweat/dsh-browser@0.1.17
|
|
58
|
-
#
|
|
59
|
-
dsh plugin --profile web add ./dsh-browser
|
|
60
|
-
# 重启(web profile 关闭了 HMR):
|
|
35
|
+
# 装完重启 profile(web profile 关闭了 HMR):
|
|
61
36
|
dsh --profile web
|
|
62
37
|
```
|
|
63
38
|
|
|
64
|
-
|
|
65
|
-
> 旧宿主(`dsh-v0.1.7-rc.2` 线)请固定使用 `0.1.17`。预发布通道 `@next` 不再用于安装,`0.2.0-rc.1` 仅作历史记录。
|
|
66
|
-
> 若你的 harness 是包含未发布提交的本地源码 checkout,版本号可能有出入——用
|
|
67
|
-
> `dsh plugin --profile web add ./<path>` 并在 profile 的 `pnpm-workspace.yaml`
|
|
68
|
-
> 里对齐版本后重装即可。
|
|
69
|
-
|
|
70
|
-
## 从旧版本升级
|
|
71
|
-
|
|
72
|
-
### 升级到 0.2.1
|
|
73
|
-
|
|
74
|
-
- 从 `0.2.0` 直接升级即可,DSH 基线、peer 范围、动作、参数 schema、面向模型的文本与审批规则都没有变化,已保存的资产、配置与提示文本覆盖照常使用。
|
|
75
|
-
- 唯一的行为变化:参数无效的调用(例如 `act.select` 把 `values` 写成 `value`)不再先弹审批、等用户点“允许”之后才返回 `INVALID_ARGS`;现在直接返回 `INVALID_ARGS`(带精简 schema),页面没有任何改动,模型改对后只会询问一次。被当前 `automationMode` 禁用的动作仍直接拒绝。
|
|
39
|
+
**DSH Desktop**:profile 由应用管理,CLI 对 `--profile desktop` 会直接报错(`profile "desktop" is managed exclusively by the Electron application`),请在应用里装:
|
|
76
40
|
|
|
77
|
-
|
|
41
|
+
1. 打开**插件**页,点 **Add plugin**。
|
|
42
|
+
2. 填包名,可带版本,即上面 `dsh plugin add` 后面那一段,例如 `@anweat/dsh-browser@0.2.3`。
|
|
43
|
+
3. 对话框里还能选 **Registry**。国内镜像(如 npmmirror)可能比官方源晚几分钟到几小时,装不到新版本时,把 Registry 换成 `https://registry.npmjs.org`。
|
|
44
|
+
4. 点 **Install**,装完按应用提示重启。
|
|
78
45
|
|
|
79
|
-
|
|
80
|
-
- 其他插件或自定义提示词里如果写了旧工具名,需要同步修改。Web Search Pro 请使用提示词已更新的版本。
|
|
81
|
-
- 已保存的 recipe 和 userscript 资产照常可读、可运行;升级到 v2 用 `automation.develop` 的 `convert`,它只生成新草稿,不改原资产。
|
|
82
|
-
- 激活资产现在要求当前版本有通过的测试记录。旧资产加载时会自动补一条“旧版”记录。
|
|
83
|
-
- **声明了输入的资产,激活门槛提高了。**新增策略项 `automationAssets.minInputSetsForActivation`(默认 2,范围 1–5):带 `inputSchema` 或 `inputNames` 的资产,当前版本的通过凭据必须覆盖至少这么多组不同输入(`automation.develop` 的 `test` 传 `inputSets`;设置面板的“测试输入 JSON”填 2 到 5 个对象的数组),否则激活被拒绝,错误里写明原因。只用一组输入测试通过的 recipe 可能把那组输入写死,换一组就失败。没有输入的资产不受影响;升级前已通过测试的旧资产带“旧版”凭据,视为满足,不会因升级而无法激活。要恢复旧行为,把它设为 `1`。
|
|
84
|
-
- `BrowserService` 上供其他插件调用的方法(`render`、`snapshot`、`searchResults`、`opencli`、`close`)签名不变。
|
|
85
|
-
- **依赖范围收窄到 DSH 0.2.0 线。**peer 范围为 `>=0.2.0-rc.2 <0.2.1-0`(插件自身不再覆盖 `0.1.7-rc.2` 与 `0.2.0-rc.1`)。
|
|
86
|
-
- 先确认宿主是 `dsh-v0.2.0-rc.2`。宿主更旧时,`dsh plugin add` 会因 peer 不满足而拒绝,或在组装期点名报 `incompatible`;这类宿主继续使用 `0.1.17`。
|
|
87
|
-
- 工具、动作、参数 schema、文本与审批规则都没有变化,已保存的资产、配置与提示文本覆盖照常使用。
|
|
88
|
-
- 设置的保存与重启生效路径不变:在设置卡片保存后重启 profile 生效。
|
|
89
|
-
- 不再要求宿主提供 `settings` 服务:插件只声明 `inject: ['tools']`;有 Settings 服务时设置卡片照常显示,没有时按配置默认值运行。
|
|
46
|
+
非官方插件的升级 = 先卸载再重装。
|
|
90
47
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
Web Search Pro 与浏览器插件应同步升级;面向 `dsh-v0.1.7-rc.2` 不要混用仍声明旧 peer 的 Browser `0.1.15-alpha.2`;两者都升到 `0.1.17` 即可。
|
|
48
|
+
**本地目录 / tarball**(开发用):
|
|
94
49
|
|
|
95
50
|
```bash
|
|
96
|
-
dsh plugin --profile web add
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
升级后完整停止并重启 Web profile,再调用 `runtime.status`、`opencli.status` 和 `web_backend_status`;仅刷新网页不会重新加载插件服务或 Web Search Pro 配置面板。尤其不要只升级 Web Search Pro:新的工具目录、Patchright 运行时和调用缓冲都来自浏览器插件。
|
|
100
|
-
|
|
101
|
-
## 快速使用与适用情形
|
|
102
|
-
|
|
103
|
-
安装并重启后,模型通过 `browser_index` 查看能力目录、用 `browser_call` 执行动作(`runtime.status` 可查看运行时状态),再按任务选择动作。默认
|
|
104
|
-
`automationMode: standard`:读取直接执行,点击、输入、按键、选择、勾选、悬停、文件上传及页面写操作走 DSH 原生一次性审批。页面脚本和本地文件上传在 `autonomous` 下仍需审批,只有 `unrestricted` 会跳过确认。
|
|
105
|
-
|
|
106
|
-
| 情形 | 推荐方式 | 关键边界 |
|
|
107
|
-
|---|---|---|
|
|
108
|
-
| 公开网页读取、截图 | `target.open` → `observe.read` / `observe.screenshot` | 不需要登录态 |
|
|
109
|
-
| 表单、分页、懒加载 | `act.click` / `act.fill` / `act.type` / `act.clear` / `act.press` / `act.select` / `act.check` / `act.scroll` | CSS 或 role/text/label/testId 语义定位,默认严格唯一;`standard` 下审批 |
|
|
110
|
-
| SPA 条件等待 | `act.wait` | 支持 locator、URL glob、networkidle 或最多 10 秒固定等待 |
|
|
111
|
-
| 悬停菜单与提示 | `act.hover` | 与直接页面交互使用相同审批策略 |
|
|
112
|
-
| 文件上传 | `act.upload` | 只接受现有绝对文件路径;最多 20 个、合计 512 MiB;除 `unrestricted` 外审批会显示路径 |
|
|
113
|
-
| 页面脚本表达式 | `script.evaluate` | 使用当前页面来源和登录态;可访问 DOM、非 HttpOnly Cookie、Web Storage 和浏览器允许的网络 API |
|
|
114
|
-
| 页面故障排查 | `target.open(capture=[console,network])` → `inspect.console` / `inspect.requests` | 只在内存保留最多 200 条;网络仅记录失败及 4xx/5xx,不记录 body/header |
|
|
115
|
-
| 登录后站点 | `authProfile` | 必须配置 `allowedDomains`;默认不回写 Cookie |
|
|
116
|
-
| 固定站点增强 | `rulePack` | 只允许有界步骤;本地 init script 必须 SHA-256 固定且 ≤64KB |
|
|
117
|
-
| 模型生成的多步操作 | `automation.run_recipe` | 声明式步骤;审批策略由 `automationMode` 决定 |
|
|
118
|
-
| 默认只读脚本 | `script.catalog` → `script.run_builtin` | 内置 article/links/JSON-LD/forms,不执行外来代码 |
|
|
119
|
-
| 外部模型生成 UserScript | `script.validate` → `script.run_userscript` | 必须 `@match` + `@grant none`;除 `unrestricted` 外执行前审批 |
|
|
120
|
-
| 有限站点遍历 | `crawl.crawl` | 页数、深度、并发、突发与退避始终受 `usagePolicy` 约束 |
|
|
121
|
-
| Reddit/小红书等 OpenCLI 平台 | `opencli.status` → `opencli.catalog` → `opencli.run` | 先发现精确 adapter;通用调用除 `unrestricted` 外需审批 |
|
|
122
|
-
| 普通站点兼容性不佳 | `browserRuntime: patchright` | Chromium-only;建议专用 Chrome profile,不与指纹注入库叠加 |
|
|
123
|
-
|
|
124
|
-
所有网页访问、交互、脚本、Cookie 使用、上传和下载都必须由调用方或操作者根据目标网站规则及适用要求判断并使用。插件只执行被请求或批准的浏览器操作,不判断具体用途是否获得网站授权,也不承担调用方的合规责任。限流、审批、域名和文件边界用于约束执行面,不能替代目标网站规则。
|
|
125
|
-
|
|
126
|
-
DSH 会话示例:
|
|
127
|
-
|
|
128
|
-
```text
|
|
129
|
-
先调用 browser_call({action:"runtime.status"});然后用 target.open 打开目标页。
|
|
130
|
-
若页面需要登录,使用 authProfile=forum;不要把 Cookie 放进工具参数。
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
## 内核与依赖的"打包 vs 复用"
|
|
134
|
-
|
|
135
|
-
| 层 | 实际是什么 | 打包还是复用 |
|
|
136
|
-
|---|---|---|
|
|
137
|
-
| **chromium 内核** | 共享缓存 `%LOCALAPPDATA%\ms-playwright`(约 400MB) | **永远复用共享缓存**,不塞进插件、不重复下载;缺失时 `runtime.install` 一键补 |
|
|
138
|
-
| **playwright 驱动**(JS 包) | `playwright` npm 依赖 | 插件本地 node_modules 优先,缺省回退全局 npm |
|
|
139
|
-
| **patchright 驱动**(可选) | 与 Playwright 同版本的 Chromium 兼容驱动 | 插件内置;配置 `browserRuntime: patchright` 才启用 |
|
|
140
|
-
| **opencli**(纯 Node CLI) | `@jackwener/opencli` npm 依赖 | 同上,本地优先 / 全局复用 |
|
|
141
|
-
|
|
142
|
-
### 把共享浏览器缓存放到别的盘(可选)
|
|
143
|
-
|
|
144
|
-
共享缓存默认落在 `%LOCALAPPDATA%\ms-playwright`(Windows 上即系统盘,约 400MB)。
|
|
145
|
-
若要把内核放在别的盘、或直接复用一份已有的内核,在 loader 条目上显式给出可执行文件路径:
|
|
146
|
-
|
|
147
|
-
```yaml
|
|
148
|
-
- id: browser
|
|
149
|
-
config:
|
|
150
|
-
executablePath: 'E:/caches/ms-playwright/chromium-1234/chrome-win64/chrome.exe'
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
`executablePath` 必须指向真实的内核可执行文件(不是目录);设置后 `runtime.status` 会显示该路径,
|
|
154
|
-
`runtime.install` 不再需要执行。`browserRuntime: patchright` 时同样适用。
|
|
155
|
-
注意该字段在插件挂载时解析:改完需要重新加载 profile(重启 Web profile),仅刷新网页不生效。
|
|
156
|
-
|
|
157
|
-
## 服务:`browser`
|
|
158
|
-
|
|
159
|
-
`dsh-browser` 在 `apply()` 里 `ctx.provide('browser', service)`。任何插件声明
|
|
160
|
-
`inject: ['browser']` 即可消费:
|
|
161
|
-
|
|
162
|
-
```ts
|
|
163
|
-
export const inject = ['tools', 'browser']
|
|
164
|
-
export function apply(ctx: Context) {
|
|
165
|
-
const browser = ctx.get('browser') as BrowserService
|
|
166
|
-
// browser.render / snapshot / searchResults / opencli / recipe /
|
|
167
|
-
// runBuiltinScript / runUserscript / open / click / type / scroll / read / screenshot / close
|
|
168
|
-
}
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
服务接口(结构性,无需共享类型包)见 `src/browser-service.ts`。
|
|
172
|
-
|
|
173
|
-
### 跨 session 隔离
|
|
174
|
-
|
|
175
|
-
`browser` 服务是**单实例**:`apply()` 只 `ctx.provide` 一次,所有消费者拿到同一个
|
|
176
|
-
`BrowserService`。因此交互式页面状态不能是全局的。
|
|
177
|
-
|
|
178
|
-
宿主在工具执行时带上 `exec.agent`,它是 session 身份(`agent.session.id`,
|
|
179
|
-
基础契约里也声明 `agent.id: SessionId`)。插件据此为每个 session 分配独立的
|
|
180
|
-
`BrowserContext` + `Page`:
|
|
181
|
-
|
|
182
|
-
- **共享**:浏览器**进程**。启动 N 个 Chromium 代价高昂,而一个进程开 N 个
|
|
183
|
-
`BrowserContext` 正是 Chromium 自身的多配置文件模型。
|
|
184
|
-
- **隔离**:每个 session 的 `BrowserContext`、页面、auth profile、rule pack、
|
|
185
|
-
以及 console / network 抓取缓冲。
|
|
186
|
-
|
|
187
|
-
注意隔离单位是 **context 而不是标签页**:同一个 context 里的多个标签页共享
|
|
188
|
-
cookie 与 storage,跨 session 串号正是要防的事。
|
|
189
|
-
|
|
190
|
-
由此得到的行为边界:
|
|
191
|
-
|
|
192
|
-
| 工具 | 作用域 |
|
|
193
|
-
|---|---|
|
|
194
|
-
| `target.open` / `act.*` / `script.evaluate` / `observe.*` / `target.close` | 仅调用方 session |
|
|
195
|
-
| `inspect.console` / `inspect.requests` | 仅返回调用方 session 抓到的记录 |
|
|
196
|
-
| `runtime.status` 的 `activeUrl` | 仅报告调用方 session 的页面 |
|
|
197
|
-
| `render` / `snapshot` / `searchResults` / `crawl` / OpenCLI | 每次调用自建临时 context,本就无共享状态 |
|
|
198
|
-
|
|
199
|
-
`target.close` 关闭的是**调用方**的页面,不影响其他 session;插件卸载时
|
|
200
|
-
`close()` 才整体拆掉所有 session 的 context 与进程。
|
|
201
|
-
|
|
202
|
-
会话槽位上限由 `maxSessions`(默认 8)控制,超出后关闭最久未使用的 session。
|
|
203
|
-
读取类调用(`runtime.status` / `inspect.console` / `inspect.requests`)**不会**
|
|
204
|
-
创建槽位,也不会触发淘汰——否则一次查询就会挤掉别人的页面。
|
|
205
|
-
|
|
206
|
-
不带 `exec.agent` 的调用方(例如其他插件直接消费服务)落在共享桶里,行为与
|
|
207
|
-
引入隔离之前一致。
|
|
208
|
-
|
|
209
|
-
## 自动化自由度
|
|
210
|
-
|
|
211
|
-
`automationMode` 控制模型可见的工具集合和执行审批。建议从 `standard` 开始,仅在完全只读任务或受控自动化环境中切换:
|
|
212
|
-
|
|
213
|
-
| 模式 | 浏览器与 Web Search Pro 写操作 | 仍需审批或拒绝 | 不可取消的安全底线 |
|
|
214
|
-
|---|---|---|---|
|
|
215
|
-
| `read-only` | 只读工具与只读 Recipe;缓存清理、规则写入和安装拒绝 | 页面交互、写 Recipe、UserScript、OpenCLI run 均隐藏或拒绝 | 只能读取、校验、截图及运行只读脚本/Recipe |
|
|
216
|
-
| `standard`(默认) | 页面交互、写 Recipe、缓存清理和规则写入均需一次性审批 | UserScript、通用 OpenCLI、浏览器/后端安装也需审批 | 所有安全校验持续启用 |
|
|
217
|
-
| `autonomous` | 页面交互、写 Recipe、缓存清理和规则写入可直接执行 | 外部 UserScript、通用 OpenCLI、浏览器/后端安装仍强制审批 | 所有安全校验持续启用 |
|
|
218
|
-
| `unrestricted` | 所有上述工具均不触发审批,适合隔离环境中的无人值守测试 | 无审批提示 | 仍执行域名、元数据、参数、大小和步骤数校验 |
|
|
219
|
-
|
|
220
|
-
`unrestricted` 会允许模型直接运行外部脚本、通用 CLI 和安装命令,只应在隔离的测试 profile 或明确授权的自动化环境中使用;日常 profile 保持 `standard`。它只取消人工确认,**不会取消 `usagePolicy` 的并发、突发、页数、深度、重试与冷却保护**。模式改变后需要重启 DSH profile,工具目录才会按新配置重新注册。
|
|
221
|
-
|
|
222
|
-
## 工具与动作
|
|
223
|
-
|
|
224
|
-
模型可见的工具面由 `toolSurface` 决定:
|
|
225
|
-
|
|
226
|
-
| `toolSurface` | 注册的工具 | 常驻上下文 | 用途 |
|
|
227
|
-
|---|---|---|---|
|
|
228
|
-
| `indexed`(默认) | `browser_index`、`browser_call` 两个 | 约 0.3k token | 渐进披露:先看目录,再按需查看单个动作的 schema |
|
|
229
|
-
| `flat` | 每个可用动作一个工具,名为 `browser_<group>_<action>` | 约 14.5k token(34 个工具;recipe 的 v2 schema 在 `automation.develop` / `automation.run_recipe` 里内联展开) | 对照与调试;与 `indexed` 共用同一份动作注册表和同一个分发入口 |
|
|
230
|
-
|
|
231
|
-
`indexed` 下:`browser_index()` 列出能力组和当前环境状态(`automationMode`、Chromium 是否已安装);`browser_index({group})` 列出该组动作;`browser_index({action})` 给出完整参数 schema;`browser_index({query})` 按关键词检索。`browser_call({action, args})` 执行动作,服务端按 schema 校验参数,校验失败返回 `INVALID_ARGS` 并附上精简 schema。所有动作的返回值使用同一信封:
|
|
232
|
-
|
|
233
|
-
```json
|
|
234
|
-
{ "ok": true, "action": "act.click", "executionStatus": "completed", "result": { } }
|
|
235
|
-
{ "ok": false, "action": "act.click", "executionStatus": "failed", "error": { "code": "LOCATOR_NOT_FOUND", "message": "<Playwright 原始信息>", "hint": "…" } }
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
错误码:`INVALID_ARGS`、`UNKNOWN_ACTION`、`CAPABILITY_UNAVAILABLE`、`POLICY_DENIED`、`LOCATOR_NOT_FOUND`、`LOCATOR_AMBIGUOUS`、`NOT_ACTIONABLE`、`TARGET_CLOSED`、`DEADLINE`、`CANCELLED`、`NOT_FOUND`、`ACTION_FAILED`,以及 recipe 专用的 `VALIDATION_FAILED`、`OUTCOME_UNKNOWN`、`INVALID_RECIPE`。会产生副作用的动作超时时 `executionStatus` 为 `outcome_unknown`,调用方应先核验页面再决定是否重试。
|
|
239
|
-
|
|
240
|
-
**recipe 的执行结果**:`automation.run_recipe`、`automation.run`、`automation.develop` 的 `test` 总是把完整的运行报告放在 `result` 里,失败时也一样(此时 `ok` 为 false,并附带 `error`):`executionStatus`(`completed` / `failed` / `cancelled` / `outcome_unknown`)、`validationStatus`(`not_checked` / `passed` / `failed`)、`completedSteps`、`failedStep{index, action, errorCode, message, candidates?}`、`effects`(`none` / `observed` / `unknown`)、`outputs`。`ok` 只在“执行完成且没有断言失败”时为 true。extract 和 screenshot 的值只放在 `outputs`(v2 的 `extract` 带 `as` 时有 `name`),`completedSteps[].output` 是指向它的下标,不再重复一份。fill、clear、type、click、press、select、check 视为有副作用:如果超时发生在**已命中元素、动作已开始之后**,`executionStatus` 为 `outcome_unknown`、`effects` 为 `unknown`;如果 Playwright 的 call log 显示一直只在 “waiting for locator”(元素从未出现),该步没有动手,判为 `failed`、`LOCATOR_NOT_FOUND`,`effects` 不受影响;没有 call log 的超时无法证明元素从未命中,仍按 `outcome_unknown`。取消和整体 deadline 在每一步开始前以及最后一步之后检查;正在执行的 Playwright 步骤无法中断,调用会等它返回,已完成的步骤不回滚,session 页面保持打开。测试或运行只有在执行完成且没有断言失败时才算通过;没有 `assert` 步骤的旧式(v1)recipe 仍可通过测试,但资产记为 `evidenceLevel: 'legacy-unverified'`。
|
|
241
|
-
|
|
242
|
-
**严格定位**:原子动作和 v2 recipe 步骤共用同一套定位(`src/locator.ts`)。locator 必须只匹配一个元素;匹配多个时该动作**不执行**,返回 `LOCATOR_AMBIGUOUS`,`error.candidates` 给出总数和前 5 个候选(`role`、`name`、文本片段、`visible`)。确需选其中一个时写 `index` 并同时写 `indexReason`,否则拒绝。
|
|
243
|
-
|
|
244
|
-
**Recipe schema v2**:资产和内联 recipe 用 `schemaVersion: 2` 启用,缺省为 1,v1 的语义(CSS `selector`、永远取第一个匹配、fill 不允许空串)一律不变。v2 的变化:
|
|
245
|
-
|
|
246
|
-
- 步骤用 `locator`(`{role,name?,exact?}` / `{label}` / `{text}` / `{testId}` / `{css}`,可加 `framePath`);严格唯一,歧义时该步不执行且 `effects` 不变。
|
|
247
|
-
- 新增 `goto`(URL 必须落在资产的 `domains` 内,保存时和运行时各查一次,也检查重定向落点;内联 recipe 可停留在起始页同源,或落在显式的 `allowedDomains`)和 `clear`;`fill` 的空串必须写 `allowEmpty: true`,或改用 `clear`。
|
|
248
|
-
- `extract` 和 `assert` 默认最多等 5 秒(可用 `timeoutMs` 调整),选择器不存在时不再等约 30 秒;`extract` 可用 `as` 命名输出。
|
|
249
|
-
- 资产级字段:`inputSchema`(`string` / `number` / `enum`,可带 `required`、`example`、`enumValues`,运行前按 schema 校验并转换)、`outputSchema`(命名输出及类型 `string` / `number` / `json`)、`postconditions`(`{selector}` / `{text}` / `{urlIncludes}` / `{output, nonEmpty|allowEmpty}`)、`requiredCapabilities`(只记录,不门控)。
|
|
250
|
-
- `validationStatus` 为 `passed` 当且仅当所有 `assert` 和 postconditions 都成立。**没有任何 assert 或 postcondition 的 v2 资产可以保存为草稿,但测试不会记为 passed**,`testMessage` 会说明原因。
|
|
251
|
-
- `automation.develop` 的 `convert` 把 v1 recipe 资产转成**新的** v2 草稿:CSS selector 变成 `{css, explicitFirst: true}`(仍取第一个匹配),全部列入 `pendingDisambiguation`,草稿记录 `sourceAssetId` / `sourceRevision`,原资产(含 active)不会被修改;未知的 extract mode 或 wait condition 会拒绝转换并说明哪一步。
|
|
252
|
-
|
|
253
|
-
**审批按动作判断**:Host 的审批理由写明动作和关键参数(例如 `act.click role="button" name="Submit"`),`browser_index` 直接放行,`browser_call` 解析出动作后适用与下表相同的规则,不可用的动作在 `browser_call` 中再拒绝一次。判断顺序:先看动作是否被当前模式禁用(禁用则拒绝),再按动作的参数 schema 校验参数(与执行层是同一个校验;无效则不询问,直接交给执行层返回 `INVALID_ARGS`,不会执行任何页面动作),最后才是审批规则。Host 里按工具名设置的“总是允许”不会跳过插件策略。运行或回放资产(`automation.run`、`automation.develop` 的 `test`)时,审批理由写资产名称、版本和短 id,例如 `automation.run "Host check: docs search" r1 (5fdc912d)`;名称去掉换行并截断到 60 个字符。
|
|
254
|
-
|
|
255
|
-
旧的 30 个 `browser_*` 工具名已不再注册(`flat` 形态中 `browser_<group>_<action>` 与个别旧名相同,但它们现在就是注册表里的动作,返回统一信封)。
|
|
256
|
-
|
|
257
|
-
### 动作目录
|
|
258
|
-
|
|
259
|
-
| 动作 | 作用 |
|
|
260
|
-
|---|---|
|
|
261
|
-
| `target.open` | 打开 URL,返回标题/可读文本/全页截图路径;可显式启用 console/network 内存捕获 |
|
|
262
|
-
| `target.close` | 关闭当前页(下次 open 全新) |
|
|
263
|
-
| `target.list` | 列出本 session 的页面(自己打开的页加上弹窗),含 `id`、`url`、`title`、`active` |
|
|
264
|
-
| `target.select` | 把本 session 的某个页面(`target.list` 里的 id)切换为当前页;弹窗不会自动成为当前页 |
|
|
265
|
-
| `observe.read` | 读当前页 URL/标题/文本(不截图) |
|
|
266
|
-
| `observe.screenshot` | 当前页、locator 或区域截图;普通文件名固定落在 `snapshotDir` |
|
|
267
|
-
| `act.click` | 按 CSS 或结构化 Playwright locator 点击 |
|
|
268
|
-
| `act.fill` | 向 CSS 或语义定位的 input/textarea 填入文本,整体替换(原 `browser_type`) |
|
|
269
|
-
| `act.type` | 逐键输入(`pressSequentially`),触发每个按键事件;用于自动补全、掩码输入框 |
|
|
270
|
-
| `act.clear` | 清空输入框并触发 input 事件,受控输入的状态会同步 |
|
|
271
|
-
| `act.wait` | 等待 locator 状态、URL glob、networkidle 或固定时间 |
|
|
272
|
-
| `act.press` | 对 locator 或全局键盘发送按键 |
|
|
273
|
-
| `act.select` | 按 locator 选择一个或多个 option value |
|
|
274
|
-
| `act.check` | 按 locator 勾选或取消勾选控件 |
|
|
275
|
-
| `act.hover` | 悬停 CSS 或语义 locator 并返回页面状态 |
|
|
276
|
-
| `act.scroll` | 纵向滚动(触发懒加载) |
|
|
277
|
-
| `act.upload` | 把现有本地文件设置到 `input[type=file]`;绝对路径、数量和总大小受限 |
|
|
278
|
-
| `inspect.console` | 读取本次显式捕获的脱敏 console 记录 |
|
|
279
|
-
| `inspect.requests` | 读取本次显式捕获的失败及 HTTP 4xx/5xx 请求;无 body/header |
|
|
280
|
-
| `script.evaluate` | 在当前页执行最长 20,000 字符的 JavaScript 表达式,返回最多 100,000 字符 JSON |
|
|
281
|
-
| `script.catalog` | 列出内置只读脚本及其 SHA-256 |
|
|
282
|
-
| `script.validate` | 解析外部 UserScript 的元数据、域名、grant、能力与哈希,不执行 |
|
|
283
|
-
| `script.run_builtin` | 在独立 Playwright context 中运行内置只读脚本 |
|
|
284
|
-
| `script.run_userscript` | 运行外部 UserScript;强制域名匹配,审批策略由模式决定 |
|
|
285
|
-
| `runtime.status` | 运行时状态(含 automationMode、已暴露工具/动作及各类审批策略) |
|
|
286
|
-
| `runtime.install` | 安装 playwright chromium(`runtime.status` 报缺失时执行一次) |
|
|
287
|
-
| `automation.run_recipe` | 最多 25 步 Playwright Recipe;支持等待、定位、表单、键盘、提取、断言和截图;`schemaVersion: 2` 启用严格定位、`goto`、`clear` 与 postconditions |
|
|
288
|
-
| `automation.search` | 只有显式关键词调用才检索;可限定 active/draft/all、域名和类型,最多返回 `retrievalTopK` 条摘要 |
|
|
289
|
-
| `automation.develop` | 按确切 ID 读取源码,或显式保存、静态校验、真实回放、`convert`(v1 转 v2 新草稿);永远不能激活资产 |
|
|
290
|
-
| `automation.run` | 按 ID 运行已激活资产;再次执行限域和输入大小校验,审批由 `automationMode` 决定 |
|
|
291
|
-
| `opencli.status` | 实际运行 OpenCLI doctor,报告 daemon/extension/profile 连通性 |
|
|
292
|
-
| `opencli.catalog` | 对 OpenCLI 大目录按 query/site/access/strategy 过滤,单次最多返回 100 条 |
|
|
293
|
-
| `opencli.run` | 通用 OpenCLI argv 网关;除 `unrestricted` 外触发 DSH 原生一次性审批 |
|
|
294
|
-
| `crawl.crawl` | 匿名、有限广度遍历;默认同源,强制使用全局调用缓冲和单次页数/深度预算 |
|
|
295
|
-
|
|
296
|
-
### dsh-browser skill
|
|
297
|
-
|
|
298
|
-
插件在 Host 提供 `skills` 服务时注册 `dsh-browser` skill(`assets/skills/dsh-browser/`:SKILL.md 与 `references/`),内容为复用优先、定位策略、按错误码处理失败、沉淀资产和边界。`skills` 不是必需依赖:没有该服务时插件照常工作,`browser_index()` 的根目录附一段不超过 300 token 的精简指南。skill 与精简指南都可以用 `prompts` 配置覆盖,见“自定义提示文本”。
|
|
299
|
-
|
|
300
|
-
## 可复用自动化资产(实验性)
|
|
301
|
-
|
|
302
|
-
> **Experimental:** Recipe/UserScript 的积累、模型开发、检索和复用接口仍可能调整。建议先在隔离 profile 中启用,审阅草稿并完成真实浏览器回放后再手动激活;不要把它作为无人监管的生产写操作入口。
|
|
303
|
-
|
|
304
|
-
自动化执行自由度与资产持久化是两套独立开关。`automationMode: unrestricted` 只影响执行审批,不会让 Agent 自动保存脚本;默认 `automationAssets.persistenceMode: suggest` 仅对成功的 `automation.run_recipe` 记录脱敏语义步骤。具体输入会替换为 `{{input}}` / `{{secret}}`,会话 ID 只保存短哈希,不保存页面正文、cookie、token、密码或聊天记录。
|
|
305
|
-
|
|
306
|
-
默认在 14 天窗口内,同一域名和步骤指纹至少成功 3 次、来自至少 2 个会话且成功率达到 80%,面板才出现“是否总结”候选。每天最多提示 2 次;候选、草稿和已激活资产均有数量上限。推荐流程是:
|
|
307
|
-
|
|
308
|
-
1. 候选达到阈值后,在“浏览器自动化 → 可复用自动化资产”选择“总结为草稿”或“暂不总结”。
|
|
309
|
-
2. 在脚本列表点选草稿;只有此时前端才按 ID 读取完整 recipe / UserScript。编辑器支持 recipe 和带 `@match`、`@grant none` 的 UserScript。UserScript 可从只读对象 `__DSH_INPUTS__` 读取 `inputNames` 声明的运行时输入,输入不会写入资产文件。
|
|
310
|
-
3. 保存后先做静态校验,再填写测试 URL/输入执行真实浏览器回放。只有真实回放成功才可手动激活;已激活版本不可原地编辑,避免后台行为静默漂移。
|
|
311
|
-
4. Agent 用 `automation.search` 获取有界摘要,再用 `automation.run` 按 ID 调用。检索默认 top 5、目录预算约 800 tokens,源码不会进入模型上下文。
|
|
312
|
-
|
|
313
|
-
`persistenceMode` 可选 `off | manual | suggest | auto-draft`。日常使用建议 `suggest`;`auto-draft` 只适合隔离测试 profile,并且仍不会自动激活。`activationMode` 当前默认并推荐 `manual`;`auto-tested` 作为后续真实沙箱回放策略的保留配置,不会把一次静态校验当成生产激活依据。
|
|
314
|
-
|
|
315
|
-
### 模型显式开发 recipe / UserScript
|
|
316
|
-
|
|
317
|
-
模型目录不会预载任何 recipe 或源码。需要批量索引等强指向自动化时,模型按以下顺序显式访问:
|
|
318
|
-
|
|
319
|
-
1. 调用 `automation.search(query="batch-index issues", status="draft|active", kind="recipe")`,仅得到 ID、名称、标签、域名、输入名和运行统计。
|
|
320
|
-
2. 确认要修改某项后,调用 `automation.develop(action="get", id="...")`;只有这一步会把单个资产的完整 recipe/源码带入当前上下文。
|
|
321
|
-
3. `action="save"` 可直接声明新的 recipe(建议 `schemaVersion: 2`,见上文),或保存带 `@match` / `@grant none` 的 UserScript;只能生成/更新 draft,且整体替换。`action="convert"` 把 v1 资产复制成新的 v2 草稿。默认每个模型会话最多写 3 次(save 与 convert 合计),仍受全局 `maxDrafts` 限制。
|
|
322
|
-
4. `action="validate"` 只做结构与 UserScript 元数据校验,不提供激活资格;`action="test"` 必须给 URL 和声明输入,执行真实 Playwright 回放,成功后才标记 `passed`。
|
|
323
|
-
5. 激活、归档和回滚只在可视化面板完成,模型开发工具没有对应动作。
|
|
324
|
-
|
|
325
|
-
recipe 建议把检索意图固化在 `name`、`description` 和 `tags`,例如 `batch-index`、`issues`、`community-search`。检索采用小规模确定性关键词评分和 token 预算,不自动把整个资产库升级成模型工具,也不使用隐藏的全量 prompt 注入。
|
|
326
|
-
|
|
327
|
-
`modelDevelopmentEnabled: false` 会在重启后直接从模型工具目录移除开发入口;`standard` 保存草稿和真实回放均需审批,`autonomous` 可直接保存草稿但真实回放仍需审批,只有 `unrestricted` 才会跳过回放审批。所有模式仍执行域名、UserScript 元数据、输入、源码大小和使用频率限制。
|
|
328
|
-
|
|
329
|
-
## 使用策略:防止过度调用的缓冲
|
|
330
|
-
|
|
331
|
-
`usagePolicy` 是资源与站点压力保护,不是审批系统。所有模式共用同一个进程内 Governor:
|
|
332
|
-
|
|
333
|
-
- `maxConcurrency` 限制同时发起的导航,超出后排队;`burst` + `minDelayMs` 限制单站点短时突发。
|
|
334
|
-
- OpenCLI adapter / Browser Bridge 调度也占用同一全局并发与 burst 缓冲,不会因绕过 Playwright 而失去节流。
|
|
335
|
-
- 站点返回 429、502、503、504 时,按 `Retry-After` 或指数退避进入站点级冷却,最多重试 `retryLimit` 次。
|
|
336
|
-
- `crawl.crawl` 还受 `maxPagesPerRun` 和 `maxDepth` 硬上限约束;调用参数只能收紧,不能突破配置。
|
|
337
|
-
- 泛爬取默认使用匿名 context,不继承全局 `storageStatePath` 或 `defaultAuthProfile`;登录后读取仍使用显式限域的单页/Recipe 工具。
|
|
338
|
-
- `runtime.status` 显示累计运行、排队、等待和 backoff 次数,便于判断是否调用过密。
|
|
339
|
-
- 泛爬取能力本身不隐藏,但调用方仍应遵守目标站点条款、robots 指令、版权、隐私和适用法律;工具每次返回该警告。
|
|
340
|
-
|
|
341
|
-
## 外部模型脚本:推荐流程
|
|
342
|
-
|
|
343
|
-
外部模型可以输出 Tampermonkey/UserScript 格式源码,但不要直接执行。让当前 DSH Agent 先调用
|
|
344
|
-
`script.validate`,展示名称、`@match`、SHA-256 和能力,再调用
|
|
345
|
-
`script.run_userscript`。除 `unrestricted` 外,执行调用会进入 Harness 的
|
|
346
|
-
`tools/pre-execute → approval` 原生流程;用户拒绝、没有 approval 服务或调用不属于 Agent 时都不会运行。
|
|
347
|
-
|
|
348
|
-
最小脚本示例:
|
|
349
|
-
|
|
350
|
-
```js
|
|
351
|
-
// ==UserScript==
|
|
352
|
-
// @name Read Search Cards
|
|
353
|
-
// @match https://example.com/search*
|
|
354
|
-
// @grant none
|
|
355
|
-
// ==/UserScript==
|
|
356
|
-
return [...document.querySelectorAll('.result')].slice(0, 20).map(card => ({
|
|
357
|
-
title: card.querySelector('h2')?.textContent?.trim() || '',
|
|
358
|
-
url: card.querySelector('a')?.href || '',
|
|
359
|
-
}))
|
|
51
|
+
dsh plugin --profile web add ./dsh-browser # 本地检出
|
|
52
|
+
pnpm pack && dsh plugin --profile web add ./anweat-dsh-browser-0.2.3.tgz
|
|
360
53
|
```
|
|
361
54
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
- 只支持 `@grant none`;`GM_cookie`、`GM_xmlhttpRequest`、`unsafeWindow` 等不提供。
|
|
365
|
-
- 不支持 `@require`,避免审批过的源码在运行时再拉取未审查代码。
|
|
366
|
-
- 源码 ≤64KB、结果 ≤100,000 字符、单次运行最长 30 秒。
|
|
367
|
-
- 使用显式 URL,新建独立 Playwright context;需要登录态时只能选已限域的 `authProfile`。
|
|
368
|
-
- 审批代表允许该脚本以当前站点登录身份操作页面;静态能力报告只用于解释,不是沙箱。
|
|
369
|
-
|
|
370
|
-
`script.evaluate` 是面向当前持久页的短表达式入口,不使用 UserScript 元数据。它能调用页面已有 JavaScript、读取或修改 DOM、访问非 HttpOnly Cookie 和 Web Storage,也能通过 `fetch` 等浏览器 API 发起页面来源允许的请求。插件会明确报告这些能力,但不会判断具体网站是否允许该访问;调用方应根据目标网站规则及适用要求使用并承担相应责任,插件只执行被批准的浏览器操作。表达式没有 Node.js 全局对象或直接主机文件系统权限,结果必须可 JSON 序列化;超时会通过 Chromium DevTools 终止页面 JavaScript,保留当前 page/context 供后续读取或导航。需要可复用、可审阅的脚本时仍使用 UserScript 资产流程。
|
|
371
|
-
|
|
372
|
-
## Cookie 与文件落盘
|
|
55
|
+
本地源码 checkout 的版本号可能与已发布的有出入,需要在 profile 的 `pnpm-workspace.yaml` 里对齐版本后重装。`dsh plugin add` 在 pnpm 11 下应当直接成功、退出码 0;排障时才需要手改 profile 的 `package.json`。
|
|
373
56
|
|
|
374
|
-
|
|
375
|
-
- `script.evaluate` 可读取 `document.cookie`,因此能看到当前来源的非 HttpOnly Cookie;浏览器不会向页面 JavaScript 暴露 HttpOnly Cookie。除 `unrestricted` 外,每次执行都需要确认。
|
|
376
|
-
- `act.upload` 只读取调用中列出的绝对路径并交给当前页面上传控件,不修改源文件,也不会遍历目录。除 `unrestricted` 外,即使在 `autonomous` 模式也需要确认。
|
|
377
|
-
- `observe.screenshot` 和 `snapshot` 只向 `snapshotDir` 写入截图或 HTML;自定义截图名只允许普通文件名,拒绝绝对路径、目录分隔符和 `..`。持久登录态只写配置的状态文件。`script.evaluate` 触发的浏览器下载不会由该工具保存或返回,下载落盘需要后续单独设计显式目录和文件名规则。
|
|
378
|
-
- console/network 捕获必须由 `target.open.capture` 显式启用,只在内存保留最多 200 条;记录文本和 URL 查询中的常见 token/cookie/password 字段会脱敏,网络只保留方法、URL、失败原因或 4xx/5xx 状态,不保存 header/body。
|
|
57
|
+
## 第一次使用
|
|
379
58
|
|
|
380
|
-
|
|
381
|
-
|
|
59
|
+
1. **重启后找到设置卡片**:设置页的“插件”里,`@anweat/dsh-browser` 的配置卡片标题是“浏览器自动化”。顶部**状态摘要**直接说明运行环境:
|
|
60
|
+
- 红色徽章“没有可用浏览器”:点“查看详情”有可照做的步骤;
|
|
61
|
+
- “浏览器:系统 Chrome / Edge”:正常状态,什么都不用做;
|
|
62
|
+
- “OpenCLI 未安装”:只是提示,不是警告。
|
|
63
|
+
2. **确认浏览器**:让模型调用 `browser_call({action:"runtime.status"})`(或看状态摘要),`browser.ready` 为 `true` 即可。
|
|
64
|
+
- 有 Chrome / Edge:自动使用,不下载任何东西。Playwright 的 Chromium 一旦下载过就改用它;填了 `executablePath`,或把 `channel` 设为 `chrome` / `msedge`,则固定用你指定的那个,找不到就报错。
|
|
65
|
+
- 都没有:装 Chrome 或 Edge;或让模型调用 `runtime.install`(下载约 190 MB,会询问审批);或在设置里填 `executablePath`。完整选项见 [内核与依赖](https://github.com/anweat/dsh-browser/blob/master/docs/guide/runtime-and-dependencies.md)。
|
|
66
|
+
3. **可选依赖**:
|
|
67
|
+
- **OpenCLI**:只有 `opencli.*` 动作和 Web Search Pro 的 `browser-opencli` 后端用到。`npm i -g @jackwener/opencli`,重启后调用 `opencli.status`。不装不影响其他功能,也不会让 `dsh plugin add` 失败。查找顺序与排障见 [登录态复用与 OpenCLI](https://github.com/anweat/dsh-browser/blob/master/docs/guide/login-and-opencli.md)。
|
|
68
|
+
- **dsh-web-search-pro**:它在运行时读取本插件提供的 `browser` 服务来做页面快照、`playwright` 抓取和搜索页类平台,两者可独立安装;这些浏览器类能力需要本插件在场。
|
|
382
69
|
|
|
383
|
-
##
|
|
384
|
-
|
|
385
|
-
Recipe 适合让模型生成可审计、可复现的多步操作,不必生成 JavaScript:
|
|
386
|
-
|
|
387
|
-
```json
|
|
388
|
-
{
|
|
389
|
-
"url": "https://example.com/search",
|
|
390
|
-
"steps": [
|
|
391
|
-
{ "type": "wait", "condition": "selector", "value": "#query" },
|
|
392
|
-
{ "type": "fill", "selector": "#query", "value": "DeepSeek Harness" },
|
|
393
|
-
{ "type": "press", "selector": "#query", "key": "Enter" },
|
|
394
|
-
{ "type": "wait", "condition": "load" },
|
|
395
|
-
{ "type": "extract", "selector": "main", "mode": "links", "limit": 30 },
|
|
396
|
-
{ "type": "screenshot" }
|
|
397
|
-
]
|
|
398
|
-
}
|
|
399
|
-
```
|
|
70
|
+
## 快速示例
|
|
400
71
|
|
|
401
|
-
|
|
402
|
-
`scroll`、`extract`、`assert`、`screenshot`。纯读取步骤直接执行;出现点击、输入、键盘、选择、
|
|
403
|
-
勾选、悬停或滚动时,`standard` 下整个 Recipe 只询问一次审批,批准后顺序执行;
|
|
404
|
-
`autonomous` / `unrestricted` 下直接执行,`read-only` 下拒绝。
|
|
405
|
-
|
|
406
|
-
## 配置(cordis.yml / patch config)
|
|
72
|
+
**本地开发服务器**(例如 `http://127.0.0.1:5173` 的 Vite 应用):先在设置卡片(或配置文件)里设置:
|
|
407
73
|
|
|
408
74
|
```yaml
|
|
409
75
|
- insert:
|
|
410
76
|
- id: browser
|
|
411
77
|
name: '@anweat/dsh-browser'
|
|
412
78
|
config:
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
channel: chromium # 'chromium'(打包内核)| 'msedge'(系统 Edge)
|
|
417
|
-
headless: true
|
|
418
|
-
opencliEnabled: true
|
|
419
|
-
usagePolicy: # 所有模式都生效;无审批模式也不会绕过
|
|
420
|
-
minDelayMs: 750
|
|
421
|
-
maxConcurrency: 2
|
|
422
|
-
burst: 3
|
|
423
|
-
maxPagesPerRun: 20
|
|
424
|
-
maxDepth: 2
|
|
425
|
-
retryLimit: 2
|
|
426
|
-
backoffBaseMs: 1000
|
|
427
|
-
cooldownMs: 30000
|
|
428
|
-
automationAssets:
|
|
429
|
-
enabled: true
|
|
430
|
-
persistenceMode: suggest # off | manual | suggest | auto-draft
|
|
431
|
-
activationMode: manual # 当前推荐值;不会因静态校验自动激活
|
|
432
|
-
minSuccessfulRuns: 3
|
|
433
|
-
minDistinctSessions: 2
|
|
434
|
-
successWindowDays: 14
|
|
435
|
-
minSuccessRate: 0.8
|
|
436
|
-
maxCandidates: 20
|
|
437
|
-
candidateTtlDays: 14
|
|
438
|
-
maxSuggestionsPerDay: 2
|
|
439
|
-
maxDrafts: 10
|
|
440
|
-
maxActiveAssets: 50
|
|
441
|
-
retrievalTopK: 5
|
|
442
|
-
catalogTokenBudget: 800
|
|
443
|
-
modelDevelopmentEnabled: true
|
|
444
|
-
maxModelDraftWritesPerSession: 3
|
|
445
|
-
maxTestCredentials: 5 # 每个资产保留最近 N 条测试凭据(激活只认绑定当前 revision 与内容哈希的 passed 凭据)
|
|
446
|
-
minInputSetsForActivation: 2 # 声明了输入的资产,激活要求当前版本的通过凭据至少覆盖 N 组输入(1–5);无输入的资产不受影响
|
|
447
|
-
maxSessions: 8 # 同时持有 context+page 的 session 上限,超出淘汰最久未使用者
|
|
448
|
-
storageStatePath: '' # Playwright 登录态 JSON(复用已登录会话)
|
|
449
|
-
authProfiles:
|
|
450
|
-
forum:
|
|
451
|
-
storageStatePath: 'D:/secrets/forum.json'
|
|
452
|
-
allowedDomains: [example.com]
|
|
453
|
-
persistState: false # 默认只读;true 才会原子回写刷新后的状态
|
|
454
|
-
rulePacks:
|
|
455
|
-
forum-enhanced:
|
|
456
|
-
matches: [example.com]
|
|
457
|
-
initScriptPath: 'D:/dsh/rules/forum.js'
|
|
458
|
-
initScriptSha256: '<64位sha256>'
|
|
459
|
-
steps:
|
|
460
|
-
- { type: waitFor, selector: '#results', timeoutMs: 10000 }
|
|
461
|
-
- { type: scroll, deltaY: 1600, repeat: 2, waitMs: 300 }
|
|
462
|
-
autoInstall: false # 缺内核时是否自动 install chromium
|
|
463
|
-
verbose: false
|
|
79
|
+
channel: chrome # 固定用本机 Chrome;省略则自动选择
|
|
80
|
+
headless: true # 默认值,不弹窗口
|
|
81
|
+
automationMode: autonomous # 会话的审批策略为 never 时需要,见下
|
|
464
82
|
```
|
|
465
83
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
- **卡片覆盖全部公开配置字段**:`maxSessions`(会话上限)和 `args`(Chromium 启动参数,JSON 字符串数组)在“浏览器运行时”分区;`authProfiles`、`rulePacks` 结构较复杂,卡片里不提供表单,只列出名称并注明“在配置文件中编辑”。“调用缓冲 JSON”和“自动化资产策略 JSON”的提示由代码生成,列出全部可用键名。
|
|
469
|
-
- **测试输入 JSON** 填一个对象是在当前页面运行一次;填 2 到 5 个对象组成的数组是逐组在全新上下文中回放(等价于 `inputSets`)。卡片逐组显示结果和 `PARAMETERIZATION_SUSPECT` 警告;声明了输入的资产在通过凭据覆盖的输入组数不足 `minInputSetsForActivation` 时,“激活”按钮旁给出说明并保持禁用。
|
|
470
|
-
- **新建 recipe** 从 v2 模板开始(带 `schemaVersion: 2`、locator 步骤、`inputSchema` 和 `postconditions` 占位),模板本身可以直接保存。v1 recipe 有“转换为 v2”按钮:生成新草稿并选中,显示仍取第一个匹配的步骤数(`pendingDisambiguation`),原资产不变;有未保存修改时会先确认。
|
|
471
|
-
- “提示文本”分区的“导出默认文本”按钮在只读文本框里显示全部默认值(与 `pnpm prompts:dump` 相同的 JSON),复制后按需改写。
|
|
472
|
-
- 估算的常驻 L0 token 数与 `node scripts/measure-tool-surface.mjs` 使用同一个估算函数和同一份工具定义,两处数字一致。保存运行时配置后需要重启 profile;资产 CRUD 通过 loopback-only Host RPC 即时落盘。若没有看到卡片,先确认浏览器插件已同步升级并完整重启,而不是只刷新 Web Search Pro 页面。
|
|
473
|
-
|
|
474
|
-
### Patchright 可选内核
|
|
475
|
-
|
|
476
|
-
Patchright 是 Playwright-compatible 的 Chromium 驱动,适合普通 Playwright 在搜索页遇到自动化检测时显式启用:
|
|
84
|
+
保存后重启 profile,然后模型依次调用 `browser_call`:
|
|
477
85
|
|
|
478
|
-
```
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
86
|
+
```text
|
|
87
|
+
# 以下每行是一次 browser_call 的参数
|
|
88
|
+
{"action":"target.open","args":{"url":"http://127.0.0.1:5173"}}
|
|
89
|
+
{"action":"observe.read","args":{"sections":["controls","tables"]}}
|
|
90
|
+
{"action":"act.click","args":{"locator":{"role":"columnheader","name":"Name"}}}
|
|
91
|
+
{"action":"observe.screenshot","args":{"filename":"dev-home.png"}} → result.path
|
|
92
|
+
# 然后调用宿主的 read_image 工具
|
|
93
|
+
read_image({"file_path":"<上一步返回的 path>"})
|
|
482
94
|
```
|
|
483
95
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
模型读到的提示和建议文本都可以由部署方覆盖:两个常驻工具的描述、`browser_index` 根目录的指南和附言、分组与动作的摘要和说明、错误提示、以及 `dsh-browser` skill。不配置 `prompts` 时所有输出与内置默认逐字节一致。
|
|
491
|
-
|
|
492
|
-
**键结构**(全部可选;写在 `config.prompts` 下):
|
|
493
|
-
|
|
494
|
-
```yaml
|
|
495
|
-
- insert:
|
|
496
|
-
- id: browser
|
|
497
|
-
name: '@anweat/dsh-browser'
|
|
498
|
-
config:
|
|
499
|
-
prompts:
|
|
500
|
-
tools:
|
|
501
|
-
browser_index: { description: '浏览器能力目录。无参数:分组与环境状态。' }
|
|
502
|
-
browser_call: { description: '执行一个浏览器动作;动作名见 browser_index。' } # 合规声明始终自动追加在末尾
|
|
503
|
-
rootGuide: '先 automation.search;没有合适资产再 target.open -> observe.read -> act.*。' # 无 skill 时替换精简指南
|
|
504
|
-
rootNote: '内网站点优先用 opencli.run;不要访问生产后台。' # 追加在根目录末尾,有 skill 时也显示
|
|
505
|
-
groups:
|
|
506
|
-
act: { summary: '点击、填写、输入(会改变页面)' }
|
|
507
|
-
actions:
|
|
508
|
-
act.click: { summary: '点击元素', notes: '提交类按钮点击后先 observe.read 确认结果。' }
|
|
509
|
-
automation.develop.save: { notes: '保存前先 validate。' } # 子动作
|
|
510
|
-
observe.read.controls: { notes: '……' } # 详情页(notes 替换整页正文)
|
|
511
|
-
errorHints:
|
|
512
|
-
LOCATOR_NOT_FOUND: '没找到元素:先 observe.read 看页面,再换定位方式。'
|
|
513
|
-
skill:
|
|
514
|
-
enabled: true # false:不注册 skill,根目录改用精简指南
|
|
515
|
-
description: '浏览器工具使用指南'
|
|
516
|
-
bodyFile: 'D:/dsh/prompts/skill.md' # 绝对路径,替换 SKILL.md 正文(文件缺失/不可读时回退到内置正文)
|
|
517
|
-
append: '## 本部署的约定\n……' # 追加到正文末尾
|
|
518
|
-
```
|
|
96
|
+
- 访问本机地址的 `target.open` 不需要额外权限,也不需要登录 profile。
|
|
97
|
+
- **审批**:`standard`(默认)下 `act.*` 要走 DSH 审批;会话的审批策略为 `never` 时,所有需要询问的动作都会被自动拒绝,这时把 `automationMode` 设为 `autonomous`,页面交互就直接执行。`script.evaluate`、`act.upload` 在 `autonomous` 下仍会询问,只有 `unrestricted` 才跳过。
|
|
98
|
+
- **登录态**:要在本机地址上带登录态,配 `authProfiles`(`allowedDomains: [127.0.0.1]`,状态文件必须存在)。如果希望由 agent 经 `runtime.set_auth_profile` 自己写这类 loopback / 内网域名,需要 `allowPrivateHosts: true`(默认关);在会话审批策略为 `never` 时放宽动作会被拒绝,请直接在配置里写。
|
|
99
|
+
- **截图**:`observe.screenshot` 把文件存进 `snapshotDir`(默认 `$DSH_HOME/data/browser/snapshots`),结果里的 `path` 交给宿主的 `read_image` 工具(参数 `file_path`)读成图片;`read_image` 由宿主提供,不是本插件的工具。`target.open` 的结果里也带全页截图路径。
|
|
100
|
+
- 需要固定视口(例如手机尺寸):`target.open` 的 `viewport` 参数,或配置 `viewportMode`,见 [下载与上下文选项](https://github.com/anweat/dsh-browser/blob/master/docs/guide/downloads-and-context.md)。
|
|
519
101
|
|
|
520
|
-
|
|
102
|
+
**公开网页**:`target.open` → `observe.read` 读文本,`observe.screenshot` 截图;表单用 `act.fill` / `act.click`,`standard` 下每次询问一次。
|
|
521
103
|
|
|
522
|
-
|
|
104
|
+
## 工具与动作概览
|
|
523
105
|
|
|
524
|
-
|
|
106
|
+
模型先用 `browser_index` 看目录(无参数列出分组和环境状态;`{group}` 列动作;`{action}` 给完整参数 schema;`{query}` 关键词检索),再用 `browser_call({action, args})` 执行。所有动作返回同一种信封 `{ok, action, executionStatus, result | error{code,message,hint}}`。把 `toolSurface` 设为 `flat` 可以改成每个动作一个工具(常驻约 17.4k token,仅用于对照与调试)。
|
|
525
107
|
|
|
526
|
-
|
|
|
108
|
+
| 组 | 用途 |
|
|
527
109
|
|---|---|
|
|
528
|
-
|
|
|
529
|
-
|
|
|
530
|
-
| `
|
|
531
|
-
| `
|
|
532
|
-
| `
|
|
533
|
-
| `
|
|
534
|
-
| `
|
|
535
|
-
| `
|
|
536
|
-
| `
|
|
537
|
-
|
|
538
|
-
**未知或无效的键**(不存在的分组、动作、错误码,类型不对,`bodyFile` 不是绝对路径等)不会报错,只是被忽略。`errorHints` 只覆盖有固定文案的错误码;`INVALID_ARGS`、`ACTION_FAILED`、`UNKNOWN_ACTION` 的提示依上下文生成,不可覆盖,`DEADLINE` 对会改变状态的动作仍使用“结果未知,先核对再重试”的固定提示。
|
|
539
|
-
|
|
540
|
-
**诊断**:`browser_call({action:"runtime.status"})` 的结果有 `prompts` 段,列出生效的覆盖项(只有键名和长度,不回显全文)、被忽略的条目及原因、`bodyFile` 回退、L0 与各目录层的估算 token。设置卡片的“提示文本”分区显示同样的信息。
|
|
541
|
-
|
|
542
|
-
**热更新范围**:
|
|
543
|
-
- 目录(根目录、分组、动作、子动作、详情页、搜索)、错误提示:下一次调用即生效,无需重启。
|
|
544
|
-
- skill:开关、描述、正文文件和追加文本在下一次 `browser_index` / `browser_call` 时检测变化,注册或撤销 provider,或通过 provider 的 `invalidate()` 通知 Host;正文文件内容变化同样会被发现。
|
|
545
|
-
- 两个常驻工具的 `description`,以及 `flat` 表面的各动作工具描述:Host 在注册时固定,**保存后需重启 profile 才生效**。
|
|
110
|
+
| `runtime` | 运行时状态、Chromium 安装、登录 profile 与限流的策略覆盖层 |
|
|
111
|
+
| `target` | 打开 / 关闭 / 列出 / 切换页面,下载文件 |
|
|
112
|
+
| `observe` | 读页面文本、结构化观察(controls / links / tables)、截图 |
|
|
113
|
+
| `act` | 点击、填写、输入、清空、按键、选择、勾选、悬停、滚动、上传、等待 |
|
|
114
|
+
| `inspect` | console 与失败请求、下载记录、生效的策略 |
|
|
115
|
+
| `script` | 页面 JavaScript、内置只读脚本、UserScript |
|
|
116
|
+
| `automation` | 检索 / 运行可复用资产、开发草稿、内联 recipe |
|
|
117
|
+
| `crawl` | 有界多页遍历 |
|
|
118
|
+
| `opencli` | OpenCLI 站点 adapter |
|
|
546
119
|
|
|
547
|
-
|
|
120
|
+
完整动作目录、错误码、严格定位和审批规则见 [工具与动作](https://github.com/anweat/dsh-browser/blob/master/docs/guide/tools-and-actions.md) 与 [自动化自由度与审批](https://github.com/anweat/dsh-browser/blob/master/docs/guide/automation-modes.md)。插件随包提供 `dsh-browser` skill,教模型复用优先、定位策略和按错误码处理失败。
|
|
548
121
|
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
## 登录态复用
|
|
552
|
-
|
|
553
|
-
- `channel: chromium` + `storageStatePath` 指向一份 storageState JSON,即可用你已登录的身份抓受限页面。
|
|
554
|
-
- 新配置优先使用 `authProfiles`:按名称复用全局登录态,但必须用 `allowedDomains` 限域;默认只读,避免一次搜索意外改写 Cookie Vault。
|
|
555
|
-
- `target.open` 和 web-search-pro 的平台搜索可选择 `authProfile` / `rulePack`。`runtime.status` 只显示 profile 名称、域名和回写状态,不显示文件路径或 Cookie。
|
|
556
|
-
- RulePack 仍只允许有界动作;init script 必须是本地、SHA-256 固定且不超过 64KB。外部模型 JavaScript 使用独立的 UserScript 工具,不能冒充 RulePack;除 `unrestricted` 外需一次性审批。
|
|
557
|
-
- 生成登录态:`npx playwright codegen --save-storage=storageState.json`(或复用 `dsh-web-search-pro` 的 `scripts/save-login.mjs`),把产物路径填进 `storageStatePath`。
|
|
558
|
-
- opencli 的社交平台后端(小红书/推特/Reddit/IG/FB)仍需浏览器扩展 + 登录态在线,即使 opencli 已打包为依赖也绕不开扩展。
|
|
559
|
-
|
|
560
|
-
### OpenCLI 连接检查
|
|
561
|
-
|
|
562
|
-
插件运行时优先使用自己依赖的 OpenCLI。需要在终端排查 Browser Bridge 时,可全局安装同一 CLI 并检查:
|
|
563
|
-
|
|
564
|
-
```bash
|
|
565
|
-
npm i -g @jackwener/opencli
|
|
566
|
-
opencli daemon status
|
|
567
|
-
opencli doctor
|
|
568
|
-
```
|
|
122
|
+
所有网页访问、交互、脚本、Cookie 使用、上传和下载都必须由调用方或操作者根据目标网站规则及适用要求判断并使用;插件只执行被请求或批准的浏览器操作,不判断用途是否获得网站授权。
|
|
569
123
|
|
|
570
|
-
|
|
124
|
+
## 常用配置
|
|
571
125
|
|
|
572
|
-
|
|
126
|
+
在设置卡片里改,或写进 profile 的配置文件(完整带注释的示例见 [配置参考](https://github.com/anweat/dsh-browser/blob/master/docs/guide/configuration.md))。**保存后需要重启 profile 才生效**(只有提示文本覆盖按调用实时读取)。
|
|
573
127
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
```json
|
|
587
|
-
{ "query": "search", "site": "reddit", "access": "read", "limit": 10 }
|
|
588
|
-
```
|
|
589
|
-
|
|
590
|
-
`opencli.catalog` 从 `opencli list -f json` 读取并缓存目录,只暴露过滤后的最多 100 条;它不执行站点命令,也不读取站点登录数据。
|
|
591
|
-
|
|
592
|
-
优先级建议:已有站点 adapter(`opencli <site> <command>`)→ `opencli web read` / `extract` →
|
|
593
|
-
`browser network` → DOM state/find/action → 最后才是只读 `eval`。`opencli browser` 必须包含显式 session:
|
|
594
|
-
|
|
595
|
-
```text
|
|
596
|
-
["browser", "research", "open", "https://example.com"]
|
|
597
|
-
["browser", "research", "state"]
|
|
598
|
-
["browser", "research", "network", "--filter", "title,url"]
|
|
599
|
-
["browser", "research", "extract", "--selector", "main"]
|
|
600
|
-
["browser", "research", "close"]
|
|
601
|
-
```
|
|
128
|
+
| 键 | 默认 | 说明 |
|
|
129
|
+
|---|---|---|
|
|
130
|
+
| `automationMode` | `standard` | `read-only` 只读 \| `standard` 写操作逐次审批 \| `autonomous` 页面交互直接执行 \| `unrestricted` 全部免审批(仅隔离环境) |
|
|
131
|
+
| `toolSurface` | `indexed` | `indexed` 两个常驻工具;`flat` 每个动作一个工具 |
|
|
132
|
+
| `channel` | `chromium` | `chromium`(Playwright 的 Chromium,没装时自动用系统 Chrome / Edge)\| `chrome` \| `msedge`(固定用) |
|
|
133
|
+
| `headless` | `true` | `false` 显示浏览器窗口 |
|
|
134
|
+
| `executablePath` | 空 | 自定义浏览器可执行文件的绝对路径 |
|
|
135
|
+
| `browserRuntime` | `playwright` | `patchright`:仅 Chromium,对自动化检测更友好 |
|
|
136
|
+
| `opencliEnabled` | `true` | OpenCLI 总开关;没装 OpenCLI 时只是 `opencli.*` 不可用 |
|
|
137
|
+
| `authProfiles` / `defaultAuthProfile` | 空 | 按域名限定的登录态(`allowedDomains`、`storageStatePath`、`persistState`) |
|
|
138
|
+
| `allowPrivateHosts` | `false` | 允许 agent 把 localhost / 内网地址写进登录域名 |
|
|
139
|
+
| `downloadDir` / `downloadMaxBytes` | `$DSH_HOME/data/browser/downloads` / 100 MiB | 下载目录与单个文件上限 |
|
|
602
140
|
|
|
603
|
-
`
|
|
604
|
-
除 `unrestricted` 外都要求原生一次性审批。常规搜索仍优先走 `dsh-web-search-pro` 的只读工具。
|
|
141
|
+
另有视口、`userAgent`、`locale`、`timezoneId`、代理(`viewportMode`、`proxyServer` 等)、`usagePolicy` 限流、`automationAssets` 与 `prompts`,见配置参考。
|
|
605
142
|
|
|
606
|
-
##
|
|
143
|
+
## 文档索引
|
|
607
144
|
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
pnpm run build # tsc → lib/
|
|
612
|
-
pnpm run verify # typecheck → build → real-browser tests → client bundle check
|
|
613
|
-
node scripts/install-browser.mjs # 安装 chromium 内核(发布前验证,可选)
|
|
614
|
-
```
|
|
145
|
+
- 用户指南(中文):[文档索引](https://github.com/anweat/dsh-browser/blob/master/docs/README.md) 列出 `docs/guide/` 下每一篇——配置参考、设置卡片、工具与动作、Playwright Recipe、自动化资产、审批、策略覆盖层、使用策略、下载与上下文、登录态与 OpenCLI、内核与依赖、提示文本、UserScript、`browser` 服务。
|
|
146
|
+
- [CHANGELOG](https://github.com/anweat/dsh-browser/blob/master/CHANGELOG.md):各版本的兼容范围与升级说明。
|
|
147
|
+
- 开发者文档:[docs/dev/](https://github.com/anweat/dsh-browser/blob/master/docs/dev/build-and-release.md)(构建与发布、宿主兼容)、[docs/validation/](https://github.com/anweat/dsh-browser/tree/master/docs/validation)(验证记录)。
|
|
615
148
|
|
|
616
|
-
##
|
|
149
|
+
## License
|
|
617
150
|
|
|
618
|
-
|
|
619
|
-
`web_platform_search`(中文社区 playwright + 社交平台 opencli) 全部走本插件的 `browser` 服务。
|
|
620
|
-
两者可独立安装,但 web-search-pro 的浏览器类能力依赖 dsh-browser 先行提供 `browser` 服务(Cordis `inject` 自动排序,无需手动控制挂载顺序)。
|
|
151
|
+
MIT
|