插件#
插件让 agent-browser 可以与外部工具集成,而无需把这些工具纳入核心。插件是一个本地可执行程序,它从 stdin 读取一个 JSON 请求,并向 stdout 写回一个 JSON 响应。
可将插件用于基于 vault 的登录、自定义浏览器提供方、本地启动定制,以及 CAPTCHA 处理这类领域特定命令。
何时编写插件#
当集成需要厂商 SDK、本地 CLI、凭据、付费 API,或者不应成为 agent-browser 依赖的行为时,就编写插件。
适合做成插件的场景:
- 从外部 vault 解析登录凭据
- 通过托管提供方启动浏览器并返回 CDP WebSocket URL
- 添加本地 Chrome 启动参数、扩展或初始化脚本
- 运行类似
captcha.solve这样的命名空间命令
浏览器自动化本身应保留在 agent-browser 中。插件应提供数据或启动配置,然后让 agent-browser 继续驱动浏览器。
适合做成插件的内容#
以下是插件作者适合从这些地方开始的方向:
- 新的云浏览器提供方:托管浏览器平台是
browser.provider的好模型。已有内置提供方可以为了兼容性留在核心里,但新的提供方通常应先作为插件出现。 - Vault 集成:密码管理器、密钥存储和企业 SSO helper 适合
credential.read。把本地加密认证 vault 保留在核心中,但把厂商特定的 vault 访问放进插件。 - 隐身与反检测:这些技术变化很快,在核心中支持它们可能有风险。适合通过
launch.mutate插件附加启动参数、扩展、初始化脚本或 user-agent 覆写。 - CAPTCHA 解决器:CAPTCHA 集成属于插件领域,因为它们涉及第三方 API、凭据、政策考量以及快速的厂商变化。它们可以使用
command.run,也可以使用像captcha.solve这样的自定义能力。 - 厂商特定认证 helper:针对特定应用、IdP 或企业流程的登录 helper 应该放在核心之外,除非它们演变成通用浏览器自动化原语。
添加他人构建的插件#
使用包名或仓库名执行 plugin add:
agent-browser plugin add agent-browser-plugin-captcha
agent-browser plugin add @company/agent-browser-plugin-vault --name vault
agent-browser plugin add org/agent-browser-plugin-cloud-browseragent-browser 会根据引用自动选择来源:
| 引用 | 来源 | 示例 |
|---|---|---|
name | npm 包 | agent-browser-plugin-captcha |
@scope/name | 带作用域的 npm 包 | @company/agent-browser-plugin-vault |
owner/repo | GitHub 仓库 | org/agent-browser-plugin-cloud-browser |
plugin add 默认会写入 ./agent-browser.json。如需写入 ~/.agent-browser/config.json,请使用 --global。
在添加过程中,agent-browser 会运行一次该包并请求 plugin.manifest。插件清单会声明插件名称和能力。如果插件暂不支持清单,请使用插件 README 中列出的能力:
agent-browser plugin add agent-browser-plugin-captcha --capability command.run --capability captcha.solve --no-manifest验证插件是否已配置:
agent-browser plugin list
agent-browser plugin show captcha然后通过其能力对应的命令路径来使用它:
agent-browser auth login my-app --credential-provider vault --item "My App"
agent-browser --provider cloud-browser open https://example.com
agent-browser open https://example.com
agent-browser plugin run captcha captcha.solve --payload '{"siteKey":"abc","url":"https://example.com"}'launch.mutate 插件会在本地启动时自动运行,例如 agent-browser open。
配置插件#
plugin add 会为你创建这份配置。你也可以手动编辑 plugins 数组:
{
"plugins": [
{
"name": "vault",
"command": "agent-browser-plugin-vault",
"args": [],
"capabilities": ["credential.read"]
},
{
"name": "captcha",
"command": "agent-browser-plugin-captcha",
"capabilities": ["command.run", "captcha.solve"]
}
]
}查看注册表:
agent-browser plugin list
agent-browser plugin show vaultAGENT_BROWSER_PLUGINS 可以用同样结构的 JSON 数组替代配置发现。
不要把 API token、vault token 或密码放进插件 args。请使用厂商自己的 CLI 登录、钥匙串、环境变量或会话机制,而不是写进 agent-browser 配置。
协议#
agent-browser 会启动该可执行文件,把这个信封写入 stdin,等待 stdout,并将 stdout 解析为 JSON:
{
"protocol": "agent-browser.plugin.v1",
"type": "credential.resolve",
"capability": "credential.read",
"request": {}
}每个成功响应都必须包含相同的协议和 success: true:
{
"protocol": "agent-browser.plugin.v1",
"success": true,
"data": {}
}只会解析 stdout。不要向 stdout 写日志。agent-browser 会在核心集成中抑制插件的 stderr,因此开发时请使用文件或你自己的调试模式。
为了降低意外泄露密钥的风险,核心集成会在面向用户的错误中抑制插件提供的错误文本。通用的 plugin run 会保留插件错误文本,因为它是面向开发者的命令。
插件清单#
支持 plugin.manifest,这样用户就能在不手动输入能力的情况下添加你的插件:
{
"protocol": "agent-browser.plugin.v1",
"type": "plugin.manifest",
"capability": "plugin.manifest",
"request": {}
}返回插件名称和能力:
{
"protocol": "agent-browser.plugin.v1",
"success": true,
"manifest": {
"name": "captcha",
"capabilities": ["command.run", "captcha.solve"],
"description": "Solve CAPTCHA challenges through Example CAPTCHA"
}
}有了清单,用户可以运行:
agent-browser plugin add agent-browser-plugin-captcha没有清单时,用户必须在添加时传入 --capability 标志。
能力#
| 能力 | 请求类型 | 用户如何调用 | 响应字段 |
|---|---|---|---|
credential.read | credential.resolve | auth login --credential-provider <name> | credential |
browser.provider | browser.launch, browser.close | --provider <name> | browser |
launch.mutate | launch.mutate | 任何本地启动 | launch |
command.run | 自定义请求类型 | plugin run <name> <type> | data |
插件可以声明自定义能力,例如 captcha.solve。plugin run 可以调用 command.run 和自定义能力,但不能直接调用核心能力或协议请求类型。credential.read、browser.provider 和 launch.mutate 请使用专用命令路径。
最小插件#
这个插件实现了 captcha.solve 并返回一个伪造 token:
#!/usr/bin/env node
const chunks = [];
for await (const chunk of process.stdin) {
chunks.push(chunk);
}
const input = JSON.parse(Buffer.concat(chunks).toString("utf8"));
function reply(body) {
process.stdout.write(
JSON.stringify({
protocol: "agent-browser.plugin.v1",
success: true,
...body,
})
);
}
if (input.protocol !== "agent-browser.plugin.v1") {
process.stdout.write(
JSON.stringify({
protocol: "agent-browser.plugin.v1",
success: false,
error: "unsupported protocol",
})
);
process.exit(0);
}
if (input.type === "plugin.manifest") {
reply({
manifest: {
name: "captcha",
capabilities: ["command.run", "captcha.solve"],
description: "Example CAPTCHA plugin",
},
});
process.exit(0);
}
if (input.type === "captcha.solve") {
reply({
data: {
token: "example-token",
siteKey: input.request.siteKey,
url: input.request.url,
},
});
process.exit(0);
}
process.stdout.write(
JSON.stringify({
protocol: "agent-browser.plugin.v1",
success: false,
error: `unsupported request type: ${input.type}`,
})
);将其设为可执行并进行配置:
chmod +x ./agent-browser-plugin-captcha{
"plugins": [
{
"name": "captcha",
"command": "./agent-browser-plugin-captcha",
"capabilities": ["command.run", "captcha.solve"]
}
]
}运行它:
agent-browser plugin run captcha captcha.solve --payload '{"siteKey":"abc","url":"https://example.com"}'凭据插件#
凭据插件接收:
{
"protocol": "agent-browser.plugin.v1",
"type": "credential.resolve",
"capability": "credential.read",
"request": {
"profileName": "my-app",
"itemRef": "My App",
"url": "https://app.example.com/login"
}
}返回 credential:
{
"protocol": "agent-browser.plugin.v1",
"success": true,
"credential": {
"username": "alice@example.com",
"password": "secret",
"url": "https://app.example.com/login",
"usernameSelector": "#username",
"passwordSelector": "#password",
"submitSelector": "input[type=submit]"
}
}将其用于一次登录:
agent-browser auth login my-app --credential-provider vault --item "My App"对于外部 vault,优先在插件中调用厂商 CLI,并依赖其现有的本地会话。不要在 agent-browser.json 中传入 vault token。
浏览器提供方插件#
浏览器提供方插件接收 browser.launch 并返回一个 CDP URL:
{
"protocol": "agent-browser.plugin.v1",
"success": true,
"browser": {
"cdpUrl": "ws://127.0.0.1:9222/devtools/browser/session",
"directPage": false,
"metadata": {
"sessionId": "provider-session-id"
},
"cleanup": {
"sessionId": "provider-session-id"
}
}
}然后用户通过插件名称启动:
agent-browser --provider cloud-browser open https://example.com如果返回了 cleanup 且连接失败,agent-browser 稍后会将其作为 browser.close 的请求体发回。
启动修改器插件#
启动修改器会在 Chrome 启动前接收本地启动选项,并且可以追加参数、扩展、初始化脚本或 user agent:
{
"protocol": "agent-browser.plugin.v1",
"success": true,
"launch": {
"args": ["--disable-blink-features=AutomationControlled"],
"extensions": ["/absolute/path/to/extension"],
"initScripts": [
"Object.defineProperty(navigator, 'webdriver', { get: () => undefined });"
],
"userAgent": "my-agent/1.0"
}
}用 launch.mutate 配置它,然后使用任意本地启动命令:
agent-browser open https://example.comLaunch mutator 不会在 CDP 连接或远程浏览器提供方上运行,因为这些浏览器已经在本地启动路径之外运行。
策略与确认#
插件访问会以按能力分组的策略动作形式暴露:
agent-browser --confirm-actions plugin:vault:credential.read auth login my-app --credential-provider vault --item "My App"
agent-browser --confirm-actions plugin:cloud-browser:browser.provider --provider cloud-browser open https://example.com
agent-browser --confirm-actions plugin:stealth:launch.mutate open https://example.com动作字符串的格式是 plugin:<name>:<capability>。
打包建议#
对于 npm 包,请暴露一个不需要 stdout 日志的 bin 命令:
{
"name": "agent-browser-plugin-example",
"bin": {
"agent-browser-plugin-example": "./bin/plugin.js"
}
}保持插件小而明确:
- 只声明它实际支持的能力
- 只从 stdin 读取一个请求
- 只向 stdout 写一个 JSON 响应
- 不要把密钥放在命令行参数里
- 让 agent-browser 处理导航、选择器、截图、状态和策略