使用说明
# 智页(SmartPage Agent)
浏览器内运行的网页智能体。用自然语言读取、提取、修改当前网页,并具备完整的「供应商 → 模型 → 环境 → 会话」管理链路;SubAgent 由环境授权后在对话中被派发。
本版本按 awake-claw 的分层架构与对话交互 重构:原先 6000 余行的单体 background.js 拆分为 infrastructure / antiseptic / application / frontend 四层,管理界面迁移为 Vue 3 + Element Plus。
快速开始
npm install
npm run build # 产出 dist/
加载扩展:
- 打开
chrome://extensions - 开启「开发者模式」
- 「加载已解压的扩展程序」→ 选择本仓库的
dist/目录 - 点击扩展图标打开弹窗,或点齿轮进入控制台(
options.html)
首次使用顺序:供应商 → 模型 → 环境 → 新建会话。对话不依赖 Agent:新建会话时直接选环境、供应商、模型与提示词,之后在右侧「模型参数」面板随时调整(自动保存到会话快照)。
分层结构
src/
├─ background/ # MV3 service worker 入口:消息路由 + 流式对话端口
├─ application/
│ └─ api/router.js # REST 风格路由(/api/providers、/api/agents …)
├─ antiseptic/ # 业务编排层(对应 awake-claw 同名层)
│ ├─ provider_business.js # 供应商(含凭据脱敏、连通性测试)
│ ├─ model_business.js # 模型(含供应商联表)
│ ├─ agent_business.js # SubAgent(能力求交、复制、就绪判定)
│ ├─ mcp_business.js # MCP 服务(含请求头脱敏、工具 schema 查看)
│ ├─ skill_business.js # 技能(SKILL.md / 资源文件)
│ ├─ environment_business.js # 环境(人格/画像/记忆、资源开关、SubAgent 授权、提示词预览)
│ ├─ session_business.js # 会话、模型快照与事件时间线
│ ├─ chat_business.js # 回合执行、重试、停止、并发互斥
│ └─ tool_business.js # 工具清单与分组设置
├─ infrastructure/
│ ├─ repository/ # IndexedDB 存储,表结构对齐 awake-claw SQLite
│ ├─ model/
│ │ ├─ http.js # SSE 读取、URL 拼接
│ │ └─ model_params.js # 协议字段表、默认值、执行参数(前后端共用)
│ ├─ model_provider/ # OpenAI 兼容 / Anthropic 两种协议适配
│ └─ runtime/
│ ├─ tool_loop.js # 模型 + 工具循环(主会话与 SubAgent 共用)
│ ├─ agent_executor.js # 会话回合编排:快照解析、资源解析、事件落库
│ ├─ subagent_runtime.js # SubAgent 派发:独立提示、只读/可操作、嵌套事件
│ ├─ prompt_builder.js # 系统提示组装
│ ├─ mcp_runtime.js # Streamable HTTP / SSE / HTTP 网关
│ └─ tools/ # 工具注册表:页面 / 标签页 / 脚本 / 技能 / SubAgent
└─ frontend/
├─ popup/ # 扩展弹窗(H5 版对话:顶部工具条 + 会话抽屉 + 事件线)
├─ shared/timeline.js # 事件 → 轮次/块的共用解析(桌面与 H5 同一套语义)
└─ options/ # 控制台:对话、环境、SubAgent、提示词、模型、MCP、技能、工具、设置
数据模型
IndexedDB 库名 smartpage_agent,objectStore 与 awake-claw 的表一一对应:
| 表 | 说明 |
|---|---|
providers |
供应商:协议类型、Base URL、API Key、自定义请求头 |
models |
模型:别名、模型 ID、协议、上下文窗口、model_params / execution_params |
prompt_templates |
提示词模板 |
agents |
SubAgent:模型绑定、runtime_params、ext_config(工具/MCP/技能/人设) |
mcp_servers |
MCP 服务:transport、url、headers |
skills |
技能包:文件数组(SKILL.md + 资源) |
environments |
环境:人格/画像/记忆、工具/MCP/技能开关、SubAgent 授权 |
sessions |
会话:环境、提示词、供应商/模型与 model_snapshot(不依赖 Agent) |
message_events |
事件:user_message / model_reasoning / model_reply / model_retry / tool_call / tool_result / subagent / turn_notice / task_failed / model_reply_cancelled |
config |
全局设置(模型请求、工具与脚本、网络抓取、MCP 与权限开关) |
界面布局
控制台采用「侧栏固定 + 内容区独立滚动」:.shell 占满视口并隐藏溢出,页面根容器 .sp-page 在内容区内滚动,滚动条只出现在内容区右侧、按需显示,不会再让整个页面出现滚动条。环境管理使用双栏固定高度布局(左右两栏各自滚动),对话页为三栏自适应。
对话交互(对齐 awake-claw)
- 新建会话:控制台与工具栏弹窗都使用同一个创建对话框,必须选择环境、供应商、模型(提示词可选),标题可留空;创建时写入
model_snapshot,后续对话不再依赖 Agent。后端同样校验,缺少环境会返回SESSION_ENVIRONMENT_REQUIRED。 - 右侧模型参数面板:环境 / 供应商 / 模型 / 提示词 / API 协议(对话补全、响应接口、消息接口),以及上下文窗口、最大历史条数、历史 Token 比例、输入模态、模型参数与执行参数,改动 700ms 后自动保存。
- 普通参数与高级参数:协议常用字段(温度、最大输出、推理强度、流式)与上下文窗口、历史条数、历史 Token 比例、模态直接平铺;
top_p、惩罚项、结构化输出、工具行为、流式缓存等收进「高级参数」折叠,标题上实时显示「N 项已设置」,收起也能看出有没有配过。字段名与枚举值全部中文,悬浮提示里给出原始参数名。 - 单一数据源:参数修改以整对象向上提交,切换会话或刷新后都能正确回显;会话切换前会先落库待保存的改动,避免写到别的会话。
- 模型参数按协议动态生成:只展示当前协议合法的字段(例如
max_tokens只出现在 Anthropic,reasoning_effort只出现在 OpenAI chat),并按分组折叠,避免发出会被 400 的键。 - 执行参数:
max_tool_call_rounds(工具轮次上限)、max_retries(模型请求重试次数,默认 2,0 表示跟随设置页全局值)、tool_call_retention_rounds(历史中保留最近几批工具明细)。429 限流、5xx 与网络错误会按退避自动重试,重试过程写入model_retry轨道行,无需手动点按钮。重试计数按事件线累计(重试 ×1、重试 ×2…),与 awake 的retry_count语义一致,不再显示1/2这种每次请求都重置的分式。 - 历史裁剪:
history_token_ratio按「字符数 × 比例」估算历史 Token(默认 0.35),预算 = 上下文窗口 − 输出预留 − 系统提示占用;超预算时从最早的消息开始丢弃,且不会以 tool 消息开头。优先级为会话 → 模型默认。 - 事件线(直接移植 awake 的 ConversationTimeline):用户消息是右对齐的浅蓝气泡;助手侧是一条带竖线的事件轨道,思考、工具、回复、SubAgent、重试、失败全部是同级轨道行,图标同一列、正文统一缩进 22px。思考行默认收起,摘要取最近 160 字(与 awake 的
eventSummary一致),展开才显示全文。工具行展开后是「参数 / 返回」两栏,失败行展开是完整错误并带「重试本轮」。 - 两套外形,一套结构:控制台与工具栏弹窗共用同一套时间线 DOM 与样式(弹窗只是把字号、间距、图标尺寸压小),差异仅在容器宽度;两端共用
frontend/shared/timeline.js的轮次解析,避免语义分叉。 - 删除与清空:每条轮次底部有「删除本轮」;失败事件行内也可直接重试或删除。弹窗会话抽屉里可「清空会话」或删除整个会话,操作前均有二次确认。
SubAgent
Agent 不再参与普通会话,只作为 SubAgent 使用(参考 awake-claw 的 coding subagent):
- 在「SubAgent」页创建:绑定供应商/模型/提示词,勾选工具、技能、MCP,设置运行参数。
- 在「环境 → SubAgent」授权:选择访问模式(
read_only只能读取页面;workspace_write可点击、输入、执行脚本),脚本执行需单独允许。 - 主 Agent 拿到
subagents_list/subagent_run两个工具,派发时给出agent_id、title、task、context。 - SubAgent 拥有独立系统提示与消息序列,不加载父会话历史,也不能再派发 SubAgent;执行过程以
subagent事件嵌套展示。 - 未授权任何 SubAgent 时,这两个工具不会下发,避免模型反复试探。
能力开关语义(与 awake-claw 一致)
include_new = true:显式启用集合 ∪ 全部现存资源(等价于全量可用)include_new = false:仅显式启用的资源- 会话使用的工具由 环境资源 决定;SubAgent 的工具由 SubAgent 勾选 ∩ 环境资源 决定,并按访问模式收窄
- 环境开启「注入技能元数据」后,已启用技能的「名称 + 描述」写入 system prompt,模型再按需
skills_view加载全文
设置
设置页按分组渲染(键名与后端 config_meta.js 一致,避免两边各写一份):
| 分组 | 内容 |
|---|---|
| 模型请求 | 请求超时、网络层重试、重试退避、默认工具轮次 |
| 工具与脚本 | 工具超时、脚本超时、交互后等待 |
| 网络抓取 | web_fetch 开关、抓取超时、返回字符上限、域名白名单 |
| MCP | 连接超时、工具缓存 |
| 权限 | 调试通道权限状态(安装级)、allow_script 与 CDP 回退开关 |
设置页结构对齐 awake-claw:单面板内按分组堆叠,分组标题栏 + 两列行(说明 / 控件),右侧标注控件类型。
没有「新会话默认」这类配置:新建会话必须显式选择环境、供应商、模型(提示词可选),因此默认环境 / 默认提示词 / 默认模型 / 全局备注都不再存在,避免出现「看着配了、实际没生效」的隐式状态。
供应商配置
- 协议:OpenAI 官方 / OpenAI 兼容端点 / Anthropic
- 请求路径:下拉选择,由协议决定——OpenAI 提供「对话补全(/chat/completions)」与「响应接口(/responses)」,Anthropic 固定 Messages 接口、不显示该字段;旧数据中的自定义路径会作为额外选项保留
- 自定义请求头:逐行表格编辑(名称 / 值 / 删除),支持批量导入——
Key: Value、Key=Value、Key,Value三种写法,也可直接粘贴 JSON;名称与值会自动去掉首尾空格与包裹引号,重复名称以最后一行为准
内置工具(74 个:61 个默认 + 13 个需显式启用,其中 40 个只读)
- 标签页与导航(10):
list_tabs、get_active_tab、open_tab、switch_tab、close_tab、go_back、go_forward、reload_tab、wait_for_navigation、list_framesswitch_tab/open_tab会把目标标签页绑定为当前工作标签页,后续页面工具自动跟随wait_for_navigation以「URL 变化或匹配 + 加载完成」为条件,避免用固定 sleep 猜加载
- 页面读取(13):
get_page_snapshot、get_element_info、query_elements、query_by_text、extract_text/links/table/form/meta/jsonld、extract_buttons_info、extract_all_anchors、get_whole_html- 选择器支持
#host >>> .inner语法穿透 shadow DOM;快照会返回元素是否在视口、是否被其他元素遮挡
- 选择器支持
- 页面交互(9):
click_element、hover_element、input_text、press_key、submit_form、set_checkbox、select_option、scroll_to、wait_for_element- 点击会依次派发 pointerover/mouseover/pointerdown/mousedown/pointerup/mouseup/click,兼容只监听 mousedown 的组件
- 写入走原生 value setter + InputEvent,React / Vue 受控组件同样生效
- 页面改写(7):
set_text、set_html、set_attribute、remove_elements、replace_whole_html、execute_script、assert_page_state - 通用工具(14):
http_request、web_fetch、set_storage/get_storage、encoding_convert、url_encode/decode、jwt_decode、jsonpath_query、regex_extract、random_*web_fetch抓取 http/https 网页并抽取正文,默认返回 Markdown(标题、列表、链接、代码块),支持纯文本 / 原始 HTML、字符上限、超时与域名白名单;无法访问浏览器内部页面与本地文件
- 编排与 SubAgent(4):
tool_list、batch_execute、subagents_list、subagent_run - 技能(3):
skills_list、skills_view、skills_read_file - 需在环境资源里显式勾选才会下发(13):
crypto_encrypt/decrypt、hash_digest、hmac_sign、rsa_*、mcp_service_*、mcp_tool_list、get_mcp_service
工具默认集只包含「操作浏览器」需要的能力;配置类与加解密类工具标记为 expose: admin,避免模型误用。每个工具标注了 readOnly,SubAgent 处于只读模式时只会拿到这 40 个只读工具。
环境管理
环境页沿用 awake-claw 的结构:左侧环境列表 + 右侧分页签编辑器,改动自动保存(文本 600ms 防抖,开关立即保存)。
- 环境资源:MCP / 技能 / 工具三类,各自带「自动包含新增资源」开关。开启时默认全部可用(加解密与 MCP 配置类工具仍需显式勾选),关闭后按勾选精确控制;默认生效的条目会标「自动包含」,关闭开关时会把当前生效状态固化成显式勾选,不会突然清空。
- 上下文四段:记忆、用户画像、人格、行为,各自可设字符上限,按「人格 → 画像 → 行为 → 记忆」顺序注入系统提示。
- SubAgent:总开关控制是否派发;列表始终可勾选,授权某个 SubAgent 会自动打开总开关,另提供「全部授权 / 全部取消 / 刷新列表」,未创建时给出跳转入口
- 预览:先保存当前配置,再按「系统环境 → 环境上下文 → 提示词 → 技能 → 工具规范 → 输出约束」生成完整提示
新建环境时可先填名称与四段上下文;重命名、删除都在编辑器右上角。
脚本执行与严格 CSP
execute_script 默认关闭,需在「设置 → 权限」显式开启。它先在页面主世界执行(能访问页面自己的 jQuery / React / Vue 实例):
- 普通页面:直接执行,返回可序列化结果
- 严格 CSP 页面(
script-src不含unsafe-eval):new Function会被拦截,此时自动回退到 CDPRuntime.evaluate,该通道不受页面 CSP 约束;可在设置中关闭「使用调试通道」,关闭后在严格 CSP 页面直接返回SCRIPT_CSP_BLOCKED debugger是 Chrome 的安装级权限(Chrome 不允许把它声明为可选权限,运行时permissions.request会报 “Only permissions specified in the manifest may be requested”),因此随扩展安装声明;修改清单后需在扩展管理页重新加载一次- 调试期间浏览器会显示「正在调试此浏览器」,执行结束立即断开;DevTools 已打开该标签页时无法 attach,会明确报错
技能库
技能库按 awake-claw 的卡片式管理:卡片显示启用状态、是否可用(缺 SKILL.md 会标红)、文件数与描述;「查看」为只读,「编辑」打开左侧文件树 + 右侧全文编辑,可新建子目录文件、删除文件;导出为 JSON。
导入只有一个入口:点击「导入」直接唤起目录选择,不再有二次确认弹窗。每个包含 SKILL.md 的目录生成一个技能,其余文件按相对路径保留(如 references/api.md);没有 SKILL.md 的单个 Markdown 各自成为技能;选中后立即写入并提示导入数量与被跳过的项,同名技能会被覆盖。
MCP 支持范围
| 传输 | 支持 | 说明 |
|---|---|---|
streamable_http |
✅ | 推荐,POST JSON-RPC 到服务端点 |
http |
✅ | GET /tools + POST /call 网关模式 |
sse |
✅ | endpoint 事件 + 消息端点,按 JSON-RPC id 对齐 |
stdio |
❌ | 浏览器扩展无法启动本地进程,保存时即被拒绝 |
界面沿用 awake-claw 的交互:卡片显示启用与连接状态(未测试 / 已连接 / 失败),编辑弹窗支持请求头逐行编辑与批量粘贴、保存前「测试连接」;「查看」弹窗分「工具 / 资源 / 提示词」三段,工具可展开 input_schema,并支持「测试全部」。
开发与验证
npm run build:background # 仅构建 service worker
npm run build:ui # 仅构建界面
npm test # 离线冒烟测试(fake-indexeddb + 桩 fetch)
npm run test:e2e # 真实 Chrome 端到端(需先 npm run build)
npm run test:ui # 真实 Chrome 逐页渲染与交互(需先 npm run build)
npm test 覆盖三段链路:
scripts/smoke.mjs—— 模块 CRUD、脱敏、唯一性校验、级联解绑、会话快照(含历史 Token 比例)、路由错误码(47 项断言)scripts/smoke_chat.mjs—— 流式输出、工具循环、事件落库、HTTP 错误处理(19 项断言)scripts/smoke_tools.mjs—— function calling 专项:工具不变量、环境工具开关、多轮tool_calls ↔ tool 结果配对、参数自我纠正、重复失败拦截、轮次上限收尾、模型重试、工具结果保留轮数、SubAgent 派发与只读约束、历史 Token 预算、web_fetch正文抽取与域名白名单、新增设置项、请求头批量解析、MCP 传输与调试通道配置、默认自动重试与累计计数(80 项断言)
npm run test:e2e 会安装未打包扩展、起一个桩模型服务,让模型按脚本下发 15 次工具调用,真实执行「读取标签页 → 快照 → 输入 → 按键 → 点击 → 脚本执行(含 CSP 回退)→ 新标签页 → 切换 → 关闭」,并对页面 DOM 做最终断言(32 项)。
npm run test:ui 在真实浏览器中逐页打开控制台,检查渲染与运行时错误,验证「新建会话」对话框、模型参数回显、设置保存、内容区独立滚动(页头固定)、供应商请求路径与请求头批量导入、环境 SubAgent 授权、技能目录导入、弹窗尺寸,以及桌面与 H5 两套事件线的结构与样式、H5 删除与清空(74 项)。
已知限制
- 界面产物未做 minify:当前沙箱环境 esbuild 压缩大 chunk 会异常退出;功能不受影响,可用
build.minify在正常环境开启 - 浏览器内部页面(
chrome://、edge://)无法注入脚本,工具会返回明确错误,并提示用open_tab打开普通网页 debugger为安装级权限,安装/更新扩展时 Chrome 会额外提示「调试此浏览器」;修改清单后需在扩展管理页重新加载才能生效- MCP 的
stdio与本地文件系统能力受浏览器安全模型限制,不可用(界面与接口均不提供该选项) web_fetch受同源策略与站点反爬限制:需要登录、Cloudflare 挑战或robots.txt禁止的页面可能抓不到;跨域请求依赖扩展的<all_urls>主机权限- 关闭弹窗会结束正在进行的一轮对话(长连接断开即取消),长任务请在控制台执行
- API Key 与 MCP 请求头以明文存放于扩展私有 IndexedDB(与 awake-claw 的 SQLite 存放方式一致),请勿在共享设备上使用生产密钥
execute_script的 CDP 回退通道按标签页整体求值,暂不支持指定frameId(用主世界通道时可传frameId)- 文件上传(
<input type="file">)无法通过 DOM 赋值伪造,需要 CDPDOM.setFileInputFiles,当前未提供对应工具