@tangle-network/browser-agent-driver 0.22.0 → 0.23.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/brain/index.d.ts +21 -0
- package/dist/brain/index.d.ts.map +1 -1
- package/dist/brain/index.js +462 -34
- package/dist/brain/index.js.map +1 -1
- package/dist/browser-launch.d.ts +2 -0
- package/dist/browser-launch.d.ts.map +1 -1
- package/dist/browser-launch.js +12 -5
- package/dist/browser-launch.js.map +1 -1
- package/dist/captcha.d.ts +0 -7
- package/dist/captcha.d.ts.map +1 -1
- package/dist/captcha.js +113 -4
- package/dist/captcha.js.map +1 -1
- package/dist/cli.js +69 -13
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +7 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/drivers/cursor-overlay.d.ts +1 -1
- package/dist/drivers/cursor-overlay.d.ts.map +1 -1
- package/dist/drivers/cursor-overlay.js +21 -9
- package/dist/drivers/cursor-overlay.js.map +1 -1
- package/dist/drivers/extract-with-index.d.ts +45 -0
- package/dist/drivers/extract-with-index.d.ts.map +1 -0
- package/dist/drivers/extract-with-index.js +141 -0
- package/dist/drivers/extract-with-index.js.map +1 -0
- package/dist/drivers/playwright.d.ts +7 -0
- package/dist/drivers/playwright.d.ts.map +1 -1
- package/dist/drivers/playwright.js +232 -1
- package/dist/drivers/playwright.js.map +1 -1
- package/dist/drivers/som-overlay.d.ts +36 -0
- package/dist/drivers/som-overlay.d.ts.map +1 -0
- package/dist/drivers/som-overlay.js +109 -0
- package/dist/drivers/som-overlay.js.map +1 -0
- package/dist/drivers/types.d.ts +2 -0
- package/dist/drivers/types.d.ts.map +1 -1
- package/dist/recovery.d.ts.map +1 -1
- package/dist/recovery.js +2 -0
- package/dist/recovery.js.map +1 -1
- package/dist/run-state.d.ts +27 -1
- package/dist/run-state.d.ts.map +1 -1
- package/dist/run-state.js +40 -1
- package/dist/run-state.js.map +1 -1
- package/dist/runner/runner.d.ts +21 -0
- package/dist/runner/runner.d.ts.map +1 -1
- package/dist/runner/runner.js +260 -14
- package/dist/runner/runner.js.map +1 -1
- package/dist/supervisor/critic.d.ts.map +1 -1
- package/dist/supervisor/critic.js +1 -0
- package/dist/supervisor/critic.js.map +1 -1
- package/dist/supervisor/policy.js +10 -0
- package/dist/supervisor/policy.js.map +1 -1
- package/dist/test-runner.d.ts.map +1 -1
- package/dist/test-runner.js +8 -3
- package/dist/test-runner.js.map +1 -1
- package/dist/types.d.ts +62 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -1
|
@@ -17,5 +17,5 @@
|
|
|
17
17
|
* The init script that runs in every page. Returned as a string so it can be
|
|
18
18
|
* passed to `page.addInitScript`. Pure DOM/CSS — no dependencies.
|
|
19
19
|
*/
|
|
20
|
-
export declare const CURSOR_OVERLAY_INIT_SCRIPT = "\n(() => {\n if (window.__bad_overlay_installed) return;\n window.__bad_overlay_installed = true;\n\n const NS = 'http://www.w3.org/2000/svg';\n const Z = 2147483647; // max i32\n\n // \u2500\u2500 Root container (absolute, ignores pointer events) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const root = document.createElement('div');\n root.id = '__bad_overlay_root';\n Object.assign(root.style, {\n position: 'fixed',\n inset: '0',\n width: '100vw',\n height: '100vh',\n pointerEvents: 'none',\n zIndex: String(Z),\n });\n\n // \u2500\u2500 Cursor sprite (SVG arrow) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const cursor = document.createElementNS(NS, 'svg');\n cursor.setAttribute('width', '24');\n cursor.setAttribute('height', '24');\n cursor.setAttribute('viewBox', '0 0 24 24');\n cursor.setAttribute('fill', 'none');\n Object.assign(cursor.style, {\n position: 'fixed',\n left: '0',\n top: '0',\n transform: 'translate(-100px, -100px)',\n transition: 'transform
|
|
20
|
+
export declare const CURSOR_OVERLAY_INIT_SCRIPT = "\n(() => {\n if (window.__bad_overlay_installed) return;\n window.__bad_overlay_installed = true;\n\n const NS = 'http://www.w3.org/2000/svg';\n const Z = 2147483647; // max i32\n\n // \u2500\u2500 Root container (absolute, ignores pointer events) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const root = document.createElement('div');\n root.id = '__bad_overlay_root';\n Object.assign(root.style, {\n position: 'fixed',\n inset: '0',\n width: '100vw',\n height: '100vh',\n pointerEvents: 'none',\n zIndex: String(Z),\n });\n\n // \u2500\u2500 Cursor sprite (SVG arrow) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // \u2500\u2500 Idle bounce keyframes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const style = document.createElement('style');\n style.textContent = `\n @keyframes __bad_cursor_bob {\n 0%, 100% { margin-top: 0px; }\n 50% { margin-top: -3px; }\n }\n `;\n (document.head || document.documentElement).appendChild(style);\n\n const cursor = document.createElementNS(NS, 'svg');\n cursor.setAttribute('width', '24');\n cursor.setAttribute('height', '24');\n cursor.setAttribute('viewBox', '0 0 24 24');\n cursor.setAttribute('fill', 'none');\n Object.assign(cursor.style, {\n position: 'fixed',\n left: '0',\n top: '0',\n transform: 'translate(-100px, -100px)',\n transition: 'transform 400ms cubic-bezier(0.34, 1.56, 0.64, 1)',\n pointerEvents: 'none',\n filter: 'drop-shadow(0 2px 4px rgba(0,0,0,0.5))',\n animation: '__bad_cursor_bob 1.8s ease-in-out infinite',\n });\n cursor.innerHTML = `\n <path d=\"M3 2 L21 12 L13 14 L9 22 Z\" fill=\"#ffffff\" stroke=\"#0b1220\" stroke-width=\"1.5\" stroke-linejoin=\"round\"/>\n `;\n\n // \u2500\u2500 Pulse ring (animated on click) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const ring = document.createElement('div');\n Object.assign(ring.style, {\n position: 'fixed',\n left: '0',\n top: '0',\n width: '0',\n height: '0',\n borderRadius: '9999px',\n border: '3px solid rgba(79, 70, 229, 0.95)',\n transform: 'translate(-100px, -100px)',\n pointerEvents: 'none',\n opacity: '0',\n transition: 'all 500ms ease-out',\n });\n\n // \u2500\u2500 Highlight box (drawn around the target element) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const box = document.createElement('div');\n box.id = '__bad_overlay_box';\n Object.assign(box.style, {\n position: 'fixed',\n left: '0',\n top: '0',\n width: '0',\n height: '0',\n border: '2px solid rgba(34, 197, 94, 0.95)',\n borderRadius: '6px',\n background: 'rgba(34, 197, 94, 0.08)',\n boxShadow: '0 0 0 4px rgba(34, 197, 94, 0.18)',\n transform: 'translate(-100px, -100px)',\n pointerEvents: 'none',\n transition: 'all 350ms cubic-bezier(0.34, 1.56, 0.64, 1)',\n opacity: '0',\n });\n\n // \u2500\u2500 Action label (shows \"click\" / \"type\" / etc next to cursor) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const label = document.createElement('div');\n Object.assign(label.style, {\n position: 'fixed',\n left: '0',\n top: '0',\n padding: '5px 12px',\n background: 'rgba(11, 18, 32, 0.95)',\n color: '#ffffff',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n fontSize: '13px',\n fontWeight: '600',\n letterSpacing: '0.01em',\n borderRadius: '8px',\n transform: 'translate(-200px, -200px)',\n pointerEvents: 'none',\n opacity: '0',\n transition: 'transform 400ms cubic-bezier(0.34, 1.56, 0.64, 1), opacity 200ms ease',\n boxShadow: '0 4px 16px rgba(0,0,0,0.35)',\n whiteSpace: 'nowrap',\n });\n\n // Append to documentElement (not body) so the overlay is not affected by\n // body's stacking context \u2014 many modern sites apply transform/will-change\n // to body which would clip a max-z-index child appended to body.\n // Bound the retry loop so a body-less doc (XML, PDF viewer, chrome://)\n // doesn't spin requestAnimationFrame forever.\n let attachAttempts = 0;\n function attach() {\n const host = document.documentElement || document.body;\n if (!host) {\n if (++attachAttempts > 60) return; // ~1 second of attempts\n requestAnimationFrame(attach);\n return;\n }\n host.appendChild(root);\n root.appendChild(box);\n root.appendChild(ring);\n root.appendChild(cursor);\n root.appendChild(label);\n }\n attach();\n\n // \u2500\u2500 Public API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n window.__bad_overlay = {\n /**\n * Highlight a target element by CSS selector. Returns the rect or null.\n * Used when the caller has a stable CSS selector.\n */\n highlight(selector) {\n try {\n const el = typeof selector === 'string'\n ? document.querySelector(selector)\n : null;\n if (!el) return null;\n const rect = el.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) return null;\n Object.assign(box.style, {\n width: rect.width + 'px',\n height: rect.height + 'px',\n transform: `translate(${rect.left}px, ${rect.top}px)`,\n opacity: '1',\n });\n return { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2, width: rect.width, height: rect.height };\n } catch { return null; }\n },\n\n /**\n * Highlight an arbitrary rect at given page coordinates. Used when the\n * caller already computed the rect via Playwright's boundingBox (i.e.,\n * the @ref selector isn't a real CSS selector).\n */\n highlightRect(x, y, width, height) {\n try {\n Object.assign(box.style, {\n width: width + 'px',\n height: height + 'px',\n transform: `translate(${x}px, ${y}px)`,\n opacity: '1',\n });\n } catch { /* never let cosmetic overlay break a run */ }\n },\n\n /**\n * Move the cursor to (x, y) and show a label.\n */\n moveTo(x, y, labelText) {\n cursor.style.transform = `translate(${x - 4}px, ${y - 4}px)`;\n if (labelText) {\n label.textContent = labelText;\n Object.assign(label.style, {\n transform: `translate(${x + 16}px, ${y + 16}px)`,\n opacity: '1',\n });\n }\n },\n\n /**\n * Pulse a click ring at (x, y).\n */\n pulseClick(x, y) {\n // reset\n Object.assign(ring.style, {\n width: '0',\n height: '0',\n transform: `translate(${x}px, ${y}px)`,\n opacity: '1',\n });\n // expand\n requestAnimationFrame(() => {\n Object.assign(ring.style, {\n width: '60px',\n height: '60px',\n transform: `translate(${x - 30}px, ${y - 30}px)`,\n opacity: '0',\n });\n });\n },\n\n /**\n * Hide all overlay elements.\n */\n hide() {\n box.style.opacity = '0';\n label.style.opacity = '0';\n ring.style.opacity = '0';\n },\n\n /**\n * Hide just the highlight box (cursor + label stay).\n */\n clearHighlight() {\n box.style.opacity = '0';\n },\n };\n})();\n";
|
|
21
21
|
//# sourceMappingURL=cursor-overlay.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cursor-overlay.d.ts","sourceRoot":"","sources":["../../src/drivers/cursor-overlay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;GAGG;AACH,eAAO,MAAM,0BAA0B,
|
|
1
|
+
{"version":3,"file":"cursor-overlay.d.ts","sourceRoot":"","sources":["../../src/drivers/cursor-overlay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;GAGG;AACH,eAAO,MAAM,0BAA0B,4hQA6NtC,CAAA"}
|
|
@@ -38,6 +38,16 @@ export const CURSOR_OVERLAY_INIT_SCRIPT = `
|
|
|
38
38
|
});
|
|
39
39
|
|
|
40
40
|
// ── Cursor sprite (SVG arrow) ──────────────────────────────────────────
|
|
41
|
+
// ── Idle bounce keyframes ──────────────────────────────────────────
|
|
42
|
+
const style = document.createElement('style');
|
|
43
|
+
style.textContent = \`
|
|
44
|
+
@keyframes __bad_cursor_bob {
|
|
45
|
+
0%, 100% { margin-top: 0px; }
|
|
46
|
+
50% { margin-top: -3px; }
|
|
47
|
+
}
|
|
48
|
+
\`;
|
|
49
|
+
(document.head || document.documentElement).appendChild(style);
|
|
50
|
+
|
|
41
51
|
const cursor = document.createElementNS(NS, 'svg');
|
|
42
52
|
cursor.setAttribute('width', '24');
|
|
43
53
|
cursor.setAttribute('height', '24');
|
|
@@ -48,9 +58,10 @@ export const CURSOR_OVERLAY_INIT_SCRIPT = `
|
|
|
48
58
|
left: '0',
|
|
49
59
|
top: '0',
|
|
50
60
|
transform: 'translate(-100px, -100px)',
|
|
51
|
-
transition: 'transform
|
|
61
|
+
transition: 'transform 400ms cubic-bezier(0.34, 1.56, 0.64, 1)',
|
|
52
62
|
pointerEvents: 'none',
|
|
53
|
-
filter: 'drop-shadow(0
|
|
63
|
+
filter: 'drop-shadow(0 2px 4px rgba(0,0,0,0.5))',
|
|
64
|
+
animation: '__bad_cursor_bob 1.8s ease-in-out infinite',
|
|
54
65
|
});
|
|
55
66
|
cursor.innerHTML = \`
|
|
56
67
|
<path d="M3 2 L21 12 L13 14 L9 22 Z" fill="#ffffff" stroke="#0b1220" stroke-width="1.5" stroke-linejoin="round"/>
|
|
@@ -87,7 +98,7 @@ export const CURSOR_OVERLAY_INIT_SCRIPT = `
|
|
|
87
98
|
boxShadow: '0 0 0 4px rgba(34, 197, 94, 0.18)',
|
|
88
99
|
transform: 'translate(-100px, -100px)',
|
|
89
100
|
pointerEvents: 'none',
|
|
90
|
-
transition: 'all
|
|
101
|
+
transition: 'all 350ms cubic-bezier(0.34, 1.56, 0.64, 1)',
|
|
91
102
|
opacity: '0',
|
|
92
103
|
});
|
|
93
104
|
|
|
@@ -97,18 +108,19 @@ export const CURSOR_OVERLAY_INIT_SCRIPT = `
|
|
|
97
108
|
position: 'fixed',
|
|
98
109
|
left: '0',
|
|
99
110
|
top: '0',
|
|
100
|
-
padding: '
|
|
101
|
-
background: 'rgba(11, 18, 32, 0.
|
|
111
|
+
padding: '5px 12px',
|
|
112
|
+
background: 'rgba(11, 18, 32, 0.95)',
|
|
102
113
|
color: '#ffffff',
|
|
103
114
|
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
104
|
-
fontSize: '
|
|
115
|
+
fontSize: '13px',
|
|
105
116
|
fontWeight: '600',
|
|
106
|
-
|
|
117
|
+
letterSpacing: '0.01em',
|
|
118
|
+
borderRadius: '8px',
|
|
107
119
|
transform: 'translate(-200px, -200px)',
|
|
108
120
|
pointerEvents: 'none',
|
|
109
121
|
opacity: '0',
|
|
110
|
-
transition: '
|
|
111
|
-
boxShadow: '0 4px
|
|
122
|
+
transition: 'transform 400ms cubic-bezier(0.34, 1.56, 0.64, 1), opacity 200ms ease',
|
|
123
|
+
boxShadow: '0 4px 16px rgba(0,0,0,0.35)',
|
|
112
124
|
whiteSpace: 'nowrap',
|
|
113
125
|
});
|
|
114
126
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cursor-overlay.js","sourceRoot":"","sources":["../../src/drivers/cursor-overlay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG
|
|
1
|
+
{"version":3,"file":"cursor-overlay.js","sourceRoot":"","sources":["../../src/drivers/cursor-overlay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6NzC,CAAA"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gen 10 — extractWithIndex implementation.
|
|
3
|
+
*
|
|
4
|
+
* Runs in page context via page.evaluate() and returns a numbered list of
|
|
5
|
+
* every visible element matching `query`, each with its tag, textContent,
|
|
6
|
+
* key attributes, and a stable selector. The agent picks elements by index
|
|
7
|
+
* in the next turn.
|
|
8
|
+
*
|
|
9
|
+
* Why this is the Gen 10 capability fix: rather than asking the LLM to
|
|
10
|
+
* write a precise CSS selector that returns exactly one element (the
|
|
11
|
+
* approach that fails on real-web pages where data lives in obscurely-classed
|
|
12
|
+
* wrapper divs or `<dl>/<dt>/<dd>` blocks), the LLM emits a wide query and
|
|
13
|
+
* READS the actual text content of every match. Pick-by-content beats
|
|
14
|
+
* pick-by-selector on every failing task in the Gen 8 gauntlet.
|
|
15
|
+
*/
|
|
16
|
+
import type { Page } from 'playwright';
|
|
17
|
+
export interface ExtractMatch {
|
|
18
|
+
/** Position in the result list (0-based) */
|
|
19
|
+
index: number;
|
|
20
|
+
/** Element tag name (lowercase) */
|
|
21
|
+
tag: string;
|
|
22
|
+
/** Visible text content, trimmed and length-capped */
|
|
23
|
+
text: string;
|
|
24
|
+
/** Key attributes that help uniquely identify the element */
|
|
25
|
+
attributes: Record<string, string>;
|
|
26
|
+
/** A stable CSS selector the agent can use in a follow-up action */
|
|
27
|
+
selector: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Execute the extractWithIndex action in page context. The function passed
|
|
31
|
+
* to page.evaluate runs in the browser; it must be self-contained (no
|
|
32
|
+
* closures over Node-side variables).
|
|
33
|
+
*/
|
|
34
|
+
export declare function runExtractWithIndex(page: Page, query: string, contains?: string): Promise<ExtractMatch[]>;
|
|
35
|
+
/**
|
|
36
|
+
* Format extract matches as a compact, LLM-readable list. The format is
|
|
37
|
+
* line-per-match with index, tag, attributes, then text on the next line.
|
|
38
|
+
*
|
|
39
|
+
* [0] p {class: "downloads"}
|
|
40
|
+
* Weekly downloads: 26,543,821
|
|
41
|
+
* [1] dd
|
|
42
|
+
* Returns a new array formed by applying...
|
|
43
|
+
*/
|
|
44
|
+
export declare function formatExtractWithIndexResult(matches: ExtractMatch[], query: string, contains?: string): string;
|
|
45
|
+
//# sourceMappingURL=extract-with-index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract-with-index.d.ts","sourceRoot":"","sources":["../../src/drivers/extract-with-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,WAAW,YAAY;IAC3B,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,mCAAmC;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,oEAAoE;IACpE,QAAQ,EAAE,MAAM,CAAC;CAClB;AAOD;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,YAAY,EAAE,CAAC,CAsFzB;AAED;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,YAAY,EAAE,EACvB,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CAmBR"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gen 10 — extractWithIndex implementation.
|
|
3
|
+
*
|
|
4
|
+
* Runs in page context via page.evaluate() and returns a numbered list of
|
|
5
|
+
* every visible element matching `query`, each with its tag, textContent,
|
|
6
|
+
* key attributes, and a stable selector. The agent picks elements by index
|
|
7
|
+
* in the next turn.
|
|
8
|
+
*
|
|
9
|
+
* Why this is the Gen 10 capability fix: rather than asking the LLM to
|
|
10
|
+
* write a precise CSS selector that returns exactly one element (the
|
|
11
|
+
* approach that fails on real-web pages where data lives in obscurely-classed
|
|
12
|
+
* wrapper divs or `<dl>/<dt>/<dd>` blocks), the LLM emits a wide query and
|
|
13
|
+
* READS the actual text content of every match. Pick-by-content beats
|
|
14
|
+
* pick-by-selector on every failing task in the Gen 8 gauntlet.
|
|
15
|
+
*/
|
|
16
|
+
/** Hard cap on matches returned per call. Prevents 800-element pages from blowing the response. */
|
|
17
|
+
const MAX_MATCHES = 80;
|
|
18
|
+
/** Per-element textContent cap. */
|
|
19
|
+
const TEXT_CAP = 200;
|
|
20
|
+
/**
|
|
21
|
+
* Execute the extractWithIndex action in page context. The function passed
|
|
22
|
+
* to page.evaluate runs in the browser; it must be self-contained (no
|
|
23
|
+
* closures over Node-side variables).
|
|
24
|
+
*/
|
|
25
|
+
export async function runExtractWithIndex(page, query, contains) {
|
|
26
|
+
return await page.evaluate(({ query, contains, max, textCap }) => {
|
|
27
|
+
// Browser-side helpers (must be self-contained)
|
|
28
|
+
const isVisible = (el) => {
|
|
29
|
+
if (!(el instanceof HTMLElement))
|
|
30
|
+
return true;
|
|
31
|
+
const style = window.getComputedStyle(el);
|
|
32
|
+
if (style.display === 'none' || style.visibility === 'hidden' || style.opacity === '0')
|
|
33
|
+
return false;
|
|
34
|
+
const rect = el.getBoundingClientRect();
|
|
35
|
+
return rect.width > 0 && rect.height > 0;
|
|
36
|
+
};
|
|
37
|
+
const cssEscape = (s) => (window.CSS && typeof window.CSS.escape === 'function')
|
|
38
|
+
? window.CSS.escape(s)
|
|
39
|
+
: s.replace(/[^\w-]/g, (c) => `\\${c}`);
|
|
40
|
+
// Build a selector that uniquely targets the element. Preference order:
|
|
41
|
+
// [data-testid="x"] > [id="x"] > [aria-label="x"] > tag.cls.cls > nth-of-type
|
|
42
|
+
const buildSelector = (el) => {
|
|
43
|
+
const tag = el.tagName.toLowerCase();
|
|
44
|
+
const testid = el.getAttribute('data-testid');
|
|
45
|
+
if (testid)
|
|
46
|
+
return `[data-testid="${testid}"]`;
|
|
47
|
+
const id = el.getAttribute('id');
|
|
48
|
+
if (id && /^[a-zA-Z][\w-]*$/.test(id))
|
|
49
|
+
return `#${id}`;
|
|
50
|
+
const aria = el.getAttribute('aria-label');
|
|
51
|
+
if (aria && aria.length < 60)
|
|
52
|
+
return `${tag}[aria-label="${aria.replace(/"/g, '\\"')}"]`;
|
|
53
|
+
// Class-based fallback (cap at 3 stable-looking classes)
|
|
54
|
+
const classes = (el.className && typeof el.className === 'string')
|
|
55
|
+
? el.className.split(/\s+/).filter((c) => c.length > 0 && c.length < 40 && /^[a-zA-Z_-][\w-]*$/.test(c) && !/^\d/.test(c)).slice(0, 3)
|
|
56
|
+
: [];
|
|
57
|
+
if (classes.length > 0)
|
|
58
|
+
return `${tag}.${classes.map(cssEscape).join('.')}`;
|
|
59
|
+
// Last resort: tag + nth-of-type position relative to parent
|
|
60
|
+
const parent = el.parentElement;
|
|
61
|
+
if (!parent)
|
|
62
|
+
return tag;
|
|
63
|
+
const siblings = Array.from(parent.children).filter((c) => c.tagName === el.tagName);
|
|
64
|
+
const idx = siblings.indexOf(el) + 1;
|
|
65
|
+
return `${tag}:nth-of-type(${idx})`;
|
|
66
|
+
};
|
|
67
|
+
// Collect interesting attributes for each match (helps the LLM
|
|
68
|
+
// disambiguate without bloating the response)
|
|
69
|
+
const attrsForMatch = (el) => {
|
|
70
|
+
const attrs = {};
|
|
71
|
+
const interesting = ['id', 'data-testid', 'aria-label', 'role', 'href', 'name', 'type', 'value'];
|
|
72
|
+
for (const name of interesting) {
|
|
73
|
+
const v = el.getAttribute(name);
|
|
74
|
+
if (v != null && v.length > 0 && v.length < 200)
|
|
75
|
+
attrs[name] = v;
|
|
76
|
+
}
|
|
77
|
+
return attrs;
|
|
78
|
+
};
|
|
79
|
+
let elements;
|
|
80
|
+
try {
|
|
81
|
+
elements = Array.from(document.querySelectorAll(query));
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// Invalid selector — return empty so the runner can report the error cleanly.
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
const filterText = contains ? contains.toLowerCase() : '';
|
|
88
|
+
const matches = [];
|
|
89
|
+
for (const el of elements) {
|
|
90
|
+
if (!isVisible(el))
|
|
91
|
+
continue;
|
|
92
|
+
const rawText = (el.textContent || '').trim().replace(/\s+/g, ' ');
|
|
93
|
+
if (filterText && !rawText.toLowerCase().includes(filterText))
|
|
94
|
+
continue;
|
|
95
|
+
const text = rawText.length > textCap ? rawText.slice(0, textCap) + '…' : rawText;
|
|
96
|
+
// Skip empty text matches unless the element has interesting attributes
|
|
97
|
+
if (!text && Object.keys(attrsForMatch(el)).length === 0)
|
|
98
|
+
continue;
|
|
99
|
+
matches.push({
|
|
100
|
+
index: matches.length,
|
|
101
|
+
tag: el.tagName.toLowerCase(),
|
|
102
|
+
text,
|
|
103
|
+
attributes: attrsForMatch(el),
|
|
104
|
+
selector: buildSelector(el),
|
|
105
|
+
});
|
|
106
|
+
if (matches.length >= max)
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
return matches;
|
|
110
|
+
}, { query, contains: contains ?? '', max: MAX_MATCHES, textCap: TEXT_CAP });
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Format extract matches as a compact, LLM-readable list. The format is
|
|
114
|
+
* line-per-match with index, tag, attributes, then text on the next line.
|
|
115
|
+
*
|
|
116
|
+
* [0] p {class: "downloads"}
|
|
117
|
+
* Weekly downloads: 26,543,821
|
|
118
|
+
* [1] dd
|
|
119
|
+
* Returns a new array formed by applying...
|
|
120
|
+
*/
|
|
121
|
+
export function formatExtractWithIndexResult(matches, query, contains) {
|
|
122
|
+
if (matches.length === 0) {
|
|
123
|
+
return `(no matches for query "${query}"${contains ? ` containing "${contains}"` : ''})`;
|
|
124
|
+
}
|
|
125
|
+
const lines = [];
|
|
126
|
+
for (const m of matches) {
|
|
127
|
+
const attrPairs = Object.entries(m.attributes)
|
|
128
|
+
.map(([k, v]) => `${k}="${v.length > 60 ? v.slice(0, 60) + '…' : v}"`)
|
|
129
|
+
.join(' ');
|
|
130
|
+
const attrPart = attrPairs ? ` ${attrPairs}` : '';
|
|
131
|
+
lines.push(`[${m.index}] <${m.tag}>${attrPart} selector: ${m.selector}`);
|
|
132
|
+
if (m.text) {
|
|
133
|
+
lines.push(` text: ${m.text}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (matches.length === MAX_MATCHES) {
|
|
137
|
+
lines.push(`(capped at ${MAX_MATCHES} matches — narrow your query or use a 'contains' filter to see more)`);
|
|
138
|
+
}
|
|
139
|
+
return lines.join('\n');
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=extract-with-index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract-with-index.js","sourceRoot":"","sources":["../../src/drivers/extract-with-index.ts"],"names":[],"mappings":"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"}
|
|
@@ -70,6 +70,8 @@ export declare class PlaywrightDriver implements Driver {
|
|
|
70
70
|
* the init script. Undefined if showCursor is off.
|
|
71
71
|
*/
|
|
72
72
|
private cursorInstallPromise?;
|
|
73
|
+
/** Gen 23: SoM element map from last observe — used to resolve clickLabel/typeLabel */
|
|
74
|
+
private somElements;
|
|
73
75
|
constructor(page: Page, options?: PlaywrightDriverOptions);
|
|
74
76
|
/**
|
|
75
77
|
* Inject the cursor overlay init script into the current page and into the
|
|
@@ -85,6 +87,11 @@ export declare class PlaywrightDriver implements Driver {
|
|
|
85
87
|
* overlay via its public `highlightRect` / `moveTo` / `pulseClick` API.
|
|
86
88
|
*/
|
|
87
89
|
private animateCursorToSelector;
|
|
90
|
+
/**
|
|
91
|
+
* Animate cursor to raw (x, y) coordinates — for clickAt/typeAt actions.
|
|
92
|
+
* Same visual effect as animateCursorToSelector but without needing a locator.
|
|
93
|
+
*/
|
|
94
|
+
private animateCursorToCoord;
|
|
88
95
|
/** Get phase-level timing from the last observe() call */
|
|
89
96
|
getLastTiming(): ObserveTiming | undefined;
|
|
90
97
|
getPage(): Page;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"playwright.d.ts","sourceRoot":"","sources":["../../src/drivers/playwright.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAc,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAChF,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"playwright.d.ts","sourceRoot":"","sources":["../../src/drivers/playwright.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAc,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAChF,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAyFrD,iDAAiD;AACjD,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,YAAY,EAAE,MAAM,CAAC;IACrB,qCAAqC;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,qCAAqC;IACrC,YAAY,EAAE,MAAM,CAAC;IACrB,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,uBAAuB;IACtC,2BAA2B;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,6CAA6C;IAC7C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,qEAAqE;IACrE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,sEAAsE;IACtE,cAAc,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;IAC7C,6EAA6E;IAC7E,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;;;;;OAUG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,qBAAa,gBAAiB,YAAW,MAAM;IAgB3C,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,OAAO;IAhBjB,OAAO,CAAC,QAAQ,CAA4B;IAC5C,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAA4B;IAC9C,OAAO,CAAC,YAAY,CAAK;IACzB;;;;OAIG;IACH,OAAO,CAAC,oBAAoB,CAAC,CAAgB;IAC7C,uFAAuF;IACvF,OAAO,CAAC,WAAW,CAAoB;gBAG7B,IAAI,EAAE,IAAI,EACV,OAAO,GAAE,uBAA4B;IAU/C;;;OAGG;YACW,oBAAoB;IAWlC;;;;;;;OAOG;YACW,uBAAuB;IA4CrC;;;OAGG;YACW,oBAAoB;IAqBlC,0DAA0D;IAC1D,aAAa,IAAI,aAAa,GAAG,SAAS;IAI1C,OAAO,IAAI,IAAI;IAIf,MAAM,IAAI,MAAM;IAIV,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;YAS1D,SAAS;IAWvB;;;OAGG;IACG,qBAAqB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAuC5E;;;OAGG;YACW,gBAAgB;IAcxB,OAAO,IAAI,OAAO,CAAC,SAAS,CAAC;IAmDnC;;OAEG;YACW,UAAU;IA4ExB;;OAEG;YACW,iBAAiB;IAwCzB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAI7B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAO5B;;;OAGG;YACW,mBAAmB;YAUnB,aAAa;IAUrB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;CAoXrD"}
|