finch-ego-lite 0.1.1 → 0.1.2
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/index.js +166 -17
- package/i18n/en-US.json +9 -2
- package/i18n/zh-CN.json +9 -2
- package/package.json +2 -2
- package/skills/ego-browser/SKILL.md +40 -45
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import { execFile } from "node:child_process";
|
|
3
|
-
import { existsSync } from "node:fs";
|
|
3
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
4
4
|
import { homedir } from "node:os";
|
|
5
5
|
import { join } from "node:path";
|
|
6
6
|
import { promisify } from "node:util";
|
|
@@ -126,6 +126,94 @@ async function openWebsite() {
|
|
|
126
126
|
const args = process.platform === "win32" ? ["/c", "start", "", WEBSITE] : [WEBSITE];
|
|
127
127
|
await execFileAsync(command, args, { timeout: 5e3 });
|
|
128
128
|
}
|
|
129
|
+
var ACTION_STAGES = {
|
|
130
|
+
open_url: "opening",
|
|
131
|
+
snapshot: "reading",
|
|
132
|
+
extract: "reading",
|
|
133
|
+
click: "acting",
|
|
134
|
+
fill: "acting",
|
|
135
|
+
type: "acting",
|
|
136
|
+
press_key: "acting",
|
|
137
|
+
scroll: "scrolling",
|
|
138
|
+
screenshot: "shooting",
|
|
139
|
+
close_space: "closing",
|
|
140
|
+
run: "running"
|
|
141
|
+
};
|
|
142
|
+
function pickProgress(t, stage) {
|
|
143
|
+
const pool = t(`progress.${stage}`);
|
|
144
|
+
const list = pool.split("|").map((s) => s.trim()).filter(Boolean);
|
|
145
|
+
return list[Math.floor(Math.random() * list.length)] ?? pool;
|
|
146
|
+
}
|
|
147
|
+
async function resolveSpaceId(spaceId) {
|
|
148
|
+
if (spaceId !== void 0) return spaceId;
|
|
149
|
+
const status = await getStatus(false);
|
|
150
|
+
const agentSpaces = status.spaces.filter((space) => space.ownership === "agent");
|
|
151
|
+
if (agentSpaces.length === 1) return agentSpaces[0].id;
|
|
152
|
+
return void 0;
|
|
153
|
+
}
|
|
154
|
+
function buildScript(action, input, spaceId) {
|
|
155
|
+
const q = JSON.stringify;
|
|
156
|
+
const sel = input.selector ? q(input.selector) : "null";
|
|
157
|
+
const spaceLine = spaceId !== void 0 ? `await switchTaskSpace(${spaceId});` : "";
|
|
158
|
+
switch (action) {
|
|
159
|
+
case "open_url": {
|
|
160
|
+
const name = input.space_name || "web task";
|
|
161
|
+
const timeout = input.timeout_seconds ?? 20;
|
|
162
|
+
return `const space = await useOrCreateTaskSpace(${q(name)});
|
|
163
|
+
await openOrReuseTab(${q(input.url ?? "")}, { wait: true, timeout: ${timeout} });
|
|
164
|
+
const tab = await currentTab();
|
|
165
|
+
cliLog(JSON.stringify({ spaceId: space.id, url: tab.url, title: tab.title }));`;
|
|
166
|
+
}
|
|
167
|
+
case "snapshot":
|
|
168
|
+
return `${spaceLine}
|
|
169
|
+
const text = await snapshotText();
|
|
170
|
+
cliLog(String(text));`;
|
|
171
|
+
case "extract":
|
|
172
|
+
return `${spaceLine}
|
|
173
|
+
const sel = ${sel};
|
|
174
|
+
let text;
|
|
175
|
+
if (sel) {
|
|
176
|
+
text = String(await js('(() => { const el = document.querySelector(' + JSON.stringify(sel) + '); return el ? el.innerText : ""; })()'));
|
|
177
|
+
} else {
|
|
178
|
+
text = String(await snapshotText());
|
|
179
|
+
}
|
|
180
|
+
cliLog(text);`;
|
|
181
|
+
case "click":
|
|
182
|
+
return `${spaceLine}
|
|
183
|
+
await click(${sel});
|
|
184
|
+
await waitForLoad({ timeout: 15 }).catch(() => {});
|
|
185
|
+
const info = await pageInfo();
|
|
186
|
+
cliLog(JSON.stringify({ ok: true, url: info.url, title: info.title }));`;
|
|
187
|
+
case "fill":
|
|
188
|
+
return `${spaceLine}
|
|
189
|
+
await fillInput(${sel}, ${q(input.value ?? "")});
|
|
190
|
+
cliLog('ok');`;
|
|
191
|
+
case "type":
|
|
192
|
+
return `${spaceLine}
|
|
193
|
+
${sel !== "null" ? `await click(${sel});` : ""}
|
|
194
|
+
await typeText(${q(input.text ?? "")});
|
|
195
|
+
cliLog('ok');`;
|
|
196
|
+
case "press_key":
|
|
197
|
+
return `${spaceLine}
|
|
198
|
+
await pressKey(${q(input.key ?? "Enter")});
|
|
199
|
+
cliLog('ok');`;
|
|
200
|
+
case "scroll":
|
|
201
|
+
return `${spaceLine}
|
|
202
|
+
await scrollBy({ y: ${input.delta_y ?? 300} });
|
|
203
|
+
const info = await pageInfo();
|
|
204
|
+
cliLog(JSON.stringify({ ok: true, sy: info.sy }));`;
|
|
205
|
+
case "screenshot":
|
|
206
|
+
return `${spaceLine}
|
|
207
|
+
const path = await captureScreenshot();
|
|
208
|
+
cliLog('__EGO_SHOT__' + path);`;
|
|
209
|
+
case "close_space":
|
|
210
|
+
return `await completeTaskSpace(${spaceId}, { keep: false });
|
|
211
|
+
cliLog('ok');`;
|
|
212
|
+
case "run":
|
|
213
|
+
default:
|
|
214
|
+
return input.script ?? "";
|
|
215
|
+
}
|
|
216
|
+
}
|
|
129
217
|
function key(value) {
|
|
130
218
|
return Buffer.from(JSON.stringify(value)).toString("base64url");
|
|
131
219
|
}
|
|
@@ -393,17 +481,36 @@ ${domainOf(tab.url, t("site.unknown"))}`,
|
|
|
393
481
|
ctx.subscriptions.push(ctx.tools.register({
|
|
394
482
|
name: "ego_browser",
|
|
395
483
|
title: "Ego Browser",
|
|
396
|
-
description: `Operate Ego Browser
|
|
484
|
+
description: `Operate Ego Browser with declarative actions. Everyday browsing needs no scripts.
|
|
397
485
|
action:
|
|
398
|
-
status
|
|
399
|
-
|
|
400
|
-
|
|
486
|
+
status \u2014 check installation, runtime, task spaces and open pages
|
|
487
|
+
open_url \u2014 open a URL in a task space (url, space_name?) and return its spaceId
|
|
488
|
+
snapshot \u2014 read the current page as text (space_id?)
|
|
489
|
+
click \u2014 click an element by CSS selector (space_id?, selector)
|
|
490
|
+
fill \u2014 fill a form field (space_id?, selector, value)
|
|
491
|
+
type \u2014 type text; pass selector to focus the field first (space_id?, selector?, text)
|
|
492
|
+
press_key \u2014 press a key: Enter, Tab, Escape, ArrowDown... (space_id?, key)
|
|
493
|
+
scroll \u2014 scroll down by pixels (space_id?, delta_y?)
|
|
494
|
+
screenshot \u2014 capture the page and return it as an image (space_id?)
|
|
495
|
+
extract \u2014 extract innerText of a CSS selector, or the whole page (space_id?, selector?)
|
|
496
|
+
close_space \u2014 close a task space (space_id)
|
|
497
|
+
run \u2014 advanced: run a raw Ego Browser script (script, timeout_seconds?)
|
|
498
|
+
Most actions accept space_id; when omitted and exactly one agent-owned task space exists, it is used.
|
|
499
|
+
Reuse task spaces, respect user ownership, verify meaningful actions, and complete spaces when done.`,
|
|
401
500
|
inputSchema: {
|
|
402
501
|
type: "object",
|
|
403
502
|
properties: {
|
|
404
|
-
action: { type: "string", enum: ["status", "run"] },
|
|
405
|
-
|
|
406
|
-
|
|
503
|
+
action: { type: "string", enum: ["status", "open_url", "snapshot", "click", "fill", "type", "press_key", "scroll", "screenshot", "extract", "close_space", "run"] },
|
|
504
|
+
url: { type: "string", description: "URL to open (action=open_url)." },
|
|
505
|
+
space_id: { type: "number", description: "Task space id from status/open_url. Optional when only one agent space exists." },
|
|
506
|
+
space_name: { type: "string", description: "Semantic name for the task space (action=open_url)." },
|
|
507
|
+
selector: { type: "string", description: "CSS selector of the target element (click/fill/type/extract)." },
|
|
508
|
+
text: { type: "string", description: "Text to type (action=type)." },
|
|
509
|
+
value: { type: "string", description: "Value to fill into the field (action=fill)." },
|
|
510
|
+
key: { type: "string", description: "Key to press (action=press_key): Enter, Tab, Escape..." },
|
|
511
|
+
delta_y: { type: "number", description: "Pixels to scroll down (action=scroll, default 300)." },
|
|
512
|
+
script: { type: "string", description: "Raw Ego Browser script (action=run only)." },
|
|
513
|
+
timeout_seconds: { type: "number", description: "Execution timeout, 1 to 300 seconds. Default 60." }
|
|
407
514
|
},
|
|
408
515
|
required: ["action"]
|
|
409
516
|
},
|
|
@@ -411,17 +518,35 @@ Use cliLog(...) for output. Reuse task spaces, respect user control, verify acti
|
|
|
411
518
|
defaultEnabled: true,
|
|
412
519
|
async execute(input, exec) {
|
|
413
520
|
const request = input;
|
|
414
|
-
|
|
521
|
+
const actionName = request.action ?? "";
|
|
522
|
+
if (actionName === "status") {
|
|
415
523
|
const status = await getStatus(true);
|
|
416
524
|
cachedStatus = status;
|
|
417
525
|
action.notifyUpdate();
|
|
418
526
|
return { content: [{ type: "text", text: statusText(status, t) }], isError: !status.supported || Boolean(status.error) };
|
|
419
527
|
}
|
|
420
|
-
if (
|
|
421
|
-
return { content: [{ type: "text", text:
|
|
528
|
+
if (!ACTION_STAGES[actionName]) {
|
|
529
|
+
return { content: [{ type: "text", text: `Unknown action: ${actionName}.` }], isError: true };
|
|
530
|
+
}
|
|
531
|
+
if (actionName === "run") {
|
|
532
|
+
if (typeof request.script !== "string" || !request.script.trim()) {
|
|
533
|
+
return { content: [{ type: "text", text: "action=run requires a non-empty script." }], isError: true };
|
|
534
|
+
}
|
|
535
|
+
if (request.script.length > 1e5 || request.script.includes("\0")) {
|
|
536
|
+
return { content: [{ type: "text", text: "The Ego Browser script is invalid or too large." }], isError: true };
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
if (actionName === "open_url" && !request.url) {
|
|
540
|
+
return { content: [{ type: "text", text: "action=open_url requires a url." }], isError: true };
|
|
541
|
+
}
|
|
542
|
+
if ((actionName === "click" || actionName === "fill" || actionName === "extract") && !request.selector) {
|
|
543
|
+
return { content: [{ type: "text", text: `action=${actionName} requires a CSS selector.` }], isError: true };
|
|
422
544
|
}
|
|
423
|
-
if (
|
|
424
|
-
return { content: [{ type: "text", text: "
|
|
545
|
+
if (actionName === "fill" && request.value === void 0) {
|
|
546
|
+
return { content: [{ type: "text", text: "action=fill requires a value." }], isError: true };
|
|
547
|
+
}
|
|
548
|
+
if (actionName === "type" && !request.text) {
|
|
549
|
+
return { content: [{ type: "text", text: "action=type requires text." }], isError: true };
|
|
425
550
|
}
|
|
426
551
|
if (process.platform !== "darwin") {
|
|
427
552
|
return { content: [{ type: "text", text: t("status.unsupported", { platform: process.platform }) }], isError: true };
|
|
@@ -434,19 +559,43 @@ Use cliLog(...) for output. Reuse task spaces, respect user control, verify acti
|
|
|
434
559
|
isError: true
|
|
435
560
|
};
|
|
436
561
|
}
|
|
562
|
+
let spaceId;
|
|
563
|
+
if (actionName !== "open_url" && actionName !== "run") {
|
|
564
|
+
spaceId = await resolveSpaceId(request.space_id);
|
|
565
|
+
if (spaceId === void 0) {
|
|
566
|
+
return {
|
|
567
|
+
content: [{ type: "text", text: "No task space resolved. Call action=status or action=open_url first, then pass its space_id." }],
|
|
568
|
+
isError: true
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
}
|
|
437
572
|
if (!await processRunning()) {
|
|
438
|
-
exec.progress.report({ stage: "launching", message: t
|
|
573
|
+
exec.progress.report({ stage: "launching", message: pickProgress(t, "launching") });
|
|
439
574
|
await launchEgo();
|
|
440
575
|
await new Promise((resolve) => setTimeout(resolve, 1800));
|
|
441
576
|
}
|
|
577
|
+
const script = buildScript(actionName, request, spaceId);
|
|
442
578
|
const timeout = Math.min(300, Math.max(1, request.timeout_seconds ?? 60)) * 1e3;
|
|
443
|
-
exec.progress.report({ stage:
|
|
579
|
+
exec.progress.report({ stage: ACTION_STAGES[actionName], message: pickProgress(t, ACTION_STAGES[actionName] ?? "browsing") });
|
|
444
580
|
try {
|
|
445
|
-
const output = await runCommand(binary, ["nodejs", "-e",
|
|
581
|
+
const output = await runCommand(binary, ["nodejs", "-e", script], timeout);
|
|
446
582
|
cachedStatus = void 0;
|
|
447
583
|
action.notifyUpdate();
|
|
448
584
|
refreshStatus(false);
|
|
449
|
-
|
|
585
|
+
if (actionName === "screenshot") {
|
|
586
|
+
const path = output.split("__EGO_SHOT__").pop()?.split("\n")[0]?.trim();
|
|
587
|
+
if (!path || !existsSync(path)) {
|
|
588
|
+
return { content: [{ type: "text", text: output || "Screenshot failed." }], isError: true };
|
|
589
|
+
}
|
|
590
|
+
const data = readFileSync(path).toString("base64");
|
|
591
|
+
return {
|
|
592
|
+
content: [
|
|
593
|
+
{ type: "text", text: `Screenshot: ${path}` },
|
|
594
|
+
{ type: "image", data: `data:image/png;base64,${data}`, mimeType: "image/png" }
|
|
595
|
+
]
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
return { content: [{ type: "text", text: output || "ok" }] };
|
|
450
599
|
} catch (error) {
|
|
451
600
|
cachedStatus = void 0;
|
|
452
601
|
action.notifyUpdate();
|
package/i18n/en-US.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "Ego Browser",
|
|
3
3
|
"description": "Let Finch browse the web in isolated Ego Lite task spaces while you follow every page it opens.",
|
|
4
|
-
"systemPrompt": "Use ego_browser for browser automation. Call action=status to inspect Ego
|
|
4
|
+
"systemPrompt": "Use ego_browser for browser automation with declarative actions. Call action=status first to inspect Ego and task spaces. Use open_url, snapshot, click, fill, type, press_key, scroll, screenshot, extract and close_space for everyday tasks, passing space_id from open_url/status when needed. Fall back to action=run only for advanced cases. Reuse task spaces, respect user ownership, verify meaningful actions, and complete spaces when done.",
|
|
5
5
|
"composerActions": {
|
|
6
6
|
"ego-browser": {
|
|
7
7
|
"tooltip": "Ego Browser"
|
|
@@ -98,7 +98,14 @@
|
|
|
98
98
|
"notInstalled": "Ego Browser is not installed"
|
|
99
99
|
},
|
|
100
100
|
"progress": {
|
|
101
|
-
"launching": "
|
|
101
|
+
"launching": "Waking up Ego Browser…|Pouring a coffee for the browser…|Ego is stretching…",
|
|
102
|
+
"opening": "Opening a new door…|Loading the page…|Knocking on the web…",
|
|
103
|
+
"reading": "Taking a look around…|Reading the page…|Scanning the content…",
|
|
104
|
+
"acting": "Clicking gently…|Tapping the button…|Filling things in…",
|
|
105
|
+
"scrolling": "Scrolling down…|Rolling the wheel…",
|
|
106
|
+
"shooting": "Saying cheese! 📸|Freezing the moment…",
|
|
107
|
+
"closing": "Tidying up…|Closing the tab circus…|Wrapping up…",
|
|
108
|
+
"running": "Ego is doing its thing…|Browser magic in progress…",
|
|
102
109
|
"browsing": "Agent is working in Ego Browser…"
|
|
103
110
|
}
|
|
104
111
|
}
|
package/i18n/zh-CN.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "Ego 浏览器",
|
|
3
3
|
"description": "让 Finch 在独立的 Ego Lite 任务空间中浏览网页,你可以随时查看它打开的每个页面。",
|
|
4
|
-
"systemPrompt": "使用 ego_browser 执行浏览器自动化。先用 action=status 检查 Ego
|
|
4
|
+
"systemPrompt": "使用 ego_browser 执行浏览器自动化。先用 action=status 检查 Ego 状态和任务空间;日常操作优先用 open_url/snapshot/click/fill/type/press_key/scroll/screenshot/extract/close_space 等声明式 action,必要时传 space_id;高级场景才用 action=run 执行脚本。复用任务空间、尊重用户控制权、验证关键操作,并在完成后关闭任务空间。",
|
|
5
5
|
"composerActions": {
|
|
6
6
|
"ego-browser": {
|
|
7
7
|
"tooltip": "Ego 浏览器"
|
|
@@ -98,7 +98,14 @@
|
|
|
98
98
|
"notInstalled": "Ego Browser 未安装"
|
|
99
99
|
},
|
|
100
100
|
"progress": {
|
|
101
|
-
"launching": "
|
|
101
|
+
"launching": "正在唤醒 Ego 浏览器…|给浏览器泡杯咖啡…|Ego 正在伸懒腰…",
|
|
102
|
+
"opening": "正在推开新世界的大门…|网页加载中…|正在敲响网络的大门…",
|
|
103
|
+
"reading": "正在环顾页面…|正在阅读页面…|正在扫描内容…",
|
|
104
|
+
"acting": "轻轻点了一下…|正在按下按钮…|正在填写…",
|
|
105
|
+
"scrolling": "正在往下滚动…|鼠标滚轮转起来了…",
|
|
106
|
+
"shooting": "咔嚓!拍照留念 📸|定格这一刻…",
|
|
107
|
+
"closing": "正在收摊…|正在收拾战场…|任务完成,整理中…",
|
|
108
|
+
"running": "Ego 正在忙活…|浏览器魔法进行中…",
|
|
102
109
|
"browsing": "Agent 正在操作 Ego Browser…"
|
|
103
110
|
}
|
|
104
111
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "finch-ego-lite",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Let Finch browse the web in isolated Ego Lite task spaces while you follow every page it opens.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "PuterJam",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"id": "ego-browser",
|
|
29
29
|
"name": "Ego Browser",
|
|
30
30
|
"description": "Control Ego Browser and see the pages your Agent is working on.",
|
|
31
|
-
"systemPrompt": "Use ego_browser for browser automation. Call action=status to inspect Ego
|
|
31
|
+
"systemPrompt": "Use ego_browser for browser automation with declarative actions. Call action=status first to inspect Ego and task spaces. Use open_url, snapshot, click, fill, type, press_key, scroll, screenshot, extract and close_space for everyday tasks, passing space_id from open_url/status when needed. Fall back to action=run only for advanced cases. Reuse task spaces, respect user ownership, verify meaningful actions, and complete spaces when done.",
|
|
32
32
|
"main": "dist/index.js",
|
|
33
33
|
"activationEvents": [
|
|
34
34
|
"onStartup"
|
|
@@ -2,50 +2,45 @@
|
|
|
2
2
|
name: ego-browser
|
|
3
3
|
description: Use Ego Browser whenever the user needs to open a website, navigate pages, click, type, upload, take screenshots, extract page data, test web apps, log in, or automate browser actions. Ego gives Agents isolated task spaces that reuse the user's login state without competing with normal browser windows.
|
|
4
4
|
metadata:
|
|
5
|
-
version: "0.1.
|
|
5
|
+
version: "0.1.2"
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
# Ego Browser
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
##
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
1. Semantic pages: `snapshotText()` then act with `@N`, stable `loc=...`, or CSS selectors.
|
|
48
|
-
2. Canvas/rich editors: screenshot, coordinates, and real keyboard input; test a tiny write first.
|
|
49
|
-
3. Extraction/state: use one `js(String.raw\`(() => { ... })()\`) expression.
|
|
50
|
-
|
|
51
|
-
After meaningful actions, verify with a new snapshot, `pageInfo()`, or screenshot. Refs from `snapshotText()` are valid only for the latest snapshot. Wait and timeout values are seconds unless the name ends in `Ms`.
|
|
8
|
+
# Ego Browser 工具使用指南
|
|
9
|
+
|
|
10
|
+
本 skill 说明如何通过 `ego_browser` 工具完成浏览器自动化。日常浏览**不需要写脚本**——工具提供声明式 action,直接传参数即可。只有高级场景(CDP、自定义 JS、复杂逻辑)才使用 `action=run`。
|
|
11
|
+
|
|
12
|
+
## 使用流程
|
|
13
|
+
|
|
14
|
+
1. **`action: "status"`** — 检查 Ego 是否可用、任务空间与页面。任务开始时先调一次。
|
|
15
|
+
2. **`action: "open_url"`** — 打开网址:传 `url`(可选 `space_name` 给任务空间起个语义名)。返回 `spaceId`,后续操作复用它。
|
|
16
|
+
3. **按需执行操作**(见下表),关键操作后验证结果。
|
|
17
|
+
4. **`action: "close_space"`** — 任务完成,关闭任务空间(`space_id`)。
|
|
18
|
+
|
|
19
|
+
`space_id` 规则:多数 action 接受 `space_id`;省略时若恰好只有一个 agent 空间会自动使用,否则需要先从 `status`/`open_url` 拿到。
|
|
20
|
+
|
|
21
|
+
## Action 一览
|
|
22
|
+
|
|
23
|
+
| action | 参数 | 说明 |
|
|
24
|
+
|---|---|---|
|
|
25
|
+
| status | - | 环境、任务空间、页面状态 |
|
|
26
|
+
| open_url | url, space_name? | 打开网址,返回 spaceId |
|
|
27
|
+
| snapshot | space_id? | 读取页面为文本(语义树) |
|
|
28
|
+
| click | space_id?, selector | 按 CSS selector 点击 |
|
|
29
|
+
| fill | space_id?, selector, value | 填写表单字段 |
|
|
30
|
+
| type | space_id?, selector?, text | 输入文本;传 selector 先聚焦 |
|
|
31
|
+
| press_key | space_id?, key | 按键:Enter/Tab/Escape… |
|
|
32
|
+
| scroll | space_id?, delta_y? | 向下滚动(默认 300px) |
|
|
33
|
+
| screenshot | space_id? | 截图并作为图片返回 |
|
|
34
|
+
| extract | space_id?, selector? | 提取区域 innerText 或整页文本 |
|
|
35
|
+
| close_space | space_id | 关闭任务空间 |
|
|
36
|
+
| run | script, timeout_seconds? | 高级:执行原始 Ego 脚本 |
|
|
37
|
+
|
|
38
|
+
## 规则
|
|
39
|
+
|
|
40
|
+
- **复用任务空间**:同一目标的多步操作复用同一个 `space_id`,不要每次新建。
|
|
41
|
+
- **尊重归属**:`ownership` 为 `agent` 时可操作;`agentDelegatedToUser` 时用户正控制,停下等待;`user` 时必须先征得用户明确同意再接管。
|
|
42
|
+
- **登录/验证码/人工确认**:交给用户处理,明确告诉用户需要做什么;用户说继续后再接管。
|
|
43
|
+
- **验证关键操作**:点击、提交、填表后,用 `snapshot` 或 `pageInfo` 确认结果,不要盲目继续。
|
|
44
|
+
- **选择器优先**:定位元素用 CSS selector;`snapshot` 输出的语义树可帮助挑选 selector。
|
|
45
|
+
- **完成后关闭**:任务结束用 `close_space`;仅当用户明确要求保留页面时留着。
|
|
46
|
+
- **超时控制**:复杂操作适当调大 `timeout_seconds`(默认 60 秒)。
|