zan-browser 2.0.8 → 3.0.0
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/dist/agent/agent.d.ts +42 -0
- package/dist/agent/agent.d.ts.map +1 -0
- package/dist/agent/agent.js +157 -0
- package/dist/agent/agent.js.map +1 -0
- package/dist/agent/conversation.d.ts +22 -0
- package/dist/agent/conversation.d.ts.map +1 -0
- package/dist/agent/conversation.js +47 -0
- package/dist/agent/conversation.js.map +1 -0
- package/dist/agent/prompt.d.ts +3 -0
- package/dist/agent/prompt.d.ts.map +1 -0
- package/dist/agent/prompt.js +73 -0
- package/dist/agent/prompt.js.map +1 -0
- package/dist/browser.d.ts +0 -1
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +2 -10
- package/dist/browser.js.map +1 -1
- package/dist/index.d.ts +19 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +35 -3
- package/dist/index.js.map +1 -1
- package/dist/observer.d.ts +5 -1
- package/dist/observer.d.ts.map +1 -1
- package/dist/observer.js +23 -3
- package/dist/observer.js.map +1 -1
- package/dist/registry.d.ts +20 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +69 -0
- package/dist/registry.js.map +1 -0
- package/dist/session.d.ts +12 -27
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +74 -206
- package/dist/session.js.map +1 -1
- package/dist/tools/base.d.ts +37 -0
- package/dist/tools/base.d.ts.map +1 -0
- package/dist/tools/base.js +6 -0
- package/dist/tools/base.js.map +1 -0
- package/dist/tools/browser/click.d.ts +8 -0
- package/dist/tools/browser/click.d.ts.map +1 -0
- package/dist/tools/browser/click.js +42 -0
- package/dist/tools/browser/click.js.map +1 -0
- package/dist/tools/browser/eval_js.d.ts +8 -0
- package/dist/tools/browser/eval_js.d.ts.map +1 -0
- package/dist/tools/browser/eval_js.js +46 -0
- package/dist/tools/browser/eval_js.js.map +1 -0
- package/dist/tools/browser/fill.d.ts +8 -0
- package/dist/tools/browser/fill.d.ts.map +1 -0
- package/dist/tools/browser/fill.js +48 -0
- package/dist/tools/browser/fill.js.map +1 -0
- package/dist/tools/browser/navigate.d.ts +8 -0
- package/dist/tools/browser/navigate.d.ts.map +1 -0
- package/dist/tools/browser/navigate.js +40 -0
- package/dist/tools/browser/navigate.js.map +1 -0
- package/dist/tools/browser/screenshot.d.ts +8 -0
- package/dist/tools/browser/screenshot.d.ts.map +1 -0
- package/dist/tools/browser/screenshot.js +27 -0
- package/dist/tools/browser/screenshot.js.map +1 -0
- package/dist/tools/browser/scroll.d.ts +8 -0
- package/dist/tools/browser/scroll.d.ts.map +1 -0
- package/dist/tools/browser/scroll.js +36 -0
- package/dist/tools/browser/scroll.js.map +1 -0
- package/dist/tools/browser/wait.d.ts +8 -0
- package/dist/tools/browser/wait.d.ts.map +1 -0
- package/dist/tools/browser/wait.js +27 -0
- package/dist/tools/browser/wait.js.map +1 -0
- package/dist/tools/network/download_file.d.ts +8 -0
- package/dist/tools/network/download_file.d.ts.map +1 -0
- package/dist/tools/network/download_file.js +68 -0
- package/dist/tools/network/download_file.js.map +1 -0
- package/dist/tools/network/fetch_url.d.ts +8 -0
- package/dist/tools/network/fetch_url.d.ts.map +1 -0
- package/dist/tools/network/fetch_url.js +68 -0
- package/dist/tools/network/fetch_url.js.map +1 -0
- package/dist/tools/network/read_network_logs.d.ts +8 -0
- package/dist/tools/network/read_network_logs.d.ts.map +1 -0
- package/dist/tools/network/read_network_logs.js +64 -0
- package/dist/tools/network/read_network_logs.js.map +1 -0
- package/dist/tools/network/web_search.d.ts +8 -0
- package/dist/tools/network/web_search.d.ts.map +1 -0
- package/dist/tools/network/web_search.js +63 -0
- package/dist/tools/network/web_search.js.map +1 -0
- package/dist/tools/page/extract_dom.d.ts +8 -0
- package/dist/tools/page/extract_dom.d.ts.map +1 -0
- package/dist/tools/page/extract_dom.js +37 -0
- package/dist/tools/page/extract_dom.js.map +1 -0
- package/dist/tools/page/observe.d.ts +8 -0
- package/dist/tools/page/observe.d.ts.map +1 -0
- package/dist/tools/page/observe.js +37 -0
- package/dist/tools/page/observe.js.map +1 -0
- package/dist/tools/page/scrape.d.ts +8 -0
- package/dist/tools/page/scrape.d.ts.map +1 -0
- package/dist/tools/page/scrape.js +75 -0
- package/dist/tools/page/scrape.js.map +1 -0
- package/package.json +1 -1
package/dist/session.js
CHANGED
|
@@ -1,69 +1,77 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
// ─── Session — simplified ────────────────────────────────────────────────────
|
|
3
|
+
// Creates the tool registry, wires up context, and delegates work to the Agent.
|
|
4
|
+
// No longer contains interaction logic — that lives in individual tools.
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.Session = void 0;
|
|
4
7
|
const interceptor_1 = require("./interceptor");
|
|
5
8
|
const observer_1 = require("./observer");
|
|
9
|
+
const registry_1 = require("./registry");
|
|
10
|
+
const agent_1 = require("./agent/agent");
|
|
11
|
+
// ─── Browser tools ───────────────────────────────────────────────────────────
|
|
12
|
+
const click_1 = require("./tools/browser/click");
|
|
13
|
+
const fill_1 = require("./tools/browser/fill");
|
|
14
|
+
const scroll_1 = require("./tools/browser/scroll");
|
|
15
|
+
const navigate_1 = require("./tools/browser/navigate");
|
|
16
|
+
const wait_1 = require("./tools/browser/wait");
|
|
17
|
+
const eval_js_1 = require("./tools/browser/eval_js");
|
|
18
|
+
const screenshot_1 = require("./tools/browser/screenshot");
|
|
19
|
+
// ─── Page tools ──────────────────────────────────────────────────────────────
|
|
20
|
+
const observe_1 = require("./tools/page/observe");
|
|
21
|
+
const scrape_1 = require("./tools/page/scrape");
|
|
22
|
+
const extract_dom_1 = require("./tools/page/extract_dom");
|
|
23
|
+
// ─── Network tools ──────────────────────────────────────────────────────────
|
|
24
|
+
const web_search_1 = require("./tools/network/web_search");
|
|
25
|
+
const fetch_url_1 = require("./tools/network/fetch_url");
|
|
26
|
+
const download_file_1 = require("./tools/network/download_file");
|
|
27
|
+
const read_network_logs_1 = require("./tools/network/read_network_logs");
|
|
6
28
|
class Session {
|
|
7
29
|
page;
|
|
8
30
|
browserHandle;
|
|
9
31
|
interceptor;
|
|
10
32
|
observer;
|
|
11
|
-
|
|
33
|
+
registry;
|
|
34
|
+
ctx;
|
|
12
35
|
defaultTimeout;
|
|
36
|
+
aiModel;
|
|
13
37
|
viewerUrl;
|
|
14
|
-
constructor(page, browserHandle,
|
|
38
|
+
constructor(page, browserHandle, anthropicApiKey, timeout = 30_000, viewerUrl, aiModel) {
|
|
15
39
|
this.page = page;
|
|
16
40
|
this.browserHandle = browserHandle;
|
|
17
|
-
this.ai = ai;
|
|
18
41
|
this.defaultTimeout = timeout;
|
|
19
42
|
this.viewerUrl = viewerUrl;
|
|
43
|
+
this.aiModel = aiModel;
|
|
20
44
|
this.interceptor = new interceptor_1.Interceptor(page);
|
|
21
45
|
this.observer = new observer_1.Observer(page);
|
|
22
46
|
// Start capturing traffic immediately — t=0
|
|
23
47
|
this.interceptor.start();
|
|
48
|
+
// Build tool context
|
|
49
|
+
this.ctx = {
|
|
50
|
+
page,
|
|
51
|
+
observer: this.observer,
|
|
52
|
+
interceptor: this.interceptor,
|
|
53
|
+
anthropicApiKey,
|
|
54
|
+
aiModel,
|
|
55
|
+
};
|
|
56
|
+
// Register all tools
|
|
57
|
+
this.registry = new registry_1.ToolRegistry();
|
|
58
|
+
this.registerDefaultTools();
|
|
24
59
|
}
|
|
25
|
-
// ─── Accessors for SmartNavigator ───────────────────────────────────────────
|
|
26
|
-
getPage() { return this.page; }
|
|
27
|
-
getInterceptor() { return this.interceptor; }
|
|
28
|
-
getObserver() { return this.observer; }
|
|
29
|
-
getAI() { return this.ai; }
|
|
30
60
|
// ─── Navigation ───────────────────────────────────────────────────────────────
|
|
31
61
|
async goto(url, options) {
|
|
32
62
|
const timeout = options?.timeout ?? this.defaultTimeout;
|
|
33
|
-
await this.page.goto(url, {
|
|
34
|
-
waitUntil: "domcontentloaded",
|
|
35
|
-
timeout,
|
|
36
|
-
});
|
|
37
|
-
// Wait for network to go idle — catches XHR that SPAs fire after DOM is parsed.
|
|
63
|
+
await this.page.goto(url, { waitUntil: "domcontentloaded", timeout });
|
|
38
64
|
try {
|
|
39
65
|
await this.page.waitForNetworkIdle({ timeout: 8_000 });
|
|
40
66
|
}
|
|
41
67
|
catch {
|
|
42
|
-
// networkidle timed out — page likely has background polling
|
|
68
|
+
// networkidle timed out — page likely has background polling
|
|
43
69
|
}
|
|
44
|
-
// Minimum 800ms after networkidle (or timeout) — some SPAs fire XHR slightly after idle
|
|
45
70
|
await this.page.waitForTimeout(800);
|
|
46
71
|
}
|
|
47
|
-
async wait(ms) {
|
|
48
|
-
await this.page.waitForTimeout(ms);
|
|
49
|
-
}
|
|
50
72
|
get url() {
|
|
51
73
|
return this.page.url();
|
|
52
74
|
}
|
|
53
|
-
// ─── Observe — always first, before any action ────────────────────────────────
|
|
54
|
-
async observe() {
|
|
55
|
-
return this.observer.observe();
|
|
56
|
-
}
|
|
57
|
-
// ─── Form and autocomplete detection ────────────────────────────────────────
|
|
58
|
-
async detectForms() {
|
|
59
|
-
return this.observer.detectForms();
|
|
60
|
-
}
|
|
61
|
-
async detectAutocomplete() {
|
|
62
|
-
return this.observer.detectAutocomplete();
|
|
63
|
-
}
|
|
64
|
-
async detectErrors() {
|
|
65
|
-
return this.observer.detectErrors();
|
|
66
|
-
}
|
|
67
75
|
// ─── Screenshot ────────────────────────────────────────────────────────────────
|
|
68
76
|
async screenshot() {
|
|
69
77
|
const result = await this.page.screenshot({ type: "jpeg", quality: 80, encoding: "base64" });
|
|
@@ -73,69 +81,6 @@ class Session {
|
|
|
73
81
|
timestamp: Date.now(),
|
|
74
82
|
};
|
|
75
83
|
}
|
|
76
|
-
// ─── DOM text extraction — fallback when no useful XHR is captured ────────────
|
|
77
|
-
async extractPageContent() {
|
|
78
|
-
return await this.page.evaluate(() => {
|
|
79
|
-
const clone = document.body.cloneNode(true);
|
|
80
|
-
clone.querySelectorAll("script,style,nav,footer,header")
|
|
81
|
-
.forEach((el) => el.remove());
|
|
82
|
-
return clone.innerText
|
|
83
|
-
.split("\n")
|
|
84
|
-
.map((l) => l.trim())
|
|
85
|
-
.filter((l) => l.length > 0)
|
|
86
|
-
.join("\n")
|
|
87
|
-
.slice(0, 15000);
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
// ─── Interaction ──────────────────────────────────────────────────────────────
|
|
91
|
-
async clickById(elementId) {
|
|
92
|
-
// First try cached CSS selector (reliable)
|
|
93
|
-
const selector = this.observer.getSelector(elementId);
|
|
94
|
-
if (selector) {
|
|
95
|
-
try {
|
|
96
|
-
await this.page.click(selector);
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
catch {
|
|
100
|
-
// Fall through to coordinate-based click
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
const coords = await this.observer.resolveElementId(elementId);
|
|
104
|
-
if (!coords)
|
|
105
|
-
throw new Error(`Element ${elementId} not found in DOM`);
|
|
106
|
-
await this.page.mouse.click(coords.x, coords.y);
|
|
107
|
-
}
|
|
108
|
-
async fillById(elementId, value) {
|
|
109
|
-
// First try cached CSS selector (reliable)
|
|
110
|
-
const selector = this.observer.getSelector(elementId);
|
|
111
|
-
if (selector) {
|
|
112
|
-
try {
|
|
113
|
-
await this.page.click(selector, { clickCount: 3 }); // select all
|
|
114
|
-
await this.page.keyboard.press("Backspace");
|
|
115
|
-
await this.page.type(selector, value, { delay: 80 });
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
catch {
|
|
119
|
-
// Fall through to coordinate-based fill
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
const coords = await this.observer.resolveElementId(elementId);
|
|
123
|
-
if (!coords)
|
|
124
|
-
throw new Error(`Element ${elementId} not found in DOM`);
|
|
125
|
-
await this.page.mouse.click(coords.x, coords.y);
|
|
126
|
-
await this.page.keyboard.press("Control+a");
|
|
127
|
-
await this.page.keyboard.type(value, { delay: 80 });
|
|
128
|
-
}
|
|
129
|
-
// ─── Direct selector interaction (for autocomplete clicks) ──────────────────
|
|
130
|
-
async clickSelector(selector) {
|
|
131
|
-
const el = await this.page.waitForSelector(selector, { timeout: 3_000, visible: true });
|
|
132
|
-
if (el) {
|
|
133
|
-
await el.click();
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
throw new Error(`Selector ${selector} not found`);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
84
|
// ─── Captured requests ────────────────────────────────────────────────────────
|
|
140
85
|
getCapturedRequests() {
|
|
141
86
|
return this.interceptor.getAll();
|
|
@@ -143,60 +88,23 @@ class Session {
|
|
|
143
88
|
getUsefulRequests(minScore = 1) {
|
|
144
89
|
return this.interceptor.getUseful(minScore);
|
|
145
90
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
91
|
+
// ─── Agent — the main entry point ─────────────────────────────────────────────
|
|
92
|
+
async act(goal, config) {
|
|
93
|
+
const agent = new agent_1.AgentLoop(this.registry, this.ctx, this.aiModel);
|
|
94
|
+
return agent.run({
|
|
95
|
+
goal,
|
|
96
|
+
maxSteps: config?.maxSteps ?? 15,
|
|
97
|
+
seedValues: config?.seedValues,
|
|
98
|
+
onProgress: config?.onProgress,
|
|
99
|
+
...config,
|
|
100
|
+
});
|
|
151
101
|
}
|
|
152
|
-
|
|
153
|
-
|
|
102
|
+
// ─── Registry access (for custom tools) ────────────────────────────────────────
|
|
103
|
+
getRegistry() {
|
|
104
|
+
return this.registry;
|
|
154
105
|
}
|
|
155
|
-
|
|
156
|
-
this.
|
|
157
|
-
}
|
|
158
|
-
// ─── act() — achieve a goal through multi-step navigation ────────────────────
|
|
159
|
-
async act(goal, maxSteps = 10, seedValues) {
|
|
160
|
-
const steps = [];
|
|
161
|
-
const history = [];
|
|
162
|
-
for (let i = 0; i < maxSteps; i++) {
|
|
163
|
-
const observation = await this.observe();
|
|
164
|
-
let action;
|
|
165
|
-
let usedScreenshot = false;
|
|
166
|
-
if (observation.elements.filter((e) => e.visible).length > 0) {
|
|
167
|
-
action = await this.ai.decideFromObservation(goal, observation, history, seedValues);
|
|
168
|
-
}
|
|
169
|
-
else {
|
|
170
|
-
const shot = await this.screenshot();
|
|
171
|
-
action = await this.ai.decideFromScreenshot(goal, shot.base64, history, seedValues);
|
|
172
|
-
usedScreenshot = true;
|
|
173
|
-
}
|
|
174
|
-
steps.push({ action, observeBefore: observation, usedScreenshot });
|
|
175
|
-
history.push(`Step ${i + 1}: ${action.type} — ${action.reason}`);
|
|
176
|
-
if (action.type === "done") {
|
|
177
|
-
return { success: true, steps, finalUrl: this.url, reason: action.reason };
|
|
178
|
-
}
|
|
179
|
-
if (action.type === "impossible") {
|
|
180
|
-
return { success: false, steps, finalUrl: this.url, reason: action.reason };
|
|
181
|
-
}
|
|
182
|
-
await this.executeAction(action);
|
|
183
|
-
await this.page.waitForTimeout(500);
|
|
184
|
-
}
|
|
185
|
-
return {
|
|
186
|
-
success: false,
|
|
187
|
-
steps,
|
|
188
|
-
finalUrl: this.url,
|
|
189
|
-
reason: `Reached max steps (${maxSteps}) without completing goal`,
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
// ─── findData() — navigate + capture requests until goal achieved ─────────────
|
|
193
|
-
async findData(goal, maxSteps = 15, seedValues) {
|
|
194
|
-
const actResult = await this.act(goal, maxSteps, seedValues);
|
|
195
|
-
const capturedRequests = this.interceptor.getUseful();
|
|
196
|
-
return {
|
|
197
|
-
...actResult,
|
|
198
|
-
capturedRequests,
|
|
199
|
-
};
|
|
106
|
+
getToolContext() {
|
|
107
|
+
return this.ctx;
|
|
200
108
|
}
|
|
201
109
|
// ─── Cleanup ──────────────────────────────────────────────────────────────────
|
|
202
110
|
async close() {
|
|
@@ -209,65 +117,25 @@ class Session {
|
|
|
209
117
|
this.interceptor.stop();
|
|
210
118
|
await this.browserHandle.close();
|
|
211
119
|
}
|
|
212
|
-
// ───
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
window.scrollBy(0, direction === "down" ? amount : -amount);
|
|
232
|
-
}, { direction: action.direction, amount: action.amount ?? 300 }).catch(() => {
|
|
233
|
-
// Execution context destroyed = page navigated mid-scroll
|
|
234
|
-
});
|
|
235
|
-
break;
|
|
236
|
-
case "navigate":
|
|
237
|
-
this.interceptor.markActionTimestamp();
|
|
238
|
-
try {
|
|
239
|
-
await this.page.goto(action.url, { waitUntil: "domcontentloaded", timeout: this.defaultTimeout });
|
|
240
|
-
// Wait for network idle like Session.goto() does
|
|
241
|
-
try {
|
|
242
|
-
await this.page.waitForNetworkIdle({ timeout: 8_000 });
|
|
243
|
-
}
|
|
244
|
-
catch { /* background polling — continue */ }
|
|
245
|
-
await this.page.waitForTimeout(800);
|
|
246
|
-
}
|
|
247
|
-
catch (err) {
|
|
248
|
-
console.warn(`[Session] Navigate failed for ${action.url}:`, err.message);
|
|
249
|
-
}
|
|
250
|
-
break;
|
|
251
|
-
case "wait":
|
|
252
|
-
await this.page.waitForTimeout(action.ms);
|
|
253
|
-
break;
|
|
254
|
-
case "eval_js":
|
|
255
|
-
try {
|
|
256
|
-
await this.page.evaluate((jsCode) => {
|
|
257
|
-
// eslint-disable-next-line no-new-func
|
|
258
|
-
const fn = new Function(`return (${jsCode})`);
|
|
259
|
-
return fn();
|
|
260
|
-
}, action.code);
|
|
261
|
-
}
|
|
262
|
-
catch {
|
|
263
|
-
// result not captured in the legacy act() path
|
|
264
|
-
}
|
|
265
|
-
break;
|
|
266
|
-
case "screenshot":
|
|
267
|
-
break;
|
|
268
|
-
default:
|
|
269
|
-
break;
|
|
270
|
-
}
|
|
120
|
+
// ─── Private ──────────────────────────────────────────────────────────────────
|
|
121
|
+
registerDefaultTools() {
|
|
122
|
+
// Browser
|
|
123
|
+
this.registry.register(new click_1.ClickTool());
|
|
124
|
+
this.registry.register(new fill_1.FillTool());
|
|
125
|
+
this.registry.register(new scroll_1.ScrollTool());
|
|
126
|
+
this.registry.register(new navigate_1.NavigateTool());
|
|
127
|
+
this.registry.register(new wait_1.WaitTool());
|
|
128
|
+
this.registry.register(new eval_js_1.EvalJsTool());
|
|
129
|
+
this.registry.register(new screenshot_1.ScreenshotTool());
|
|
130
|
+
// Page
|
|
131
|
+
this.registry.register(new observe_1.ObserveTool());
|
|
132
|
+
this.registry.register(new scrape_1.ScrapeTool());
|
|
133
|
+
this.registry.register(new extract_dom_1.ExtractDomTool());
|
|
134
|
+
// Network
|
|
135
|
+
this.registry.register(new web_search_1.WebSearchTool());
|
|
136
|
+
this.registry.register(new fetch_url_1.FetchUrlTool());
|
|
137
|
+
this.registry.register(new download_file_1.DownloadFileTool());
|
|
138
|
+
this.registry.register(new read_network_logs_1.ReadNetworkLogsTool());
|
|
271
139
|
}
|
|
272
140
|
}
|
|
273
141
|
exports.Session = Session;
|
package/dist/session.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { PageHandle } from "../browser-provider";
|
|
2
|
+
import type { Observer } from "../observer";
|
|
3
|
+
import type { Interceptor } from "../interceptor";
|
|
4
|
+
export interface JSONSchema {
|
|
5
|
+
type: "object";
|
|
6
|
+
properties: Record<string, {
|
|
7
|
+
type: string;
|
|
8
|
+
description: string;
|
|
9
|
+
enum?: string[];
|
|
10
|
+
default?: unknown;
|
|
11
|
+
}>;
|
|
12
|
+
required: string[];
|
|
13
|
+
}
|
|
14
|
+
export interface ToolContext {
|
|
15
|
+
page?: PageHandle;
|
|
16
|
+
observer?: Observer;
|
|
17
|
+
interceptor?: Interceptor;
|
|
18
|
+
anthropicApiKey: string;
|
|
19
|
+
aiModel?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface ToolResult {
|
|
22
|
+
success: boolean;
|
|
23
|
+
summary: string;
|
|
24
|
+
data?: unknown;
|
|
25
|
+
error?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface Tool {
|
|
28
|
+
/** Unique name the LLM uses to invoke this tool (e.g. "click", "fetch_url") */
|
|
29
|
+
name: string;
|
|
30
|
+
/** One-line description shown in the system prompt */
|
|
31
|
+
description: string;
|
|
32
|
+
/** JSON Schema describing the parameters object */
|
|
33
|
+
inputSchema: JSONSchema;
|
|
34
|
+
/** Execute the tool. Params match inputSchema. */
|
|
35
|
+
execute(params: Record<string, unknown>, ctx: ToolContext): Promise<ToolResult>;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/tools/base.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAIlD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE;QACzB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC,CAAC;IACH,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAOD,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID,MAAM,WAAW,IAAI;IACnB,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IAEb,sDAAsD;IACtD,WAAW,EAAE,MAAM,CAAC;IAEpB,mDAAmD;IACnD,WAAW,EAAE,UAAU,CAAC;IAExB,kDAAkD;IAClD,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACjF"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ─── Tool abstraction ────────────────────────────────────────────────────────
|
|
3
|
+
// Every capability the agent can invoke implements this interface.
|
|
4
|
+
// Adding a new tool = one file + registry.register(). Zero changes elsewhere.
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/tools/base.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,mEAAmE;AACnE,8EAA8E"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Tool, ToolContext, ToolResult, JSONSchema } from "../base";
|
|
2
|
+
export declare class ClickTool implements Tool {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
inputSchema: JSONSchema;
|
|
6
|
+
execute(params: Record<string, unknown>, ctx: ToolContext): Promise<ToolResult>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=click.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"click.d.ts","sourceRoot":"","sources":["../../../src/tools/browser/click.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEzE,qBAAa,SAAU,YAAW,IAAI;IACpC,IAAI,SAAW;IACf,WAAW,SAA0E;IAErF,WAAW,EAAE,UAAU,CAMrB;IAEI,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CA6BtF"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ClickTool = void 0;
|
|
4
|
+
class ClickTool {
|
|
5
|
+
name = "click";
|
|
6
|
+
description = "Click an interactive element by its ActionSpace ID (e.g. B1, L3, I2)";
|
|
7
|
+
inputSchema = {
|
|
8
|
+
type: "object",
|
|
9
|
+
properties: {
|
|
10
|
+
elementId: { type: "string", description: "Element ID from the current ActionSpace (e.g. B1, L3)" },
|
|
11
|
+
},
|
|
12
|
+
required: ["elementId"],
|
|
13
|
+
};
|
|
14
|
+
async execute(params, ctx) {
|
|
15
|
+
const { page, observer, interceptor } = ctx;
|
|
16
|
+
if (!page || !observer) {
|
|
17
|
+
return { success: false, summary: "click failed: no browser context", error: "missing page/observer" };
|
|
18
|
+
}
|
|
19
|
+
const elementId = String(params.elementId);
|
|
20
|
+
interceptor?.markActionTimestamp();
|
|
21
|
+
// Try cached CSS selector first (reliable)
|
|
22
|
+
const selector = observer.getSelector(elementId);
|
|
23
|
+
if (selector) {
|
|
24
|
+
try {
|
|
25
|
+
await page.click(selector);
|
|
26
|
+
return { success: true, summary: `Clicked ${elementId}` };
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// Fall through to coordinate-based click
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// Fallback: resolve to coordinates
|
|
33
|
+
const coords = await observer.resolveElementId(elementId);
|
|
34
|
+
if (!coords) {
|
|
35
|
+
return { success: false, summary: `click failed: element ${elementId} not found`, error: `Element ${elementId} not found in DOM` };
|
|
36
|
+
}
|
|
37
|
+
await page.mouse.click(coords.x, coords.y);
|
|
38
|
+
return { success: true, summary: `Clicked ${elementId} at (${coords.x}, ${coords.y})` };
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
exports.ClickTool = ClickTool;
|
|
42
|
+
//# sourceMappingURL=click.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"click.js","sourceRoot":"","sources":["../../../src/tools/browser/click.ts"],"names":[],"mappings":";;;AAEA,MAAa,SAAS;IACpB,IAAI,GAAG,OAAO,CAAC;IACf,WAAW,GAAG,sEAAsE,CAAC;IAErF,WAAW,GAAe;QACxB,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,uDAAuD,EAAE;SACpG;QACD,QAAQ,EAAE,CAAC,WAAW,CAAC;KACxB,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,MAA+B,EAAE,GAAgB;QAC7D,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC;QAC5C,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACvB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,kCAAkC,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC;QACzG,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC3C,WAAW,EAAE,mBAAmB,EAAE,CAAC;QAEnC,2CAA2C;QAC3C,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QACjD,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAC3B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,SAAS,EAAE,EAAE,CAAC;YAC5D,CAAC;YAAC,MAAM,CAAC;gBACP,yCAAyC;YAC3C,CAAC;QACH,CAAC;QAED,mCAAmC;QACnC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAC1D,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,yBAAyB,SAAS,YAAY,EAAE,KAAK,EAAE,WAAW,SAAS,mBAAmB,EAAE,CAAC;QACrI,CAAC;QAED,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;QAC3C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,SAAS,QAAQ,MAAM,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;IAC1F,CAAC;CACF;AAzCD,8BAyCC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Tool, ToolContext, ToolResult, JSONSchema } from "../base";
|
|
2
|
+
export declare class EvalJsTool implements Tool {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
inputSchema: JSONSchema;
|
|
6
|
+
execute(params: Record<string, unknown>, ctx: ToolContext): Promise<ToolResult>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=eval_js.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eval_js.d.ts","sourceRoot":"","sources":["../../../src/tools/browser/eval_js.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAKzE,qBAAa,UAAW,YAAW,IAAI;IACrC,IAAI,SAAa;IACjB,WAAW,SAAuJ;IAElK,WAAW,EAAE,UAAU,CAMrB;IAEI,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CAkCtF"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EvalJsTool = void 0;
|
|
4
|
+
const MAX_RESULT_LENGTH = 4000;
|
|
5
|
+
const EVAL_TIMEOUT_MS = 5_000;
|
|
6
|
+
class EvalJsTool {
|
|
7
|
+
name = "eval_js";
|
|
8
|
+
description = "Evaluate a JavaScript expression in the page context and return the result. Useful for extracting SSR data (window.__NEXT_DATA__, __NUXT__, etc.)";
|
|
9
|
+
inputSchema = {
|
|
10
|
+
type: "object",
|
|
11
|
+
properties: {
|
|
12
|
+
code: { type: "string", description: "JavaScript expression to evaluate (must return a value)" },
|
|
13
|
+
},
|
|
14
|
+
required: ["code"],
|
|
15
|
+
};
|
|
16
|
+
async execute(params, ctx) {
|
|
17
|
+
const { page } = ctx;
|
|
18
|
+
if (!page) {
|
|
19
|
+
return { success: false, summary: "eval_js failed: no browser context", error: "missing page" };
|
|
20
|
+
}
|
|
21
|
+
const code = String(params.code);
|
|
22
|
+
try {
|
|
23
|
+
const result = await Promise.race([
|
|
24
|
+
page.evaluate((jsCode) => {
|
|
25
|
+
// eslint-disable-next-line no-new-func
|
|
26
|
+
const fn = new Function(`return (${jsCode})`);
|
|
27
|
+
return fn();
|
|
28
|
+
}, code),
|
|
29
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error("eval_js timeout after 5s")), EVAL_TIMEOUT_MS)),
|
|
30
|
+
]);
|
|
31
|
+
if (result === null || result === undefined) {
|
|
32
|
+
return { success: true, summary: "eval_js returned null/undefined", data: null };
|
|
33
|
+
}
|
|
34
|
+
const text = typeof result === "string"
|
|
35
|
+
? result.slice(0, MAX_RESULT_LENGTH)
|
|
36
|
+
: JSON.stringify(result, null, 2).slice(0, MAX_RESULT_LENGTH);
|
|
37
|
+
return { success: true, summary: `eval_js result (${text.length} chars):\n${text}`, data: result };
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
const msg = err.message;
|
|
41
|
+
return { success: false, summary: `eval_js error: ${msg}`, error: msg };
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
exports.EvalJsTool = EvalJsTool;
|
|
46
|
+
//# sourceMappingURL=eval_js.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eval_js.js","sourceRoot":"","sources":["../../../src/tools/browser/eval_js.ts"],"names":[],"mappings":";;;AAEA,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAC/B,MAAM,eAAe,GAAG,KAAK,CAAC;AAE9B,MAAa,UAAU;IACrB,IAAI,GAAG,SAAS,CAAC;IACjB,WAAW,GAAG,mJAAmJ,CAAC;IAElK,WAAW,GAAe;QACxB,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,yDAAyD,EAAE;SACjG;QACD,QAAQ,EAAE,CAAC,MAAM,CAAC;KACnB,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,MAA+B,EAAE,GAAgB;QAC7D,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC;QACrB,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,oCAAoC,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC;QAClG,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAEjC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;gBAChC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAc,EAAE,EAAE;oBAC/B,uCAAuC;oBACvC,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,WAAW,MAAM,GAAG,CAAC,CAAC;oBAC9C,OAAO,EAAE,EAAa,CAAC;gBACzB,CAAC,EAAE,IAAI,CAAC;gBACR,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAC/B,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC,EAAE,eAAe,CAAC,CACjF;aACF,CAAC,CAAC;YAEH,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC5C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,iCAAiC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;YACnF,CAAC;YAED,MAAM,IAAI,GAAG,OAAO,MAAM,KAAK,QAAQ;gBACrC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,iBAAiB,CAAC;gBACpC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAC;YAEhE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,mBAAmB,IAAI,CAAC,MAAM,aAAa,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QACrG,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAI,GAAa,CAAC,OAAO,CAAC;YACnC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,kBAAkB,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;QAC1E,CAAC;IACH,CAAC;CACF;AA9CD,gCA8CC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Tool, ToolContext, ToolResult, JSONSchema } from "../base";
|
|
2
|
+
export declare class FillTool implements Tool {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
inputSchema: JSONSchema;
|
|
6
|
+
execute(params: Record<string, unknown>, ctx: ToolContext): Promise<ToolResult>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=fill.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fill.d.ts","sourceRoot":"","sources":["../../../src/tools/browser/fill.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEzE,qBAAa,QAAS,YAAW,IAAI;IACnC,IAAI,SAAU;IACd,WAAW,SAAyE;IAEpF,WAAW,EAAE,UAAU,CAOrB;IAEI,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CAkCtF"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FillTool = void 0;
|
|
4
|
+
class FillTool {
|
|
5
|
+
name = "fill";
|
|
6
|
+
description = "Clear and type text into an input or textarea by its ActionSpace ID";
|
|
7
|
+
inputSchema = {
|
|
8
|
+
type: "object",
|
|
9
|
+
properties: {
|
|
10
|
+
elementId: { type: "string", description: "Input element ID from the current ActionSpace (e.g. I1, T1)" },
|
|
11
|
+
value: { type: "string", description: "Text to type into the field" },
|
|
12
|
+
},
|
|
13
|
+
required: ["elementId", "value"],
|
|
14
|
+
};
|
|
15
|
+
async execute(params, ctx) {
|
|
16
|
+
const { page, observer, interceptor } = ctx;
|
|
17
|
+
if (!page || !observer) {
|
|
18
|
+
return { success: false, summary: "fill failed: no browser context", error: "missing page/observer" };
|
|
19
|
+
}
|
|
20
|
+
const elementId = String(params.elementId);
|
|
21
|
+
const value = String(params.value);
|
|
22
|
+
interceptor?.markActionTimestamp();
|
|
23
|
+
// Try cached CSS selector first
|
|
24
|
+
const selector = observer.getSelector(elementId);
|
|
25
|
+
if (selector) {
|
|
26
|
+
try {
|
|
27
|
+
await page.click(selector, { clickCount: 3 }); // select all
|
|
28
|
+
await page.keyboard.press("Backspace");
|
|
29
|
+
await page.type(selector, value, { delay: 80 });
|
|
30
|
+
return { success: true, summary: `Filled ${elementId} with "${value}"` };
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// Fall through to coordinate-based fill
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// Fallback: resolve to coordinates
|
|
37
|
+
const coords = await observer.resolveElementId(elementId);
|
|
38
|
+
if (!coords) {
|
|
39
|
+
return { success: false, summary: `fill failed: element ${elementId} not found`, error: `Element ${elementId} not found in DOM` };
|
|
40
|
+
}
|
|
41
|
+
await page.mouse.click(coords.x, coords.y);
|
|
42
|
+
await page.keyboard.press("Control+a");
|
|
43
|
+
await page.keyboard.type(value, { delay: 80 });
|
|
44
|
+
return { success: true, summary: `Filled ${elementId} with "${value}" at (${coords.x}, ${coords.y})` };
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.FillTool = FillTool;
|
|
48
|
+
//# sourceMappingURL=fill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fill.js","sourceRoot":"","sources":["../../../src/tools/browser/fill.ts"],"names":[],"mappings":";;;AAEA,MAAa,QAAQ;IACnB,IAAI,GAAG,MAAM,CAAC;IACd,WAAW,GAAG,qEAAqE,CAAC;IAEpF,WAAW,GAAe;QACxB,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,6DAA6D,EAAE;YACzG,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,6BAA6B,EAAE;SACtE;QACD,QAAQ,EAAE,CAAC,WAAW,EAAE,OAAO,CAAC;KACjC,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,MAA+B,EAAE,GAAgB;QAC7D,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC;QAC5C,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACvB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,iCAAiC,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC;QACxG,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC3C,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnC,WAAW,EAAE,mBAAmB,EAAE,CAAC;QAEnC,gCAAgC;QAChC,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QACjD,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa;gBAC5D,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;gBACvC,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;gBAChD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,SAAS,UAAU,KAAK,GAAG,EAAE,CAAC;YAC3E,CAAC;YAAC,MAAM,CAAC;gBACP,wCAAwC;YAC1C,CAAC;QACH,CAAC;QAED,mCAAmC;QACnC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAC1D,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,wBAAwB,SAAS,YAAY,EAAE,KAAK,EAAE,WAAW,SAAS,mBAAmB,EAAE,CAAC;QACpI,CAAC;QAED,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;QAC3C,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QACvC,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,SAAS,UAAU,KAAK,SAAS,MAAM,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;IACzG,CAAC;CACF;AA/CD,4BA+CC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Tool, ToolContext, ToolResult, JSONSchema } from "../base";
|
|
2
|
+
export declare class NavigateTool implements Tool {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
inputSchema: JSONSchema;
|
|
6
|
+
execute(params: Record<string, unknown>, ctx: ToolContext): Promise<ToolResult>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=navigate.d.ts.map
|