auspex 0.2.1 → 0.3.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.
Files changed (101) hide show
  1. package/package.json +3 -1
  2. package/dist/agent/actions.d.ts +0 -5
  3. package/dist/agent/actions.d.ts.map +0 -1
  4. package/dist/agent/actions.js +0 -32
  5. package/dist/agent/actions.js.map +0 -1
  6. package/dist/agent/agent.d.ts +0 -26
  7. package/dist/agent/agent.d.ts.map +0 -1
  8. package/dist/agent/agent.js +0 -282
  9. package/dist/agent/agent.js.map +0 -1
  10. package/dist/agent/logger.d.ts +0 -15
  11. package/dist/agent/logger.d.ts.map +0 -1
  12. package/dist/agent/logger.js +0 -70
  13. package/dist/agent/logger.js.map +0 -1
  14. package/dist/agent/loop.d.ts +0 -21
  15. package/dist/agent/loop.d.ts.map +0 -1
  16. package/dist/agent/loop.js +0 -250
  17. package/dist/agent/loop.js.map +0 -1
  18. package/dist/agent/report.d.ts +0 -3
  19. package/dist/agent/report.d.ts.map +0 -1
  20. package/dist/agent/report.js +0 -107
  21. package/dist/agent/report.js.map +0 -1
  22. package/dist/browser/executor.d.ts +0 -5
  23. package/dist/browser/executor.d.ts.map +0 -1
  24. package/dist/browser/executor.js +0 -87
  25. package/dist/browser/executor.js.map +0 -1
  26. package/dist/browser/pool.d.ts +0 -33
  27. package/dist/browser/pool.d.ts.map +0 -1
  28. package/dist/browser/pool.js +0 -101
  29. package/dist/browser/pool.js.map +0 -1
  30. package/dist/browser/snapshot.d.ts +0 -7
  31. package/dist/browser/snapshot.d.ts.map +0 -1
  32. package/dist/browser/snapshot.js +0 -201
  33. package/dist/browser/snapshot.js.map +0 -1
  34. package/dist/config/defaults.d.ts +0 -17
  35. package/dist/config/defaults.d.ts.map +0 -1
  36. package/dist/config/defaults.js +0 -17
  37. package/dist/config/defaults.js.map +0 -1
  38. package/dist/config/schema.d.ts +0 -169
  39. package/dist/config/schema.d.ts.map +0 -1
  40. package/dist/config/schema.js +0 -53
  41. package/dist/config/schema.js.map +0 -1
  42. package/dist/index.d.ts +0 -9
  43. package/dist/index.d.ts.map +0 -1
  44. package/dist/index.js +0 -10
  45. package/dist/index.js.map +0 -1
  46. package/dist/llm/client.d.ts +0 -23
  47. package/dist/llm/client.d.ts.map +0 -1
  48. package/dist/llm/client.js +0 -88
  49. package/dist/llm/client.js.map +0 -1
  50. package/dist/llm/prompt.d.ts +0 -15
  51. package/dist/llm/prompt.d.ts.map +0 -1
  52. package/dist/llm/prompt.js +0 -82
  53. package/dist/llm/prompt.js.map +0 -1
  54. package/dist/llm/vision-models.d.ts +0 -3
  55. package/dist/llm/vision-models.d.ts.map +0 -1
  56. package/dist/llm/vision-models.js +0 -30
  57. package/dist/llm/vision-models.js.map +0 -1
  58. package/dist/scraper/extractors/content.d.ts +0 -33
  59. package/dist/scraper/extractors/content.d.ts.map +0 -1
  60. package/dist/scraper/extractors/content.js +0 -276
  61. package/dist/scraper/extractors/content.js.map +0 -1
  62. package/dist/scraper/extractors/ssr.d.ts +0 -18
  63. package/dist/scraper/extractors/ssr.d.ts.map +0 -1
  64. package/dist/scraper/extractors/ssr.js +0 -162
  65. package/dist/scraper/extractors/ssr.js.map +0 -1
  66. package/dist/scraper/extractors/to-markdown.d.ts +0 -5
  67. package/dist/scraper/extractors/to-markdown.d.ts.map +0 -1
  68. package/dist/scraper/extractors/to-markdown.js +0 -103
  69. package/dist/scraper/extractors/to-markdown.js.map +0 -1
  70. package/dist/scraper/index.d.ts +0 -35
  71. package/dist/scraper/index.d.ts.map +0 -1
  72. package/dist/scraper/index.js +0 -299
  73. package/dist/scraper/index.js.map +0 -1
  74. package/dist/scraper/tiers/tier1-http.d.ts +0 -5
  75. package/dist/scraper/tiers/tier1-http.d.ts.map +0 -1
  76. package/dist/scraper/tiers/tier1-http.js +0 -116
  77. package/dist/scraper/tiers/tier1-http.js.map +0 -1
  78. package/dist/scraper/tiers/tier2-stealth.d.ts +0 -5
  79. package/dist/scraper/tiers/tier2-stealth.d.ts.map +0 -1
  80. package/dist/scraper/tiers/tier2-stealth.js +0 -109
  81. package/dist/scraper/tiers/tier2-stealth.js.map +0 -1
  82. package/dist/scraper/tiers/tier3-browser.d.ts +0 -11
  83. package/dist/scraper/tiers/tier3-browser.d.ts.map +0 -1
  84. package/dist/scraper/tiers/tier3-browser.js +0 -511
  85. package/dist/scraper/tiers/tier3-browser.js.map +0 -1
  86. package/dist/scraper/types.d.ts +0 -161
  87. package/dist/scraper/types.d.ts.map +0 -1
  88. package/dist/scraper/types.js +0 -3
  89. package/dist/scraper/types.js.map +0 -1
  90. package/dist/security/action-validator.d.ts +0 -98
  91. package/dist/security/action-validator.d.ts.map +0 -1
  92. package/dist/security/action-validator.js +0 -72
  93. package/dist/security/action-validator.js.map +0 -1
  94. package/dist/security/url-validator.d.ts +0 -9
  95. package/dist/security/url-validator.d.ts.map +0 -1
  96. package/dist/security/url-validator.js +0 -78
  97. package/dist/security/url-validator.js.map +0 -1
  98. package/dist/types.d.ts +0 -168
  99. package/dist/types.d.ts.map +0 -1
  100. package/dist/types.js +0 -2
  101. package/dist/types.js.map +0 -1
@@ -1,250 +0,0 @@
1
- import { takeSnapshot, formatSnapshot, captureScreenshot } from "../browser/snapshot.js";
2
- import { executeAction } from "../browser/executor.js";
3
- import { LLMClient } from "../llm/client.js";
4
- import { parseAndValidateAction, formatActionForHistory } from "./actions.js";
5
- import { generateReport } from "./report.js";
6
- import { warnIfNotVisionModel, isVisionModel } from "../llm/vision-models.js";
7
- // Sliding window of history sent to LLM.
8
- // Keeps the first item (initial context) + the N most recent.
9
- const HISTORY_WINDOW = 8;
10
- // Loop detection: sliding window of recent action keys.
11
- const RECENT_WINDOW = 9;
12
- const MAX_OCCURRENCES = 3;
13
- // Actions that already include their own delay — skip the inter-iteration pause
14
- const SELF_DELAYED_ACTIONS = new Set(["wait", "goto"]);
15
- // ─── Blocked page detection ─────────────────────────────────────────────────
16
- const BLOCKED_URL_PATTERNS = [
17
- "/sorry/", // Google CAPTCHA
18
- "/captcha",
19
- "/challenge",
20
- "/recaptcha",
21
- "/blocked",
22
- ];
23
- const BLOCKED_TEXT_PATTERNS = [
24
- "unusual traffic",
25
- "not a robot",
26
- "captcha",
27
- "blocked your ip",
28
- "access denied",
29
- "rate limit",
30
- ];
31
- // Real CAPTCHA/block pages are very sparse — just the challenge + a short message.
32
- // Only flag as blocked when the page has little content AND matches a pattern,
33
- // to avoid false positives on normal pages that mention "captcha" or "access denied".
34
- const BLOCKED_TEXT_MAX_LENGTH = 2_000;
35
- function isBlockedPage(snapshot) {
36
- const url = snapshot.url.toLowerCase();
37
- if (BLOCKED_URL_PATTERNS.some(p => url.includes(p)))
38
- return true;
39
- const text = snapshot.text.toLowerCase();
40
- if (text.length < BLOCKED_TEXT_MAX_LENGTH && BLOCKED_TEXT_PATTERNS.some(p => text.includes(p)))
41
- return true;
42
- return false;
43
- }
44
- function windowedHistory(history) {
45
- if (history.length <= HISTORY_WINDOW)
46
- return history;
47
- return [history[0], ...history.slice(-(HISTORY_WINDOW - 1))];
48
- }
49
- function buildResult(status, tier, data, actions, usage, peakRssKb, startTime, url, prompt, error) {
50
- const mem = process.memoryUsage();
51
- const memory = {
52
- browserPeakRssKb: peakRssKb,
53
- nodeHeapUsedMb: Math.round((mem.heapUsed / 1024 / 1024) * 100) / 100,
54
- };
55
- const durationMs = Date.now() - startTime;
56
- const result = { status, tier, data, report: "", durationMs, actions, usage, memory, error };
57
- result.report = generateReport(result, url, prompt);
58
- return result;
59
- }
60
- export async function runStaticLoop(snapshot, url, prompt, config, signal, schemaDescription) {
61
- const emptyUsage = { promptTokens: 0, completionTokens: 0, totalTokens: 0, calls: 0 };
62
- if (signal?.aborted)
63
- return { result: null, usage: emptyUsage };
64
- const startTime = Date.now();
65
- const urlOptions = {
66
- allowedDomains: config.allowedDomains,
67
- blockedDomains: config.blockedDomains,
68
- };
69
- const llm = new LLMClient(config.llmApiKey, config.model, {
70
- temperature: config.temperature,
71
- maxTokens: config.maxTokens,
72
- topP: config.topP,
73
- frequencyPenalty: config.frequencyPenalty,
74
- presencePenalty: config.presencePenalty,
75
- }, config.llmBaseUrl);
76
- const usage = { promptTokens: 0, completionTokens: 0, totalTokens: 0, calls: 0 };
77
- let raw;
78
- try {
79
- const response = await llm.decideAction(prompt, formatSnapshot(snapshot), [], schemaDescription);
80
- raw = response.data;
81
- usage.promptTokens = response.usage.promptTokens;
82
- usage.completionTokens = response.usage.completionTokens;
83
- usage.totalTokens = response.usage.totalTokens;
84
- usage.calls = 1;
85
- }
86
- catch {
87
- return { result: null, usage }; // LLM call failed — fall back to Playwright
88
- }
89
- let action;
90
- try {
91
- action = await parseAndValidateAction(raw, urlOptions);
92
- }
93
- catch {
94
- return { result: null, usage }; // Invalid action — fall back to Playwright
95
- }
96
- if (action.type === "done") {
97
- const actions = [{ action, iteration: 0, timestamp: Date.now() }];
98
- const isFailed = typeof action.result === "string" && action.result.startsWith("FAILED:");
99
- if (isFailed) {
100
- const reason = action.result.slice(7).trim() || "The agent could not complete the task.";
101
- return { result: buildResult("error", "http", null, actions, usage, 0, startTime, url, prompt, reason), usage };
102
- }
103
- return { result: buildResult("done", "http", action.result, actions, usage, 0, startTime, url, prompt), usage };
104
- }
105
- // LLM needs to navigate or interact → Playwright required
106
- return { result: null, usage };
107
- }
108
- export async function runAgentLoop(page, url, prompt, config, getMemoryKb = () => 0, loopOptions = {}) {
109
- const llm = new LLMClient(config.llmApiKey, config.model, {
110
- temperature: config.temperature,
111
- maxTokens: config.maxTokens,
112
- topP: config.topP,
113
- frequencyPenalty: config.frequencyPenalty,
114
- presencePenalty: config.presencePenalty,
115
- }, config.llmBaseUrl);
116
- const urlOptions = {
117
- allowedDomains: config.allowedDomains,
118
- blockedDomains: config.blockedDomains,
119
- };
120
- const actionDelayMs = loopOptions.actionDelayMs ?? config.actionDelayMs;
121
- const maxTotalTokens = loopOptions.maxTotalTokens ?? config.maxTotalTokens;
122
- const signal = loopOptions.signal;
123
- const maxIterations = config.maxIterations;
124
- // Auto-dismiss dialogs to prevent browser from hanging
125
- page.on("dialog", (dialog) => dialog.dismiss().catch(() => { }));
126
- const actions = [];
127
- const history = [];
128
- const usage = { promptTokens: 0, completionTokens: 0, totalTokens: 0, calls: 0 };
129
- let peakRssKb = 0;
130
- const recentActionKeys = [];
131
- const startTime = Date.now();
132
- // ── Vision auto-fallback ─────────────────────────────────────────────
133
- // When vision=true, screenshots are NOT sent from the start.
134
- // They activate automatically after consecutive failures (invalid actions,
135
- // execution errors, stuck loops) so the LLM can "see" the page.
136
- const VISION_ESCALATION_THRESHOLD = 3;
137
- const visionAvailable = config.vision && isVisionModel(config.model);
138
- let useVision = false;
139
- let consecutiveFailures = 0;
140
- if (config.vision) {
141
- warnIfNotVisionModel(config.model);
142
- }
143
- for (let i = 0; i < maxIterations; i++) {
144
- // ── Abort check ──────────────────────────────────────────────────────
145
- if (signal?.aborted) {
146
- return buildResult("aborted", "playwright", null, actions, usage, peakRssKb, startTime, url, prompt, "Aborted by user");
147
- }
148
- const currentRss = getMemoryKb();
149
- if (currentRss > peakRssKb)
150
- peakRssKb = currentRss;
151
- if (Date.now() - startTime > config.timeoutMs) {
152
- return buildResult("timeout", "playwright", null, actions, usage, peakRssKb, startTime, url, prompt, `Timeout after ${config.timeoutMs}ms`);
153
- }
154
- // ── Budget check ─────────────────────────────────────────────────────
155
- if (maxTotalTokens > 0 && usage.totalTokens >= maxTotalTokens) {
156
- return buildResult("error", "playwright", null, actions, usage, peakRssKb, startTime, url, prompt, `Token budget exceeded: ${usage.totalTokens} >= ${maxTotalTokens}`);
157
- }
158
- const snapshot = await takeSnapshot(page);
159
- loopOptions.onIteration?.(i, snapshot);
160
- // ── Blocked page detection (CAPTCHA, consent, rate-limit) ────────
161
- if (isBlockedPage(snapshot)) {
162
- return buildResult("error", "playwright", null, actions, usage, peakRssKb, startTime, url, prompt, `Blocked by target site (CAPTCHA/rate-limit detected at ${snapshot.url.slice(0, 100)})`);
163
- }
164
- const formatted = formatSnapshot(snapshot);
165
- // ── Vision: capture viewport screenshot (only after escalation) ────
166
- let screenshot;
167
- if (useVision) {
168
- try {
169
- screenshot = await captureScreenshot(page, config.screenshotQuality);
170
- }
171
- catch { /* screenshot failed — continue without it */ }
172
- }
173
- let raw;
174
- try {
175
- const response = await llm.decideAction(prompt, formatted, windowedHistory(history), loopOptions.schemaDescription, screenshot, visionAvailable);
176
- raw = response.data;
177
- usage.promptTokens += response.usage.promptTokens;
178
- usage.completionTokens += response.usage.completionTokens;
179
- usage.totalTokens += response.usage.totalTokens;
180
- usage.calls++;
181
- }
182
- catch (err) {
183
- return buildResult("error", "playwright", null, actions, usage, peakRssKb, startTime, url, prompt, `LLM error: ${err instanceof Error ? err.message : String(err)}`);
184
- }
185
- let action;
186
- try {
187
- action = await parseAndValidateAction(raw, urlOptions);
188
- }
189
- catch (err) {
190
- const msg = err instanceof Error ? err.message : String(err);
191
- loopOptions.onInvalidAction?.(i, msg);
192
- consecutiveFailures++;
193
- history.push(`[${i}] INVALID ACTION: ${msg}. Use shorter, simpler CSS selectors (#id, [name="..."], tag). Max 500 chars. No JavaScript or data: URIs.`);
194
- if (!useVision && visionAvailable && consecutiveFailures >= VISION_ESCALATION_THRESHOLD) {
195
- useVision = true;
196
- history.push(`[${i}] VISION ACTIVATED: A screenshot of the page is now included to help you understand the layout.`);
197
- }
198
- continue;
199
- }
200
- // ── Loop detection (normalized: ignore quote style & whitespace in selectors)
201
- const actionKey = JSON.stringify(action).replace(/['"]/g, "'").replace(/\s+/g, " ");
202
- const occurrencesInWindow = recentActionKeys.filter(k => k === actionKey).length;
203
- if (occurrencesInWindow >= MAX_OCCURRENCES) {
204
- consecutiveFailures++;
205
- history.push(`[${i}] STUCK: action repeated ${MAX_OCCURRENCES} times in the last ${RECENT_WINDOW} steps. ` +
206
- "You MUST try a completely different approach.");
207
- if (!useVision && visionAvailable && consecutiveFailures >= VISION_ESCALATION_THRESHOLD) {
208
- useVision = true;
209
- history.push(`[${i}] VISION ACTIVATED: A screenshot of the page is now included to help you understand the layout.`);
210
- }
211
- recentActionKeys.length = 0;
212
- continue;
213
- }
214
- recentActionKeys.push(actionKey);
215
- if (recentActionKeys.length > RECENT_WINDOW)
216
- recentActionKeys.shift();
217
- actions.push({ action, iteration: i, timestamp: Date.now() });
218
- loopOptions.onAction?.(action, i);
219
- if (action.type === "done") {
220
- const isFailed = typeof action.result === "string" && action.result.startsWith("FAILED:");
221
- if (isFailed) {
222
- const reason = action.result.slice(7).trim() || "The agent could not complete the task.";
223
- return buildResult("error", "playwright", null, actions, usage, peakRssKb, startTime, url, prompt, reason);
224
- }
225
- return buildResult("done", "playwright", action.result, actions, usage, peakRssKb, startTime, url, prompt);
226
- }
227
- try {
228
- await executeAction(page, action, urlOptions);
229
- history.push(formatActionForHistory(action, i) + " -> OK");
230
- loopOptions.onActionResult?.(i, true);
231
- consecutiveFailures = 0;
232
- }
233
- catch (err) {
234
- const msg = err instanceof Error ? err.message : String(err);
235
- loopOptions.onActionResult?.(i, false, msg);
236
- consecutiveFailures++;
237
- history.push(`[${i}] ERROR executing ${action.type}: ${msg}. Try a different approach.`);
238
- if (!useVision && visionAvailable && consecutiveFailures >= VISION_ESCALATION_THRESHOLD) {
239
- useVision = true;
240
- history.push(`[${i}] VISION ACTIVATED: A screenshot of the page is now included to help you understand the layout.`);
241
- }
242
- }
243
- // Action-specific delay: skip for actions that already have their own wait
244
- if (!SELF_DELAYED_ACTIONS.has(action.type) && actionDelayMs > 0) {
245
- await page.waitForTimeout(actionDelayMs);
246
- }
247
- }
248
- return buildResult("max_iterations", "playwright", null, actions, usage, peakRssKb, startTime, url, prompt, `Reached max iterations (${maxIterations})`);
249
- }
250
- //# sourceMappingURL=loop.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"loop.js","sourceRoot":"","sources":["../../src/agent/loop.ts"],"names":[],"mappings":"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"}
@@ -1,3 +0,0 @@
1
- import type { AgentResult } from "../types.js";
2
- export declare function generateReport(result: AgentResult, url: string, prompt: string): string;
3
- //# sourceMappingURL=report.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/agent/report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAgB,MAAM,aAAa,CAAC;AAoE7D,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAoDvF"}
@@ -1,107 +0,0 @@
1
- function describeAction(record) {
2
- const { action } = record;
3
- switch (action.type) {
4
- case "click":
5
- return `Clicked element "${action.selector}"`;
6
- case "type":
7
- return `Typed "${action.text}" into "${action.selector}"`;
8
- case "select":
9
- return `Selected "${action.value}" in "${action.selector}"`;
10
- case "pressKey":
11
- return `Pressed key "${action.key}"`;
12
- case "hover":
13
- return `Hovered over "${action.selector}"`;
14
- case "goto":
15
- return `Navigated to ${action.url}`;
16
- case "wait":
17
- return `Waited ${action.ms}ms`;
18
- case "scroll":
19
- return `Scrolled ${action.direction}${action.amount ? ` ${action.amount}px` : ""}`;
20
- case "done": {
21
- const r = action.result;
22
- if (typeof r === "string" && r.startsWith("FAILED:")) {
23
- return `Failed: ${r.slice(7).trim()}`;
24
- }
25
- return `Finished with result`;
26
- }
27
- }
28
- }
29
- function describeStatus(result) {
30
- switch (result.status) {
31
- case "done":
32
- return "Task completed successfully.";
33
- case "max_iterations":
34
- return "Task interrupted: reached the iteration limit without completing.";
35
- case "timeout":
36
- return "Task interrupted: timeout exceeded.";
37
- case "aborted":
38
- return "Task aborted by user.";
39
- case "error":
40
- return `Task interrupted by error: ${result.error}`;
41
- }
42
- }
43
- function describeTier(result) {
44
- if (result.tier === "http") {
45
- return "HTTP/Cheerio (no browser — static page)";
46
- }
47
- return "Playwright Chromium (full browser — JS required)";
48
- }
49
- function describeMemory(result) {
50
- const node = `Node.js heap ${result.memory.nodeHeapUsedMb} MB`;
51
- if (result.tier === "http") {
52
- return `${node} | Browser: not used`;
53
- }
54
- if (result.memory.browserPeakRssKb > 0) {
55
- const browserMb = (result.memory.browserPeakRssKb / 1024).toFixed(1);
56
- return `${node} | Chromium peak ${browserMb} MB`;
57
- }
58
- return `${node} | Chromium: RSS not available`;
59
- }
60
- export function generateReport(result, url, prompt) {
61
- const lines = [];
62
- const duration = (result.durationMs / 1000).toFixed(1);
63
- lines.push("═══════════════════════════════════════════");
64
- lines.push(" EXECUTION REPORT — auspex");
65
- lines.push("═══════════════════════════════════════════");
66
- lines.push("");
67
- lines.push(` URL : ${url}`);
68
- lines.push(` Prompt : ${prompt}`);
69
- lines.push(` Status : ${describeStatus(result)}`);
70
- lines.push(` Method : ${describeTier(result)}`);
71
- lines.push(` Duration: ${duration}s`);
72
- lines.push("");
73
- if (result.actions.length > 0) {
74
- lines.push("───────────────────────────────────────────");
75
- lines.push(" STEP BY STEP");
76
- lines.push("───────────────────────────────────────────");
77
- lines.push("");
78
- for (const record of result.actions) {
79
- const step = record.iteration + 1;
80
- lines.push(` ${step}. ${describeAction(record)}`);
81
- }
82
- lines.push("");
83
- }
84
- if (result.data !== null && result.data !== undefined) {
85
- lines.push("───────────────────────────────────────────");
86
- lines.push(" RESULT");
87
- lines.push("───────────────────────────────────────────");
88
- lines.push("");
89
- const dataStr = typeof result.data === "string"
90
- ? result.data
91
- : JSON.stringify(result.data, null, 2);
92
- const maxResultChars = 10_000;
93
- lines.push(dataStr.length <= maxResultChars ? dataStr : dataStr.slice(0, maxResultChars) + "\n... (truncated)");
94
- lines.push("");
95
- }
96
- lines.push("───────────────────────────────────────────");
97
- lines.push(" RESOURCE USAGE");
98
- lines.push("───────────────────────────────────────────");
99
- lines.push("");
100
- lines.push(` LLM : ${result.usage.calls} call(s) | ${result.usage.totalTokens} tokens`);
101
- lines.push(` > ${result.usage.promptTokens} prompt + ${result.usage.completionTokens} completion`);
102
- lines.push(` RAM : ${describeMemory(result)}`);
103
- lines.push("");
104
- lines.push("═══════════════════════════════════════════");
105
- return lines.join("\n");
106
- }
107
- //# sourceMappingURL=report.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/agent/report.ts"],"names":[],"mappings":"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"}
@@ -1,5 +0,0 @@
1
- import type { Page } from "playwright-core";
2
- import type { AgentAction } from "../types.js";
3
- import { type UrlValidationOptions } from "../security/url-validator.js";
4
- export declare function executeAction(page: Page, action: AgentAction, urlOptions: UrlValidationOptions): Promise<void>;
5
- //# sourceMappingURL=executor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/browser/executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAW,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAe,KAAK,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAetF,wBAAsB,aAAa,CACjC,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,WAAW,EACnB,UAAU,EAAE,oBAAoB,GAC/B,OAAO,CAAC,IAAI,CAAC,CA2Ef"}
@@ -1,87 +0,0 @@
1
- import { validateUrl } from "../security/url-validator.js";
2
- // ─── Role-based locator resolution ──────────────────────────────────────────
3
- // Matches: role=button, role=button[name="Submit"], role=textbox[name="Search"]
4
- const ROLE_SELECTOR_RE = /^role=(\w+)(?:\[name="(.*)"\])?$/;
5
- function resolveLocator(page, selector) {
6
- const match = selector.match(ROLE_SELECTOR_RE);
7
- if (!match)
8
- return null;
9
- const role = match[1];
10
- const name = match[2]?.replace(/\\"/g, '"');
11
- const loc = name ? page.getByRole(role, { name }) : page.getByRole(role);
12
- return loc.first();
13
- }
14
- export async function executeAction(page, action, urlOptions) {
15
- switch (action.type) {
16
- case "click": {
17
- const loc = resolveLocator(page, action.selector);
18
- if (loc) {
19
- await loc.click({ timeout: 10_000 });
20
- }
21
- else {
22
- const [clickResult] = await Promise.allSettled([
23
- page.click(action.selector, { timeout: 10_000 }),
24
- ]);
25
- if (clickResult.status === "rejected")
26
- throw clickResult.reason;
27
- }
28
- await page.waitForLoadState("domcontentloaded", { timeout: 5_000 }).catch(() => { });
29
- break;
30
- }
31
- case "type": {
32
- const loc = resolveLocator(page, action.selector);
33
- if (loc) {
34
- await loc.fill(action.text, { timeout: 5_000 });
35
- }
36
- else {
37
- await page.fill(action.selector, action.text, { timeout: 5_000 });
38
- }
39
- break;
40
- }
41
- case "select": {
42
- const loc = resolveLocator(page, action.selector);
43
- if (loc) {
44
- await loc.selectOption(action.value, { timeout: 5_000 });
45
- }
46
- else {
47
- await page.selectOption(action.selector, action.value, { timeout: 5_000 });
48
- }
49
- break;
50
- }
51
- case "pressKey":
52
- await page.keyboard.press(action.key);
53
- // Enter/Return often triggers navigation — wait for it to settle
54
- if (/^enter$/i.test(action.key)) {
55
- await page.waitForLoadState("domcontentloaded", { timeout: 5_000 }).catch(() => { });
56
- }
57
- break;
58
- case "hover": {
59
- const loc = resolveLocator(page, action.selector);
60
- if (loc) {
61
- await loc.hover({ timeout: 5_000 });
62
- }
63
- else {
64
- await page.hover(action.selector, { timeout: 5_000 });
65
- }
66
- break;
67
- }
68
- case "goto": {
69
- const validUrl = await validateUrl(action.url, urlOptions);
70
- await page.goto(validUrl, { waitUntil: "domcontentloaded", timeout: 30_000 });
71
- break;
72
- }
73
- case "wait":
74
- await page.waitForTimeout(action.ms);
75
- break;
76
- case "scroll": {
77
- const amount = action.amount ?? 500;
78
- await page.evaluate(({ dir, px }) => {
79
- window.scrollBy(0, dir === "down" ? px : -px);
80
- }, { dir: action.direction, px: amount });
81
- break;
82
- }
83
- case "done":
84
- break;
85
- }
86
- }
87
- //# sourceMappingURL=executor.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/browser/executor.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAA6B,MAAM,8BAA8B,CAAC;AAEtF,+EAA+E;AAC/E,gFAAgF;AAChF,MAAM,gBAAgB,GAAG,kCAAkC,CAAC;AAE5D,SAAS,cAAc,CAAC,IAAU,EAAE,QAAgB;IAClD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAC/C,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAqC,CAAC;IAC1D,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACzE,OAAO,GAAG,CAAC,KAAK,EAAE,CAAC;AACrB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAAU,EACV,MAAmB,EACnB,UAAgC;IAEhC,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,GAAG,GAAG,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;YAClD,IAAI,GAAG,EAAE,CAAC;gBACR,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YACvC,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,WAAW,CAAC,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC;oBAC7C,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;iBACjD,CAAC,CAAC;gBACH,IAAI,WAAW,CAAC,MAAM,KAAK,UAAU;oBAAE,MAAM,WAAW,CAAC,MAAM,CAAC;YAClE,CAAC;YACD,MAAM,IAAI,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YACpF,MAAM;QACR,CAAC;QAED,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,GAAG,GAAG,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;YAClD,IAAI,GAAG,EAAE,CAAC;gBACR,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;YAClD,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;YACpE,CAAC;YACD,MAAM;QACR,CAAC;QAED,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,GAAG,GAAG,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;YAClD,IAAI,GAAG,EAAE,CAAC;gBACR,MAAM,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;YAC3D,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;YAC7E,CAAC;YACD,MAAM;QACR,CAAC;QAED,KAAK,UAAU;YACb,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACtC,iEAAiE;YACjE,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;gBAChC,MAAM,IAAI,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YACtF,CAAC;YACD,MAAM;QAER,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,GAAG,GAAG,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;YAClD,IAAI,GAAG,EAAE,CAAC;gBACR,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;YACtC,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;YACxD,CAAC;YACD,MAAM;QACR,CAAC;QAED,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;YAC3D,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YAC9E,MAAM;QACR,CAAC;QAED,KAAK,MAAM;YACT,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACrC,MAAM;QAER,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC;YACpC,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,EAA+B,EAAE,EAAE;gBAC/D,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAChD,CAAC,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;YAC1C,MAAM;QACR,CAAC;QAED,KAAK,MAAM;YACT,MAAM;IACV,CAAC;AACH,CAAC"}
@@ -1,33 +0,0 @@
1
- import { type Browser, type LaunchOptions } from "playwright";
2
- export interface BrowserPoolOptions {
3
- /** Maximum number of browser instances. Default: 3 */
4
- maxSize?: number;
5
- /** Playwright launch options applied to all browsers */
6
- launchOptions?: LaunchOptions;
7
- /** Timeout in ms to wait for an available browser. Default: 30000 */
8
- acquireTimeoutMs?: number;
9
- }
10
- export declare class BrowserPool {
11
- private readonly maxSize;
12
- private readonly launchOptions;
13
- private readonly acquireTimeoutMs;
14
- private readonly browsers;
15
- private readonly available;
16
- private readonly waitQueue;
17
- private closed;
18
- constructor(options?: BrowserPoolOptions);
19
- /** Acquire a browser instance. Blocks if all are in use and pool is at max capacity. */
20
- acquire(): Promise<Browser>;
21
- /** Release a browser back to the pool. */
22
- release(browser: Browser): void;
23
- /** Close all browsers and reject any waiters. */
24
- close(): Promise<void>;
25
- /** Current pool statistics. */
26
- get stats(): {
27
- total: number;
28
- available: number;
29
- waiting: number;
30
- maxSize: number;
31
- };
32
- }
33
- //# sourceMappingURL=pool.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../../src/browser/pool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAExE,MAAM,WAAW,kBAAkB;IACjC,sDAAsD;IACtD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wDAAwD;IACxD,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,qEAAqE;IACrE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAQD,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiB;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgB;IAC1C,OAAO,CAAC,MAAM,CAAS;gBAEX,OAAO,GAAE,kBAAuB;IAS5C,wFAAwF;IAClF,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IAwCjC,0CAA0C;IAC1C,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAuB/B,iDAAiD;IAC3C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAc5B,+BAA+B;IAC/B,IAAI,KAAK,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAOlF;CACF"}
@@ -1,101 +0,0 @@
1
- import { chromium } from "playwright";
2
- export class BrowserPool {
3
- maxSize;
4
- launchOptions;
5
- acquireTimeoutMs;
6
- browsers = [];
7
- available = [];
8
- waitQueue = [];
9
- closed = false;
10
- constructor(options = {}) {
11
- this.maxSize = options.maxSize ?? 3;
12
- this.acquireTimeoutMs = options.acquireTimeoutMs ?? 30_000;
13
- this.launchOptions = options.launchOptions ?? {
14
- headless: true,
15
- args: ["--disable-blink-features=AutomationControlled"],
16
- };
17
- }
18
- /** Acquire a browser instance. Blocks if all are in use and pool is at max capacity. */
19
- async acquire() {
20
- if (this.closed)
21
- throw new Error("BrowserPool is closed");
22
- // 1. Reuse an available (idle) browser
23
- while (this.available.length > 0) {
24
- const browser = this.available.pop();
25
- if (browser.isConnected())
26
- return browser;
27
- // Browser died — remove from tracking
28
- const idx = this.browsers.indexOf(browser);
29
- if (idx >= 0)
30
- this.browsers.splice(idx, 1);
31
- }
32
- // 2. Launch a new one if under capacity
33
- if (this.browsers.length < this.maxSize) {
34
- const browser = await chromium.launch(this.launchOptions);
35
- this.browsers.push(browser);
36
- // Auto-remove from pool if browser crashes
37
- browser.on("disconnected", () => {
38
- const idx = this.browsers.indexOf(browser);
39
- if (idx >= 0)
40
- this.browsers.splice(idx, 1);
41
- const availIdx = this.available.indexOf(browser);
42
- if (availIdx >= 0)
43
- this.available.splice(availIdx, 1);
44
- });
45
- return browser;
46
- }
47
- // 3. All browsers busy — wait in queue with timeout
48
- return new Promise((resolve, reject) => {
49
- const timer = setTimeout(() => {
50
- const idx = this.waitQueue.findIndex((w) => w.resolve === resolve);
51
- if (idx >= 0)
52
- this.waitQueue.splice(idx, 1);
53
- reject(new Error(`BrowserPool acquire timeout after ${this.acquireTimeoutMs}ms`));
54
- }, this.acquireTimeoutMs);
55
- this.waitQueue.push({ resolve, reject, timer });
56
- });
57
- }
58
- /** Release a browser back to the pool. */
59
- release(browser) {
60
- if (this.closed) {
61
- browser.close().catch(() => { });
62
- return;
63
- }
64
- if (!browser.isConnected()) {
65
- const idx = this.browsers.indexOf(browser);
66
- if (idx >= 0)
67
- this.browsers.splice(idx, 1);
68
- return;
69
- }
70
- // If someone is waiting, give it directly
71
- if (this.waitQueue.length > 0) {
72
- const waiter = this.waitQueue.shift();
73
- clearTimeout(waiter.timer);
74
- waiter.resolve(browser);
75
- return;
76
- }
77
- this.available.push(browser);
78
- }
79
- /** Close all browsers and reject any waiters. */
80
- async close() {
81
- this.closed = true;
82
- for (const waiter of this.waitQueue) {
83
- clearTimeout(waiter.timer);
84
- waiter.reject(new Error("BrowserPool is closing"));
85
- }
86
- this.waitQueue.length = 0;
87
- await Promise.allSettled(this.browsers.map((b) => b.close()));
88
- this.browsers.length = 0;
89
- this.available.length = 0;
90
- }
91
- /** Current pool statistics. */
92
- get stats() {
93
- return {
94
- total: this.browsers.length,
95
- available: this.available.length,
96
- waiting: this.waitQueue.length,
97
- maxSize: this.maxSize,
98
- };
99
- }
100
- }
101
- //# sourceMappingURL=pool.js.map