agentpage 0.0.1
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/README.md +331 -0
- package/dist/index.d.mts +320 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +1987 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +53 -0
package/README.md
ADDED
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
# AutoPilot
|
|
2
|
+
|
|
3
|
+
> **浏览器内嵌 AI Agent SDK** — 让 AI 通过 tool-calling 操作你的网页。
|
|
4
|
+
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
|
|
7
|
+
一行代码给你的网站加上 AI Agent 能力:用户说一句话,AI 自动点击按钮、填写表单、读取数据、执行 JS。
|
|
8
|
+
|
|
9
|
+
基于原生 `fetch` 的纯浏览器 AI 客户端,支持 **OpenAI** / **GitHub Copilot** / **Anthropic**。唯一运行时依赖:`@sinclair/typebox`。
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 核心特性
|
|
14
|
+
|
|
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 行** — 轻量、可审计、无黑箱
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 快速开始
|
|
27
|
+
|
|
28
|
+
### 安装
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pnpm install
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### 使用
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import { WebAgent } from "autopilot/web";
|
|
38
|
+
|
|
39
|
+
const agent = new WebAgent({
|
|
40
|
+
token: "your-api-key",
|
|
41
|
+
provider: "copilot", // "copilot" | "openai" | "anthropic"
|
|
42
|
+
model: "gpt-4o",
|
|
43
|
+
memory: true, // 开启多轮记忆
|
|
44
|
+
autoSnapshot: true, // 每次对话前自动生成 DOM 快照(默认开启)
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
agent.registerTools(); // 注册 5 个内置 Web 工具
|
|
48
|
+
|
|
49
|
+
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("📸 快照已生成"),
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const result = await agent.chat("把搜索框填上 'AutoPilot' 然后点搜索按钮");
|
|
57
|
+
console.log(result.reply);
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 运行 Demo
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
pnpm demo # 启动 Vite 开发服务器,端口 3000
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Demo 页面提供开箱即用的聊天 UI(暗色主题),包含:
|
|
67
|
+
- Token 输入(localStorage 持久化)
|
|
68
|
+
- 模型选择(gpt-4o / gpt-4o-mini / o3-mini)
|
|
69
|
+
- Dry-run 开关 & 多轮记忆开关
|
|
70
|
+
- 6 个快捷测试按钮(页面信息、DOM 快照、点击、链接、滚动、DOM 计数)
|
|
71
|
+
- 实时展示工具调用和结果
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## 架构
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
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 交互 + 回调绑定
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
两层结构:`core`(引擎,零环境依赖)+ `web`(浏览器工具 + DOM API),13 个源文件。
|
|
103
|
+
|
|
104
|
+
### 设计原则
|
|
105
|
+
|
|
106
|
+
| 层 | 目录 | 依赖 | 环境 |
|
|
107
|
+
|----|------|------|------|
|
|
108
|
+
| **core** | `src/core/` | 无(纯 TypeScript + fetch) | 任意(浏览器 / Worker) |
|
|
109
|
+
| **web** | `src/web/` | core + DOM API | 浏览器 |
|
|
110
|
+
|
|
111
|
+
- `web/` 只从 `core/` 导入,`core/` 不含任何 DOM/Node API
|
|
112
|
+
- ToolRegistry 是实例化的(非全局 Map),每个 Agent 拥有独立的工具集
|
|
113
|
+
- 全链路「容错不中断」— 单个工具失败不会中止 Agent 循环
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## AI Provider 支持
|
|
118
|
+
|
|
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
|
+
|
|
125
|
+
所有 provider 均使用原生 `fetch` 调用,支持 `baseURL` 自定义端点(如代理服务器)。
|
|
126
|
+
|
|
127
|
+
### 两层 API
|
|
128
|
+
|
|
129
|
+
**高层 API** — 一步到位:
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
import { createAIClient } from "autopilot/core/ai-client";
|
|
133
|
+
|
|
134
|
+
const client = createAIClient({ provider: "copilot", model: "gpt-4o", apiKey: "ghp_xxx" });
|
|
135
|
+
const response = await client.chat({ systemPrompt, messages, tools });
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**底层 API** — 自定义 fetch 逻辑(自定义 headers、超时、重试、代理等):
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
import { buildChatRequest, parseChatResponse } from "autopilot/core/ai-client";
|
|
142
|
+
|
|
143
|
+
const config = { provider: "copilot", model: "gpt-4o", apiKey: "ghp_xxx" };
|
|
144
|
+
const req = buildChatRequest(config, { systemPrompt, messages, tools });
|
|
145
|
+
|
|
146
|
+
// 自定义修改请求
|
|
147
|
+
req.headers["X-Custom"] = "value";
|
|
148
|
+
|
|
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
|
+
```
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## 工具一览
|
|
159
|
+
|
|
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`) |
|
|
167
|
+
|
|
168
|
+
### DOM 快照与 Ref 路径
|
|
169
|
+
|
|
170
|
+
这是 AutoPilot 的核心设计 — 让 AI **精确定位** DOM 元素,无需猜测 CSS 选择器。
|
|
171
|
+
|
|
172
|
+
`generateSnapshot()` 将 DOM 树转为 AI 可理解的文本描述,每个元素自动生成基于层级位置的 ref 路径:
|
|
173
|
+
|
|
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
|
+
```
|
|
184
|
+
|
|
185
|
+
AI 使用 ref 路径调用 `dom` 工具,`resolveRef()` 在运行时将路径解析回 DOM 元素。采集的信息包括:id、class、交互属性、布尔状态、事件绑定、data-\* 属性、实时 value。
|
|
186
|
+
|
|
187
|
+
### 添加自定义工具
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
import { Type } from "@sinclair/typebox";
|
|
191
|
+
|
|
192
|
+
agent.registerTool({
|
|
193
|
+
name: "my_tool",
|
|
194
|
+
description: "描述这个工具做什么",
|
|
195
|
+
schema: Type.Object({
|
|
196
|
+
param: Type.String({ description: "参数说明" }),
|
|
197
|
+
}),
|
|
198
|
+
async execute(params) {
|
|
199
|
+
return { content: "执行结果" };
|
|
200
|
+
},
|
|
201
|
+
});
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## API
|
|
207
|
+
|
|
208
|
+
### `WebAgent`
|
|
209
|
+
|
|
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
|
+
```
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
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();
|
|
294
|
+
|
|
295
|
+
// Content Script 端
|
|
296
|
+
import { registerToolHandler } from "agentpage";
|
|
297
|
+
registerToolHandler(executorMap);
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
## 开发
|
|
303
|
+
|
|
304
|
+
```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 模式)
|
|
314
|
+
```
|
|
315
|
+
|
|
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
|
+
---
|
|
328
|
+
|
|
329
|
+
## License
|
|
330
|
+
|
|
331
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
import { TObject } from "@sinclair/typebox";
|
|
2
|
+
|
|
3
|
+
//#region src/core/tool-registry.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* 工具执行结果 — 每个工具的 execute() 必须返回此类型。
|
|
6
|
+
*/
|
|
7
|
+
type ToolCallResult = {
|
|
8
|
+
/** 返回内容(字符串文本或结构化对象,最终会序列化后发给 AI) */content: string | Record<string, unknown>; /** 可选的额外细节(用于日志记录、调试等,不直接发给 AI) */
|
|
9
|
+
details?: Record<string, unknown>;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* 工具定义 — 注册工具时需要提供的完整描述。
|
|
13
|
+
*
|
|
14
|
+
* 这四个字段分别告诉 AI「叫什么名字」「能做什么」「需要什么参数」「怎么执行」:
|
|
15
|
+
* - name + description → AI 根据用户意图选择合适的工具
|
|
16
|
+
* - schema → AI 生成符合格式的参数 JSON
|
|
17
|
+
* - execute → 实际执行逻辑
|
|
18
|
+
*/
|
|
19
|
+
type ToolDefinition = {
|
|
20
|
+
/** 工具名称(AI 通过此名称调用,如 "exec"、"file_read") */name: string; /** 工具描述(AI 据此判断何时使用这个工具) */
|
|
21
|
+
description: string; /** 参数的 JSON Schema(TypeBox 定义,描述工具接受哪些参数及其类型) */
|
|
22
|
+
schema: TObject; /** 执行函数 — 接收 AI 传入的参数,返回执行结果 */
|
|
23
|
+
execute: (params: Record<string, unknown>) => Promise<ToolCallResult>;
|
|
24
|
+
};
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region src/core/types.d.ts
|
|
27
|
+
/** AI 模型返回的工具调用指令 */
|
|
28
|
+
type AIToolCall = {
|
|
29
|
+
/** 调用 ID(用于将结果关联回此次调用) */id: string; /** 工具名称(如 "dom"、"page_info") */
|
|
30
|
+
name: string; /** AI 传入的参数 */
|
|
31
|
+
input: unknown;
|
|
32
|
+
};
|
|
33
|
+
/** 对话消息(统一格式,支持 user / assistant / tool / system 角色) */
|
|
34
|
+
type AIMessage = {
|
|
35
|
+
role: "user" | "assistant" | "tool" | "system"; /** 文本内容,或工具执行结果数组 */
|
|
36
|
+
content: string | Array<{
|
|
37
|
+
toolCallId: string;
|
|
38
|
+
result: string;
|
|
39
|
+
}>; /** assistant 消息中附带的工具调用列表 */
|
|
40
|
+
toolCalls?: AIToolCall[];
|
|
41
|
+
};
|
|
42
|
+
/** AI 聊天接口的返回值 */
|
|
43
|
+
type AIChatResponse = {
|
|
44
|
+
/** AI 的文本回复 */text?: string; /** AI 请求的工具调用列表 */
|
|
45
|
+
toolCalls?: AIToolCall[]; /** Token 使用统计 */
|
|
46
|
+
usage?: {
|
|
47
|
+
inputTokens: number;
|
|
48
|
+
outputTokens: number;
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* AI 客户端抽象接口。
|
|
53
|
+
*
|
|
54
|
+
* 通过 createAIClient() 工厂函数创建,基于原生 fetch 实现。
|
|
55
|
+
*/
|
|
56
|
+
type AIClient = {
|
|
57
|
+
chat(params: {
|
|
58
|
+
systemPrompt: string;
|
|
59
|
+
messages: AIMessage[];
|
|
60
|
+
tools?: ToolDefinition[];
|
|
61
|
+
}): Promise<AIChatResponse>;
|
|
62
|
+
};
|
|
63
|
+
//#endregion
|
|
64
|
+
//#region src/core/agent-loop/index.d.ts
|
|
65
|
+
/** 工具调用事件回调 — 用于 UI 层实时展示 Agent 进度 */
|
|
66
|
+
type AgentLoopCallbacks = {
|
|
67
|
+
/** AI 返回文本回复时触发 */onText?: (text: string) => void; /** AI 请求调用工具时触发(执行前) */
|
|
68
|
+
onToolCall?: (name: string, input: unknown) => void; /** 工具执行完成时触发 */
|
|
69
|
+
onToolResult?: (name: string, result: ToolCallResult) => void; /** 每轮循环开始时触发(round 从 0 开始) */
|
|
70
|
+
onRound?: (round: number) => void;
|
|
71
|
+
};
|
|
72
|
+
type AgentLoopResult = {
|
|
73
|
+
/** AI 的最终文本回复 */reply: string; /** 所有工具调用记录 */
|
|
74
|
+
toolCalls: Array<{
|
|
75
|
+
name: string;
|
|
76
|
+
input: unknown;
|
|
77
|
+
result: ToolCallResult;
|
|
78
|
+
}>; /** 本轮完整对话消息(含历史 + 本轮,用于多轮记忆累积) */
|
|
79
|
+
messages: AIMessage[];
|
|
80
|
+
};
|
|
81
|
+
//#endregion
|
|
82
|
+
//#region src/web/page-info-tool.d.ts
|
|
83
|
+
/** 快照配置选项 */
|
|
84
|
+
type SnapshotOptions = {
|
|
85
|
+
/** 最大遍历深度(默认 6) */maxDepth?: number;
|
|
86
|
+
/**
|
|
87
|
+
* 视口裁剪:只保留与视口相交的元素(默认 true)。
|
|
88
|
+
* 开启后,完全在视口外的元素会被跳过,大幅减少 token 消耗。
|
|
89
|
+
* 注意:祖先容器即使自身不在视口内,只要有子元素在视口内就会保留。
|
|
90
|
+
*/
|
|
91
|
+
viewportOnly?: boolean;
|
|
92
|
+
/**
|
|
93
|
+
* 智能剪枝:折叠无意义的纯布局容器(默认 true)。
|
|
94
|
+
* 开启后,没有文本、没有 id、没有交互属性的纯布局元素(div/span/section 等)
|
|
95
|
+
* 如果自身无意义,会被折叠——子元素直接提升到父级输出,减少嵌套噪音。
|
|
96
|
+
*/
|
|
97
|
+
pruneLayout?: boolean;
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* 生成页面 DOM 快照 — 将 DOM 树转为 AI 可理解的文本描述。
|
|
101
|
+
*
|
|
102
|
+
* 类似 Playwright 的 ariaSnapshot(),但基于 Web API 实现。
|
|
103
|
+
* 只遍历可见元素,跳过 script/style/svg 等无意义节点。
|
|
104
|
+
*
|
|
105
|
+
* 每个元素自动生成基于层级位置的 XPath 引用(ref),
|
|
106
|
+
* AI 可以通过 ref 精确定位元素,无需猜测 CSS 选择器。
|
|
107
|
+
*
|
|
108
|
+
* 输出格式示例:
|
|
109
|
+
* [header] ref="/body/header"
|
|
110
|
+
* [nav] ref="/body/header/nav"
|
|
111
|
+
* [a] "首页" href="/" ref="/body/header/nav/a[1]"
|
|
112
|
+
* [a] "关于" href="/about" ref="/body/header/nav/a[2]"
|
|
113
|
+
* [main] ref="/body/main"
|
|
114
|
+
* [h1] "欢迎来到示例网站" ref="/body/main/h1"
|
|
115
|
+
* [input] type="text" placeholder="搜索..." ref="/body/main/input"
|
|
116
|
+
* [button] "搜索" id="search-btn" onclick ref="/body/main/button"
|
|
117
|
+
*
|
|
118
|
+
* 增强信息:
|
|
119
|
+
* - id:元素的 id 属性
|
|
120
|
+
* - placeholder:输入框的占位文本
|
|
121
|
+
* - 事件绑定:onclick/onchange 等内联事件处理器
|
|
122
|
+
* - 状态属性:disabled/checked/readonly/required 等
|
|
123
|
+
*
|
|
124
|
+
* @param root - 快照根元素(默认 document.body)
|
|
125
|
+
* @param options - 快照选项对象,或传入数字作为 maxDepth(向后兼容)
|
|
126
|
+
*/
|
|
127
|
+
declare function generateSnapshot(root?: Element, options?: SnapshotOptions | number): string;
|
|
128
|
+
declare function createPageInfoTool(): ToolDefinition;
|
|
129
|
+
//#endregion
|
|
130
|
+
//#region src/web/dom-tool.d.ts
|
|
131
|
+
declare function createDomTool(): ToolDefinition;
|
|
132
|
+
//#endregion
|
|
133
|
+
//#region src/web/navigate-tool.d.ts
|
|
134
|
+
declare function createNavigateTool(): ToolDefinition;
|
|
135
|
+
//#endregion
|
|
136
|
+
//#region src/web/wait-tool.d.ts
|
|
137
|
+
declare function createWaitTool(): ToolDefinition;
|
|
138
|
+
//#endregion
|
|
139
|
+
//#region src/web/evaluate-tool.d.ts
|
|
140
|
+
declare function createEvaluateTool(): ToolDefinition;
|
|
141
|
+
//#endregion
|
|
142
|
+
//#region src/web/messaging.d.ts
|
|
143
|
+
/**
|
|
144
|
+
* Web Tools 消息通信桥接层。
|
|
145
|
+
*
|
|
146
|
+
* 解决 Chrome Extension 的作用域隔离问题:
|
|
147
|
+
*
|
|
148
|
+
* Service Worker (后台) Content Script (页面)
|
|
149
|
+
* ┌──────────────────┐ ┌──────────────────────┐
|
|
150
|
+
* │ agent-core │ │ document / window │
|
|
151
|
+
* │ tool-registry │ chrome.tabs │ │
|
|
152
|
+
* │ │ .sendMessage() │ DOM 操作实际执行 │
|
|
153
|
+
* │ tool.execute() │ ─────────────────► │ handleToolMessage() │
|
|
154
|
+
* │ ↓ │ │ ↓ │
|
|
155
|
+
* │ sendToContent() │ ◄───────────────── │ 返回执行结果 │
|
|
156
|
+
* └──────────────────┘ response └──────────────────────┘
|
|
157
|
+
*
|
|
158
|
+
* 使用方式:
|
|
159
|
+
* Service Worker 端:
|
|
160
|
+
* import { createProxyExecutor } from "./messaging.js";
|
|
161
|
+
* const execute = createProxyExecutor();
|
|
162
|
+
* // execute 会把调用转发到 content script
|
|
163
|
+
*
|
|
164
|
+
* Content Script 端:
|
|
165
|
+
* import { registerToolHandler } from "./messaging.js";
|
|
166
|
+
* registerToolHandler(actualExecutors);
|
|
167
|
+
* // 监听来自 service worker 的工具调用请求
|
|
168
|
+
*/
|
|
169
|
+
/** Service Worker → Content Script 的工具调用请求 */
|
|
170
|
+
type ToolCallMessage = {
|
|
171
|
+
type: "AUTOPILOT_TOOL_CALL";
|
|
172
|
+
toolName: string;
|
|
173
|
+
params: Record<string, unknown>;
|
|
174
|
+
callId: string;
|
|
175
|
+
};
|
|
176
|
+
/** Content Script → Service Worker 的工具调用结果 */
|
|
177
|
+
type ToolCallResponse = {
|
|
178
|
+
type: "AUTOPILOT_TOOL_RESULT";
|
|
179
|
+
callId: string;
|
|
180
|
+
result: {
|
|
181
|
+
content: string | Record<string, unknown>;
|
|
182
|
+
details?: Record<string, unknown>;
|
|
183
|
+
};
|
|
184
|
+
};
|
|
185
|
+
/**
|
|
186
|
+
* 创建代理执行器 — 在 Service Worker 端使用。
|
|
187
|
+
*
|
|
188
|
+
* 它不直接执行 DOM 操作,而是通过 chrome.tabs.sendMessage
|
|
189
|
+
* 把调用请求发给当前活动 tab 的 content script 执行。
|
|
190
|
+
*
|
|
191
|
+
* @returns execute 函数,签名与 ToolDefinition.execute 相同
|
|
192
|
+
*/
|
|
193
|
+
declare function createProxyExecutor(): (toolName: string, params: Record<string, unknown>) => Promise<{
|
|
194
|
+
content: string | Record<string, unknown>;
|
|
195
|
+
details?: Record<string, unknown>;
|
|
196
|
+
}>;
|
|
197
|
+
/** 工具执行器映射:toolName → execute 函数 */
|
|
198
|
+
type ToolExecutorMap = Map<string, (params: Record<string, unknown>) => Promise<{
|
|
199
|
+
content: string | Record<string, unknown>;
|
|
200
|
+
details?: Record<string, unknown>;
|
|
201
|
+
}>>;
|
|
202
|
+
/**
|
|
203
|
+
* 在 Content Script 端注册工具执行处理器。
|
|
204
|
+
*
|
|
205
|
+
* 监听来自 Service Worker 的 AUTOPILOT_TOOL_CALL 消息,
|
|
206
|
+
* 根据 toolName 找到对应的执行函数,执行后返回结果。
|
|
207
|
+
*
|
|
208
|
+
* @param executors 工具名称 → 执行函数的映射
|
|
209
|
+
*/
|
|
210
|
+
declare function registerToolHandler(executors: ToolExecutorMap): void;
|
|
211
|
+
//#endregion
|
|
212
|
+
//#region src/web/index.d.ts
|
|
213
|
+
/** WebAgent 事件回调(扩展 AgentLoopCallbacks,增加快照事件) */
|
|
214
|
+
type WebAgentCallbacks = AgentLoopCallbacks & {
|
|
215
|
+
/** 自动快照生成完成时触发 */onSnapshot?: (snapshot: string) => void;
|
|
216
|
+
};
|
|
217
|
+
type WebAgentOptions = {
|
|
218
|
+
/**
|
|
219
|
+
* 自定义 AI 客户端实例(可选)。
|
|
220
|
+
*
|
|
221
|
+
* 传入后将直接使用该实例进行对话,忽略 token / provider / model / baseURL。
|
|
222
|
+
* 支持 BaseAIClient 或任何实现 AIClient 接口的对象。
|
|
223
|
+
*
|
|
224
|
+
* ```ts
|
|
225
|
+
* const client = new BaseAIClient({ chatHandler: async (params) => { ... } });
|
|
226
|
+
* const agent = new WebAgent({ client });
|
|
227
|
+
* ```
|
|
228
|
+
*/
|
|
229
|
+
client?: AIClient; /** API 认证 Token (GitHub PAT / OpenAI key / Anthropic key) */
|
|
230
|
+
token?: string; /** AI 提供商: "copilot" | "openai" | "anthropic"(默认 "copilot") */
|
|
231
|
+
provider?: string; /** 模型名称(默认 "gpt-4o") */
|
|
232
|
+
model?: string; /** 自定义 API 基础 URL(可选,覆盖 provider 默认值) */
|
|
233
|
+
baseURL?: string; /** 是否启用干运行模式 */
|
|
234
|
+
dryRun?: boolean; /** 自定义系统提示词(不传则使用默认 Web 提示词) */
|
|
235
|
+
systemPrompt?: string; /** 最大工具调用轮次(默认 10) */
|
|
236
|
+
maxRounds?: number; /** 是否启用多轮对话记忆(默认 false) */
|
|
237
|
+
memory?: boolean; /** 是否在每次对话前自动生成页面快照(默认 true) */
|
|
238
|
+
autoSnapshot?: boolean; /** 快照选项(视口裁剪、智能剪枝等,autoSnapshot 开启时生效) */
|
|
239
|
+
snapshotOptions?: SnapshotOptions;
|
|
240
|
+
};
|
|
241
|
+
declare class WebAgent {
|
|
242
|
+
/** 用户传入的自定义 AI 客户端实例(优先级高于 token/provider) */
|
|
243
|
+
private client?;
|
|
244
|
+
private token;
|
|
245
|
+
private provider;
|
|
246
|
+
private model;
|
|
247
|
+
private baseURL?;
|
|
248
|
+
private dryRun;
|
|
249
|
+
private maxRounds;
|
|
250
|
+
private customSystemPrompt?;
|
|
251
|
+
/** 多轮对话记忆开关 */
|
|
252
|
+
private memory;
|
|
253
|
+
/** 对话历史(memory 开启时自动累积) */
|
|
254
|
+
private history;
|
|
255
|
+
/** 自动快照开关 */
|
|
256
|
+
private autoSnapshot;
|
|
257
|
+
/** 快照选项 */
|
|
258
|
+
private snapshotOptions;
|
|
259
|
+
/** 工具注册表实例 — 每个 WebAgent 拥有独立的工具集 */
|
|
260
|
+
private registry;
|
|
261
|
+
/** 事件回调 — 绑定后可实时获取 Agent 进度,用于 UI 展示 */
|
|
262
|
+
callbacks: WebAgentCallbacks;
|
|
263
|
+
constructor(options: WebAgentOptions);
|
|
264
|
+
/** 注册所有内置 Web 工具(dom, navigate, page_info, wait, evaluate) */
|
|
265
|
+
registerTools(): void;
|
|
266
|
+
/** 注册一个自定义工具 */
|
|
267
|
+
registerTool(tool: ToolDefinition): void;
|
|
268
|
+
/** 获取所有已注册的工具定义列表 */
|
|
269
|
+
getTools(): ToolDefinition[];
|
|
270
|
+
/** 设置 API Token */
|
|
271
|
+
setToken(token: string): void;
|
|
272
|
+
/**
|
|
273
|
+
* 设置自定义 AI 客户端实例。
|
|
274
|
+
*
|
|
275
|
+
* 传入后将优先使用该实例进行对话,忽略 token / provider / model / baseURL。
|
|
276
|
+
* 传入 undefined 可恢复使用内置客户端。
|
|
277
|
+
*/
|
|
278
|
+
setClient(client: AIClient | undefined): void;
|
|
279
|
+
/** 设置 AI 提供商 */
|
|
280
|
+
setProvider(provider: string): void;
|
|
281
|
+
/** 设置模型 */
|
|
282
|
+
setModel(model: string): void;
|
|
283
|
+
/** 切换干运行模式 */
|
|
284
|
+
setDryRun(enabled: boolean): void;
|
|
285
|
+
/** 设置自定义系统提示词 */
|
|
286
|
+
setSystemPrompt(prompt: string): void;
|
|
287
|
+
/** 开启或关闭多轮对话记忆 */
|
|
288
|
+
setMemory(enabled: boolean): void;
|
|
289
|
+
/** 获取当前记忆开关状态 */
|
|
290
|
+
getMemory(): boolean;
|
|
291
|
+
/** 开启或关闭自动快照 */
|
|
292
|
+
setAutoSnapshot(enabled: boolean): void;
|
|
293
|
+
/** 获取当前自动快照开关状态 */
|
|
294
|
+
getAutoSnapshot(): boolean;
|
|
295
|
+
/** 设置快照选项(视口裁剪、智能剪枝等) */
|
|
296
|
+
setSnapshotOptions(options: SnapshotOptions): void;
|
|
297
|
+
/** 获取当前快照选项 */
|
|
298
|
+
getSnapshotOptions(): SnapshotOptions;
|
|
299
|
+
/** 清空对话历史(不影响记忆开关) */
|
|
300
|
+
clearHistory(): void;
|
|
301
|
+
/**
|
|
302
|
+
* 发送消息并获取 AI 回复(含完整工具调用循环)。
|
|
303
|
+
*
|
|
304
|
+
* 内部流程(全部复用 core):
|
|
305
|
+
* 1. createAIClient() → 创建 fetch AI 客户端
|
|
306
|
+
* 2. buildSystemPrompt() → 构建系统提示词
|
|
307
|
+
* 3. executeAgentLoop() → 执行决策循环
|
|
308
|
+
* 4. callbacks → 实时通知 UI
|
|
309
|
+
*/
|
|
310
|
+
chat(message: string): Promise<AgentLoopResult>;
|
|
311
|
+
/**
|
|
312
|
+
* 创建内置 AI 客户端(基于 token / provider / model 配置)。
|
|
313
|
+
*
|
|
314
|
+
* @throws 未设置 token 时抛出 Error
|
|
315
|
+
*/
|
|
316
|
+
private createBuiltinClient;
|
|
317
|
+
}
|
|
318
|
+
//#endregion
|
|
319
|
+
export { type SnapshotOptions, type ToolCallMessage, type ToolCallResponse, type ToolExecutorMap, WebAgent, WebAgentCallbacks, WebAgentOptions, createDomTool, createEvaluateTool, createNavigateTool, createPageInfoTool, createProxyExecutor, createWaitTool, generateSnapshot, registerToolHandler };
|
|
320
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/core/tool-registry.ts","../src/core/types.ts","../src/core/agent-loop/index.ts","../src/web/page-info-tool.ts","../src/web/dom-tool.ts","../src/web/navigate-tool.ts","../src/web/wait-tool.ts","../src/web/evaluate-tool.ts","../src/web/messaging.ts","../src/web/index.ts"],"mappings":";;;;;;KA0BY,cAAA;EAuBV,qCArBA,OAAA,WAAkB,MAAA,mBAqBR;EAnBV,OAAA,GAAU,MAAA;AAAA;;;;;;ACfZ;;;KD0BY,cAAA;ECxBV,4CD0BA,IAAA,UCtBA;EDwBA,WAAA,UCxBK;ED0BL,MAAA,EAAQ,OAAA,ECpBW;EDsBnB,OAAA,GAAU,MAAA,EAAQ,MAAA,sBAA4B,OAAA,CAAQ,cAAA;AAAA;;;;KClC5C,UAAA;ED0BA,0BCxBV,EAAA;EAEA,IAAA,UD8BkB;EC5BlB,KAAA;AAAA;;KAMU,SAAA;EACV,IAAA,4CDiBA;ECfA,OAAA,WAAkB,KAAA;IAAQ,UAAA;IAAoB,MAAA;EAAA,IDmBpC;ECjBV,SAAA,GAAY,UAAA;AAAA;;KAMF,cAAA;iBAEV,IAAA;EAEA,SAAA,GAAY,UAAA,IA3BQ;EA6BpB,KAAA;IAAU,WAAA;IAAqB,YAAA;EAAA;AAAA;;;AAjBjC;;;KA2BY,QAAA;EACV,IAAA,CAAK,MAAA;IACH,YAAA;IACA,QAAA,EAAU,SAAA;IACV,KAAA,GAAQ,cAAA;EAAA,IACN,OAAA,CAAQ,cAAA;AAAA;;;;KCnBF,kBAAA;EFS2C,mBEPrD,MAAA,IAAU,IAAA,mBFGV;EEDA,UAAA,IAAc,IAAA,UAAc,KAAA,oBFGpB;EEDR,YAAA,IAAgB,IAAA,UAAc,MAAA,EAAQ,cAAA,WFGpB;EEDlB,OAAA,IAAW,KAAA;AAAA;AAAA,KAwBD,eAAA;ED5CV,iBC8CA,KAAA,UD5CkB;EC8ClB,SAAA,EAAW,KAAA;IAAQ,IAAA;IAAc,KAAA;IAAgB,MAAA,EAAQ,cAAA;EAAA,ID5CnC;EC8CtB,QAAA,EAAU,SAAA;AAAA;;;;KC5DA,eAAA;EHQA,mBGNV,QAAA;;;;;;EAMA,YAAA;EHIgB;;AAWlB;;;EGTE,WAAA;AAAA;;;;;;;;;;;;;;;;;;;AFjBF;;;;;;;;;AAYA;iBEoCgB,gBAAA,CACd,IAAA,GAAM,OAAA,EACN,OAAA,GAAS,eAAA;AAAA,iBAoPK,kBAAA,CAAA,GAAsB,cAAA;;;iBChJtB,aAAA,CAAA,GAAiB,cAAA;;;iBCrJjB,kBAAA,CAAA,GAAsB,cAAA;;;iBCmHtB,cAAA,CAAA,GAAkB,cAAA;;;iBCjElB,kBAAA,CAAA,GAAsB,cAAA;;;;;;APxCtC;;;;;;;;;;AAeA;;;;;;;;;;;;;;KQXY,eAAA;EACV,IAAA;EACA,QAAA;EACA,MAAA,EAAQ,MAAA;EACR,MAAA;AAAA;;KAIU,gBAAA;EACV,IAAA;EACA,MAAA;EACA,MAAA;IACE,OAAA,WAAkB,MAAA;IAClB,OAAA,GAAU,MAAA;EAAA;AAAA;;;;APhBd;;;;;iBO8BgB,mBAAA,CAAA,IAEZ,QAAA,UACA,MAAA,EAAQ,MAAA,sBACP,OAAA;EAAU,OAAA,WAAkB,MAAA;EAAyB,OAAA,GAAU,MAAA;AAAA;;KAgCxD,eAAA,GAAkB,GAAA,UAE3B,MAAA,EAAQ,MAAA,sBAA4B,OAAA;EACnC,OAAA,WAAkB,MAAA;EAClB,OAAA,GAAU,MAAA;AAAA;;;;;;;;;iBAYE,mBAAA,CAAoB,SAAA,EAAW,eAAA;;;;KC5DnC,iBAAA,GAAoB,kBAAA;oBAE9B,UAAA,IAAc,QAAA;AAAA;AAAA,KAKJ,eAAA;ERzCU;;;;;;AAYtB;;;;;EQyCE,MAAA,GAAS,QAAA,ERtCS;EQwClB,KAAA,WRxC8C;EQ0C9C,QAAA,WRxCY;EQ0CZ,KAAA,WR1CsB;EQ4CtB,OAAA,WRtCwB;EQwCxB,MAAA,YRpCsB;EQsCtB,YAAA,WRtCA;EQwCA,SAAA,WRtCA;EQwCA,MAAA,YRxC+B;EQ0C/B,YAAA,YR1C2C;EQ4C3C,eAAA,GAAkB,eAAA;AAAA;AAAA,cAKP,QAAA;ERpCC;EAAA,QQsCJ,MAAA;EAAA,QACA,KAAA;EAAA,QACA,QAAA;EAAA,QACA,KAAA;EAAA,QACA,OAAA;EAAA,QACA,MAAA;EAAA,QACA,SAAA;EAAA,QACA,kBAAA;ER7CI;EAAA,QQgDJ,MAAA;ER/CE;EAAA,QQiDF,OAAA;ERhDJ;EAAA,QQkDI,YAAA;ERlDkB;EAAA,QQoDlB,eAAA;;UAGA,QAAA;;EAGR,SAAA,EAAW,iBAAA;cAEC,OAAA,EAAS,eAAA;;EAiBrB,aAAA,CAAA;EP9FA;EOuGA,YAAA,CAAa,IAAA,EAAM,cAAA;EPrGnB;EO0GA,QAAA,CAAA,GAAY,cAAA;EP1GgB;EOiH5B,QAAA,CAAS,KAAA;EP/GO;;;;;;EOyHhB,SAAA,CAAU,MAAA,EAAQ,QAAA;EP/FR;EOoGV,WAAA,CAAY,QAAA;;EAKZ,QAAA,CAAS,KAAA;EPrGE;EO0GX,SAAA,CAAU,OAAA;EPxGS;EO6GnB,eAAA,CAAgB,MAAA;EPjHhB;EOsHA,SAAA,CAAU,OAAA;EPpHC;EO0HX,SAAA,CAAA;EP1HiC;EO+HjC,eAAA,CAAgB,OAAA;EP/HyC;EOoIzD,eAAA,CAAA;EPlIU;EOuIV,kBAAA,CAAmB,OAAA,EAAS,eAAA;EPvIT;EO4InB,kBAAA,CAAA,GAAsB,eAAA;;EAKtB,YAAA,CAAA;EN7MU;;;;;;;;;EM4NJ,IAAA,CAAK,OAAA,WAAkB,OAAA,CAAQ,eAAA;EN/KP;;;;;EAAA,QMgPtB,mBAAA;AAAA"}
|