agentpage 0.0.10 → 0.0.12

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.
Files changed (2) hide show
  1. package/README.md +256 -232
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,25 +1,20 @@
1
1
  # AutoPilot
2
2
 
3
- > **浏览器内嵌 AI Agent SDK** — 让 AI 通过 tool-calling 操作你的网页。
3
+ > 浏览器内嵌 AI Agent SDK:让 AI 通过 tool-calling 操作网页。
4
4
 
5
5
  [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
6
6
 
7
- 一行代码给你的网站加上 AI Agent 能力:用户说一句话,AI 自动点击按钮、填写表单、读取数据、执行 JS。
8
-
9
- 基于原生 `fetch` 的纯浏览器 AI 客户端,支持 **OpenAI** / **GitHub Copilot** / **Anthropic**。唯一运行时依赖:`@sinclair/typebox`。
7
+ AutoPilot 的目标不是生成文本,而是在浏览器中完成真实任务:点击、填写、导航、等待、执行脚本,并在每一轮根据最新页面状态持续推进。
10
8
 
11
9
  ---
12
10
 
13
- ## 核心特性
11
+ ## 项目定位
14
12
 
15
- - **内嵌式 Agent** — 运行在页面内部,直接操作 DOM,无需截图、无需外部浏览器进程
16
- - **零 SDK 依赖** 使用原生 `fetch` 连接 AI,不引入 openai / anthropic SDK
17
- - **DOM 快照 + Ref 路径** — 自动生成页面结构快照,AI 通过 ref 路径精确定位元素,无需猜测选择器
18
- - **5 个内置工具** DOM 操作、页面导航、页面信息、等待元素、JS 执行
19
- - **可扩展** — 通过 `registerTool()` 添加自定义工具
20
- - **多轮记忆** — 可开关的对话历史,Agent 能记住上下文
21
- - **Chrome Extension 支持** — 内置 Service Worker ↔ Content Script 消息桥
22
- - **~2000 行** — 轻量、可审计、无黑箱
13
+ - 运行环境:浏览器(可扩展到 Chrome Extension)
14
+ - 核心机制:快照驱动 + 工具调用 + 增量消费
15
+ - 架构分层:
16
+ - `core`:环境无关引擎(Agent Loop、AI Client、Tool Registry)
17
+ - `web`:浏览器能力实现(DOM/导航/快照/等待/执行)
23
18
 
24
19
  ---
25
20
 
@@ -31,299 +26,328 @@
31
26
  pnpm install
32
27
  ```
33
28
 
34
- ### 使用
29
+ ### 基本使用
35
30
 
36
- ```typescript
37
- import { WebAgent } from "autopilot/web";
31
+ ```ts
32
+ import { WebAgent } from "agentpage";
38
33
 
39
34
  const agent = new WebAgent({
40
35
  token: "your-api-key",
41
- provider: "copilot", // "copilot" | "openai" | "anthropic"
42
- model: "gpt-4o",
43
- memory: true, // 开启多轮记忆
44
- autoSnapshot: true, // 每次对话前自动生成 DOM 快照(默认开启)
36
+ provider: "deepseek", // openai | copilot | anthropic | deepseek
37
+ model: "deepseek-chat",
38
+ memory: true,
39
+ autoSnapshot: true,
40
+ stream: true,
45
41
  });
46
42
 
47
- agent.registerTools(); // 注册 5 个内置 Web 工具
43
+ agent.registerTools();
48
44
 
49
45
  agent.callbacks = {
50
- onText: (text) => console.log("AI:", text),
51
- onToolCall: (name, input) => console.log("🔧", name),
52
- onToolResult: (name, result) => console.log("", name, result.content),
53
- onSnapshot: (snapshot) => console.log("📸 快照已生成"),
46
+ onRound: (round) => console.log("round", round + 1),
47
+ onToolCall: (name, input) => console.log("tool", name, input),
48
+ onToolResult: (name, result) => console.log("result", name, result.content),
49
+ onText: (text) => console.log("assistant", text),
54
50
  };
55
51
 
56
- const result = await agent.chat("把搜索框填上 'AutoPilot' 然后点搜索按钮");
52
+ const result = await agent.chat("打开任务弹窗,填写标题和优先级,然后提交");
57
53
  console.log(result.reply);
58
54
  ```
59
55
 
60
- ### 运行 Demo
56
+ ### 启动 Demo
61
57
 
62
58
  ```bash
63
- pnpm demo # 启动 Vite 开发服务器,端口 3000
59
+ pnpm demo
64
60
  ```
65
61
 
66
- Demo 页面提供开箱即用的聊天 UI(暗色主题),包含:
67
- - Token 输入(localStorage 持久化)
68
- - 模型选择(gpt-4o / gpt-4o-mini / o3-mini)
69
- - Dry-run 开关 & 多轮记忆开关
70
- - 6 个快捷测试按钮(页面信息、DOM 快照、点击、链接、滚动、DOM 计数)
71
- - 实时展示工具调用和结果
72
-
73
62
  ---
74
63
 
75
- ## 架构
64
+ ## 当前目录结构(权威)
76
65
 
77
- ```
66
+ ```text
78
67
  src/
79
- ├── core/ # 🔷 共享引擎(零环境依赖,纯 TypeScript + fetch)
80
- │ ├── types.ts # 类型:AIClient, AIMessage, AIChatResponse, AIToolCall
81
- │ ├── tool-registry.ts # ToolRegistry 类 + 辅助函数(readStringParam 等)
82
- │ ├── agent-loop.ts # 决策循环:executeAgentLoop()(ReAct 模式)
83
- │ ├── ai-client.ts # AI 客户端工厂:createAIClient()(纯 fetch)
84
- └── system-prompt.ts # 系统提示词构建:buildSystemPrompt()
85
-
86
- ├── web/ # 🌐 浏览器端 Agent(依赖 core)
87
- │ ├── index.ts # WebAgent 类 — 浏览器端 AI Agent 入口
88
- └── tools/
89
- ├── register.ts # registerWebTools(registry) — 注册 5 个工具
90
- ├── dom-tool.ts # DOM 操作:click, fill, type, get_text, get_attr...
91
- ├── navigate-tool.ts # 页面导航:goto, back, forward, reload, scroll
92
- ├── page-info-tool.ts # 页面信息与 DOM 快照:url, title, snapshot...
93
- ├── wait-tool.ts # 等待元素:waitForSelector(MutationObserver)
94
- │ ├── evaluate-tool.ts # JS 执行:在页面上下文中运行任意代码
95
- └── messaging.ts # Chrome Extension 消息桥(SW ↔ Content Script)
96
-
97
- demo/ # 🎨 Web Agent 演示
98
- ├── index.html # Chat UI(暗色主题 + 快捷测试按钮)
99
- ├── main.ts # WebAgent 实例 + UI 交互 + 回调绑定
68
+ ├── core/
69
+ │ ├── index.ts
70
+ │ ├── types.ts
71
+ │ ├── tool-params.ts
72
+ │ ├── tool-registry.ts
73
+ ├── system-prompt.ts
74
+ ├── agent-loop/
75
+ │ │ ├── index.ts
76
+ ├── types.ts
77
+ │ ├── constants.ts
78
+ ├── helpers.ts
79
+ ├── snapshot.ts
80
+ ├── messages.ts
81
+ │ └── recovery.ts
82
+ └── ai-client/
83
+ │ ├── index.ts
84
+ ├── constants.ts
85
+ ├── custom.ts
86
+ │ ├── openai.ts
87
+ ├── anthropic.ts
88
+ ├── deepseek.ts
89
+ │ └── sse.ts
90
+ └── web/
91
+ ├── index.ts
92
+ ├── dom-tool.ts # 兼容转发层(re-export)
93
+ ├── navigate-tool.ts # 兼容转发层(re-export)
94
+ ├── page-info-tool.ts # 兼容转发层(re-export)
95
+ ├── wait-tool.ts # 兼容转发层(re-export)
96
+ ├── evaluate-tool.ts # 兼容转发层(re-export)
97
+ ├── ref-store.ts
98
+ ├── messaging.ts
99
+ └── tools/
100
+ ├── dom-tool.ts
101
+ ├── navigate-tool.ts
102
+ ├── page-info-tool.ts
103
+ ├── wait-tool.ts
104
+ └── evaluate-tool.ts
100
105
  ```
101
106
 
102
- 两层结构:`core`(引擎,零环境依赖)+ `web`(浏览器工具 + DOM API),13 个源文件。
107
+ ---
103
108
 
104
- ### 设计原则
109
+ ## 核心原理
105
110
 
106
- | | 目录 | 依赖 | 环境 |
107
- |----|------|------|------|
108
- | **core** | `src/core/` | 无(纯 TypeScript + fetch) | 任意(浏览器 / Worker) |
109
- | **web** | `src/web/` | core + DOM API | 浏览器 |
111
+ ### 1) 快照驱动决策
110
112
 
111
- - `web/` 只从 `core/` 导入,`core/` 不含任何 DOM/Node API
112
- - ToolRegistry 是实例化的(非全局 Map),每个 Agent 拥有独立的工具集
113
- - 全链路「容错不中断」— 单个工具失败不会中止 Agent 循环
113
+ AI 每一轮不是“凭记忆猜页面”,而是基于最新快照选择可执行动作。
114
114
 
115
- ---
115
+ 快照包含:
116
+ - 元素标签与关键信息
117
+ - hash selector(如 `#a1b2c`)
118
+ - 结构化层级关系
119
+
120
+ ### 2) 任务增量消费
116
121
 
117
- ## AI Provider 支持
122
+ 用户任务会被分解成子任务,按轮次逐步“吃掉”:
118
123
 
119
- | Provider | 端点 | 认证头 |
120
- |----------|------|--------|
121
- | `copilot` | `https://models.inference.ai.azure.com` | `Authorization: Bearer <GitHub PAT>` |
122
- | `openai` | `https://api.openai.com/v1` | `Authorization: Bearer <API Key>` |
123
- | `anthropic` | `https://api.anthropic.com` | `x-api-key: <API Key>` |
124
+ - 轮次 N:做当前快照可满足的动作
125
+ - 工具执行后刷新快照
126
+ - 轮次 N+1:继续做剩余子任务
127
+ - 全部完成后返回总结文本
124
128
 
125
- 所有 provider 均使用原生 `fetch` 调用,支持 `baseURL` 自定义端点(如代理服务器)。
129
+ 新增(渐进式协议):
130
+ - 每轮都会显式携带 `Current remaining instruction`(当前剩余文本)
131
+ - 每轮都会携带 `Previous round planned task array`(上一轮执行计划)
132
+ - 模型可在文本中返回:
133
+ - `REMAINING: <剩余内容>`:表示还有任务要继续
134
+ - `REMAINING: DONE`:表示剩余任务已空
126
135
 
127
- ### 两层 API
136
+ ### 3) 批量但不跨变更链式执行
128
137
 
129
- **高层 API** — 一步到位:
138
+ 允许同轮批量执行多个“当前可见目标”的动作;
139
+ 不允许把“会导致新 DOM 出现”的后续动作强行塞进同轮。
130
140
 
131
- ```typescript
132
- import { createAIClient } from "autopilot/core/ai-client";
141
+ 例子:
142
+ - 可同轮:同时填写两个已可见输入框
143
+ - 不可同轮:点击“打开弹窗”后立即填写弹窗字段(应等下一轮新快照)
133
144
 
134
- const client = createAIClient({ provider: "copilot", model: "gpt-4o", apiKey: "ghp_xxx" });
135
- const response = await client.chat({ systemPrompt, messages, tools });
145
+ ---
146
+
147
+ ## 完整架构流程图(含链路)
148
+
149
+ ### A. 端到端主流程
150
+
151
+ ```mermaid
152
+ flowchart TD
153
+ U[用户输入任务] --> W[WebAgent.chat]
154
+ W --> P[构建 system prompt + 准备工具定义]
155
+ P --> L[executeAgentLoop]
156
+ L --> S[读取/刷新 latest snapshot]
157
+ S --> M[buildCompactMessages]
158
+ M --> C[AIClient.chat]
159
+ C --> D{是否返回 toolCalls}
160
+ D -->|是| X[ToolRegistry.dispatch 执行工具]
161
+ X --> T[写入 trace 与结果]
162
+ T --> S
163
+ D -->|否| F[输出最终总结并结束]
164
+ ```
165
+
166
+ ### B. 分层模块关系
167
+
168
+ ```mermaid
169
+ flowchart LR
170
+ subgraph Web[web 层]
171
+ WI[web/index.ts\nWebAgent]
172
+ WT[web tools]
173
+ RS[ref-store.ts]
174
+ MG[messaging.ts]
175
+ end
176
+
177
+ subgraph Core[core 层]
178
+ AL[agent-loop/*]
179
+ TR[tool-registry.ts]
180
+ SP[system-prompt.ts]
181
+ AI[ai-client/*]
182
+ end
183
+
184
+ WI --> AL
185
+ WI --> TR
186
+ WI --> SP
187
+ WI --> WT
188
+ WT --> RS
189
+ WI --> MG
190
+
191
+ AL --> AI
192
+ AL --> TR
136
193
  ```
137
194
 
138
- **底层 API** 自定义 fetch 逻辑(自定义 headers、超时、重试、代理等):
195
+ ### C. Agent Loop 轮次时序
196
+
197
+ ```mermaid
198
+ sequenceDiagram
199
+ participant User as User
200
+ participant Agent as WebAgent
201
+ participant Loop as AgentLoop
202
+ participant AI as AIClient
203
+ participant Tool as ToolRegistry
204
+
205
+ User->>Agent: chat(task)
206
+ Agent->>Loop: executeAgentLoop(...)
207
+ loop round 0..max
208
+ Loop->>Loop: read snapshot/context
209
+ Loop->>AI: compact messages + tools
210
+ AI-->>Loop: text/toolCalls
211
+ alt has toolCalls
212
+ Loop->>Tool: dispatch tool calls
213
+ Tool-->>Loop: results
214
+ Loop->>Loop: recovery + refresh snapshot
215
+ else final text
216
+ Loop-->>Agent: final reply
217
+ end
218
+ end
219
+ ```
139
220
 
140
- ```typescript
141
- import { buildChatRequest, parseChatResponse } from "autopilot/core/ai-client";
221
+ ---
142
222
 
143
- const config = { provider: "copilot", model: "gpt-4o", apiKey: "ghp_xxx" };
144
- const req = buildChatRequest(config, { systemPrompt, messages, tools });
223
+ ## Agent Loop 细节
145
224
 
146
- // 自定义修改请求
147
- req.headers["X-Custom"] = "value";
225
+ 主流程位于 `src/core/agent-loop/index.ts`:
148
226
 
149
- // 自行 fetch 并解析
150
- const { url, ...init } = req;
151
- const res = await fetch(url, init);
152
- const data = await res.json();
153
- const response = parseChatResponse(config.provider, data);
154
- ```
227
+ 1. 确保当前快照可用
228
+ 2. 构建紧凑消息(原始目标 + done steps + 最新快照)
229
+ 3. 调用 AI
230
+ 4. 执行工具调用并记录 trace
231
+ 5. 运行保护机制
232
+ 6. 刷新快照并进入下一轮
233
+
234
+ ### 渐进式执行状态(新增)
235
+
236
+ `src/core/agent-loop/index.ts` 内部维护 3 个关键状态:
237
+ - `remainingInstruction`:当前轮次待消费文本(初始值为用户原始输入)
238
+ - `previousRoundTasks`:上一轮执行任务数组
239
+ - `lastPlannedBatchKey`:用于识别是否连续两轮给出完全相同的任务批次
240
+
241
+ 停机规则:
242
+ - 若模型返回无工具调用 → 直接结束
243
+ - 若连续两轮规划出相同任务批次,且上一轮无错误 → 自动终止,防止自转
244
+ - 若模型文本包含 `REMAINING: DONE`,通常下一轮会自然进入“无工具调用总结”并结束
245
+
246
+ ### 紧凑消息结构
247
+
248
+ 由 `messages.ts` 构建,核心语义:
249
+ - Master goal:用户原始任务(永远保留)
250
+ - Done steps:已完成动作(避免重复)
251
+ - Execution context + latest snapshot:当前可执行范围
252
+
253
+ ### 快照生命周期
254
+
255
+ 由 `snapshot.ts` 管理:
256
+ - 读取快照
257
+ - 包裹快照边界
258
+ - 去重历史快照
259
+ - 剥离旧 prompt 快照
155
260
 
156
261
  ---
157
262
 
158
- ## 工具一览
263
+ ## 保护机制
159
264
 
160
- | 工具 | 动作 | 说明 |
161
- |------|------|------|
162
- | **dom** | `click`, `fill`, `type`, `get_text`, `get_attr`, `set_attr`, `add_class`, `remove_class` | DOM 操作(支持 ref 路径和 CSS 选择器) |
163
- | **navigate** | `goto`, `back`, `forward`, `reload`, `scroll` | 页面导航 |
164
- | **page_info** | `get_url`, `get_title`, `get_selection`, `get_viewport`, `snapshot`, `query_all` | 页面信息与 DOM 快照 |
165
- | **wait** | `wait_for_selector`, `wait_for_hidden`, `wait_for_text` | 等待元素变化(MutationObserver) |
166
- | **evaluate** | *expression* | 执行任意 JavaScript(`new Function`) |
265
+ `recovery.ts` 提供:
167
266
 
168
- ### DOM 快照与 Ref 路径
267
+ - 冗余 `page_info` 拦截:减少无意义工具调用
268
+ - 元素找不到恢复:自动等待并刷新快照
269
+ - 导航 URL 变化检测:更新上下文,防止旧定位污染
270
+ - 空转检测:避免循环无进展
271
+ - 重复批次防自转:连续返回同一批任务时自动停止
169
272
 
170
- 这是 AutoPilot 的核心设计 — 让 AI **精确定位** DOM 元素,无需猜测 CSS 选择器。
273
+ 这些机制直接决定“调用次数、成功率、稳定性”。
171
274
 
172
- `generateSnapshot()` 将 DOM 树转为 AI 可理解的文本描述,每个元素自动生成基于层级位置的 ref 路径:
275
+ ---
173
276
 
174
- ```
175
- [header] ref="/body/header"
176
- [nav] ref="/body/header/nav"
177
- [a] "首页" href="/" ref="/body/header/nav/a[1]"
178
- [a] "关于" href="/about" ref="/body/header/nav/a[2]"
179
- [main] ref="/body/main"
180
- [h1] "欢迎" ref="/body/main/h1"
181
- [input] type="text" placeholder="搜索..." ref="/body/main/input"
182
- [button] "搜索" id="search-btn" onclick ref="/body/main/button"
183
- ```
277
+ ## AI Client 设计
278
+
279
+ `src/core/ai-client/` 提供统一接口,内部按 provider 适配:
184
280
 
185
- AI 使用 ref 路径调用 `dom` 工具,`resolveRef()` 在运行时将路径解析回 DOM 元素。采集的信息包括:id、class、交互属性、布尔状态、事件绑定、data-\* 属性、实时 value。
281
+ - `openai.ts`:OpenAI / Copilot 协议
282
+ - `anthropic.ts`:Anthropic 协议
283
+ - `deepseek.ts`:DeepSeek 协议
284
+ - `sse.ts`:流式事件解析
186
285
 
187
- ### 添加自定义工具
286
+ 统一输出为 `AIChatResponse`,上层 loop 无需关心 provider 差异。
188
287
 
189
- ```typescript
288
+ ---
289
+
290
+ ## Web 工具体系
291
+
292
+ 内置 5 个工具(`src/web/*.ts`):
293
+
294
+ 1. `dom`:点击、填写、输入等交互
295
+ 2. `navigate`:跳转、前进后退、滚动
296
+ 3. `page_info`:URL/标题/快照/查询
297
+ 4. `wait`:等待元素或文本条件
298
+ 5. `evaluate`:执行页面上下文 JS
299
+
300
+ 通过 `ToolRegistry` 统一暴露给模型,执行结果标准化返回。
301
+
302
+ ---
303
+
304
+ ## 扩展与自定义
305
+
306
+ ### 注册自定义工具
307
+
308
+ ```ts
190
309
  import { Type } from "@sinclair/typebox";
191
310
 
192
311
  agent.registerTool({
193
312
  name: "my_tool",
194
- description: "描述这个工具做什么",
313
+ description: "业务工具说明",
195
314
  schema: Type.Object({
196
- param: Type.String({ description: "参数说明" }),
315
+ value: Type.String(),
197
316
  }),
198
317
  async execute(params) {
199
- return { content: "执行结果" };
318
+ return { content: `ok: ${params.value}` };
200
319
  },
201
320
  });
202
321
  ```
203
322
 
204
- ---
205
-
206
- ## API
207
-
208
- ### `WebAgent`
323
+ ### Chrome Extension 模式
209
324
 
210
- ```typescript
211
- new WebAgent(options: WebAgentOptions)
212
- ```
213
-
214
- **配置选项:**
215
-
216
- | 选项 | 类型 | 默认值 | 说明 |
217
- |------|------|--------|------|
218
- | `token` | `string` | 必填 | API Key(GitHub PAT / OpenAI key / Anthropic key) |
219
- | `provider` | `string` | `"copilot"` | AI 提供商:`"copilot"` \| `"openai"` \| `"anthropic"` |
220
- | `model` | `string` | `"gpt-4o"` | 模型名称 |
221
- | `baseURL` | `string` | — | 自定义 API 基础 URL |
222
- | `dryRun` | `boolean` | `false` | 干运行(只打印工具调用不执行) |
223
- | `systemPrompt` | `string` | — | 自定义系统提示词(不传则使用默认) |
224
- | `maxRounds` | `number` | `10` | 最大工具调用轮次 |
225
- | `memory` | `boolean` | `false` | 多轮对话记忆开关 |
226
- | `autoSnapshot` | `boolean` | `true` | 每次 chat 前自动生成 DOM 快照 |
227
-
228
- **方法:**
229
-
230
- | 方法 | 说明 |
231
- |------|------|
232
- | `registerTools()` | 注册 5 个内置 Web 工具 |
233
- | `registerTool(tool)` | 注册自定义工具 |
234
- | `getTools()` | 获取所有已注册工具定义 |
235
- | `chat(message)` | 发送消息,返回 `AgentLoopResult` |
236
- | `setToken(token)` | 更新 API Key |
237
- | `setProvider(provider)` | 更新 AI 提供商 |
238
- | `setModel(model)` | 更新模型 |
239
- | `setDryRun(enabled)` | 切换干运行模式 |
240
- | `setSystemPrompt(prompt)` | 设置自定义系统提示词 |
241
- | `setMemory(enabled)` | 开关多轮记忆(关闭时自动清空历史) |
242
- | `getMemory()` | 获取当前记忆开关状态 |
243
- | `setAutoSnapshot(enabled)` | 开关自动快照 |
244
- | `getAutoSnapshot()` | 获取当前自动快照开关 |
245
- | `clearHistory()` | 清空对话历史(不影响记忆开关) |
246
-
247
- **回调(`callbacks`):**
248
-
249
- | 回调 | 触发时机 |
250
- |------|---------|
251
- | `onRound(round)` | 每轮循环开始(round 从 0 开始) |
252
- | `onText(text)` | AI 返回文本回复 |
253
- | `onToolCall(name, input)` | AI 请求调用工具(执行前) |
254
- | `onToolResult(name, result)` | 工具执行完成 |
255
- | `onSnapshot(snapshot)` | 自动快照生成完成 |
256
-
257
- ### `AgentLoopResult`
258
-
259
- `chat()` 返回值:
260
-
261
- ```typescript
262
- {
263
- reply: string; // AI 的最终文本回复
264
- toolCalls: Array<{ // 所有工具调用记录
265
- name: string;
266
- input: unknown;
267
- result: ToolCallResult;
268
- }>;
269
- messages: AIMessage[]; // 完整对话消息(用于多轮记忆累积)
270
- }
271
- ```
325
+ `web/messaging.ts` 提供消息桥:
326
+ - Service Worker 发起工具调用
327
+ - Content Script 执行 DOM 工具
328
+ - 回传结果给后台 Agent
272
329
 
273
330
  ---
274
331
 
275
- ## Chrome Extension 支持
276
-
277
- AutoPilot 内置 Service Worker ↔ Content Script 消息桥,解决 Chrome Extension 的作用域隔离:
278
-
279
- ```
280
- Service Worker (后台) Content Script (页面)
281
- ┌──────────────────┐ ┌──────────────────────┐
282
- │ AI Agent 核心 │ AUTOPILOT_TOOL_CALL │ DOM 操作执行 │
283
- │ createProxy │ ────────────────► │ registerToolHandler │
284
- │ Executor() │ │ │
285
- │ │ AUTOPILOT_TOOL_RESULT│ │
286
- │ │ ◄──────────────── │ │
287
- └──────────────────┘ └──────────────────────┘
288
- ```
289
-
290
- ```typescript
291
- // Service Worker 端
292
- import { createProxyExecutor } from "agentpage";
293
- const execute = createProxyExecutor();
332
+ ## 设计约束(必须遵守)
294
333
 
295
- // Content Script
296
- import { registerToolHandler } from "agentpage";
297
- registerToolHandler(executorMap);
298
- ```
334
+ - `web` 只依赖 `core`,`core` 不依赖 DOM API
335
+ - ToolRegistry 必须实例化,禁止全局单例污染
336
+ - 工具失败应返回可消费结果,不应直接中断主循环
337
+ - 消息策略与系统提示必须一致(否则会增加无效 completion)
299
338
 
300
339
  ---
301
340
 
302
- ## 开发
341
+ ## 开发命令
303
342
 
304
343
  ```bash
305
- pnpm install # 安装依赖
306
- pnpm build # 构建产物(tsdown → dist/)
307
- pnpm check # 类型检查(tsc --noEmit)+ lint(oxlint)
308
- pnpm lint # 代码检查(oxlint)
309
- pnpm format # 代码格式化(oxfmt --write)
310
- pnpm format:check # 检查格式(oxfmt --check,不修改)
311
- pnpm demo # 启动 Demo(Vite,端口 3000)
312
- pnpm test # 运行测试(vitest run,单次执行)
313
- pnpm test:watch # 运行测试(vitest watch 模式)
344
+ pnpm install
345
+ pnpm check
346
+ pnpm test
347
+ pnpm demo
348
+ pnpm build
314
349
  ```
315
350
 
316
- ### 工具链
317
-
318
- | 工具 | 用途 |
319
- |------|------|
320
- | **tsdown** | 构建打包(产出 `dist/`) |
321
- | **oxlint** | 代码检查(替代 ESLint) |
322
- | **oxfmt** | 代码格式化(替代 Prettier) |
323
- | **vitest** | 测试框架(覆盖率阈值 60%) |
324
- | **vite** | Demo 开发服务器 |
325
- | **TypeScript 5.9+** | 严格模式,`module: NodeNext` |
326
-
327
351
  ---
328
352
 
329
353
  ## License
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentpage",
3
- "version": "0.0.10",
3
+ "version": "0.0.12",
4
4
  "description": "Embeddable AI Agent SDK for browsers — let AI operate your web pages via tool-calling",
5
5
  "keywords": [
6
6
  "ai",