@browserbasehq/orca 3.2.0-preview.4 → 3.2.0-preview.5
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/cjs/lib/inference.d.ts +3 -1
- package/dist/cjs/lib/inference.js +2 -2
- package/dist/cjs/lib/inference.js.map +1 -1
- package/dist/cjs/lib/prompt.d.ts +1 -1
- package/dist/cjs/lib/prompt.js +11 -2
- package/dist/cjs/lib/prompt.js.map +1 -1
- package/dist/cjs/lib/v3/agent/AgentClient.d.ts +8 -0
- package/dist/cjs/lib/v3/agent/AgentClient.js +13 -0
- package/dist/cjs/lib/v3/agent/AgentClient.js.map +1 -1
- package/dist/cjs/lib/v3/agent/AnthropicCUAClient.js +1 -0
- package/dist/cjs/lib/v3/agent/AnthropicCUAClient.js.map +1 -1
- package/dist/cjs/lib/v3/agent/GoogleCUAClient.js +1 -0
- package/dist/cjs/lib/v3/agent/GoogleCUAClient.js.map +1 -1
- package/dist/cjs/lib/v3/agent/MicrosoftCUAClient.js +1 -0
- package/dist/cjs/lib/v3/agent/MicrosoftCUAClient.js.map +1 -1
- package/dist/cjs/lib/v3/agent/OpenAICUAClient.d.ts +4 -4
- package/dist/cjs/lib/v3/agent/OpenAICUAClient.js +62 -1
- package/dist/cjs/lib/v3/agent/OpenAICUAClient.js.map +1 -1
- package/dist/cjs/lib/v3/agent/prompts/agentSystemPrompt.d.ts +2 -2
- package/dist/cjs/lib/v3/agent/prompts/agentSystemPrompt.js +10 -11
- package/dist/cjs/lib/v3/agent/prompts/agentSystemPrompt.js.map +1 -1
- package/dist/cjs/lib/v3/agent/tools/fillform.d.ts +0 -1
- package/dist/cjs/lib/v3/agent/tools/fillform.js +7 -10
- package/dist/cjs/lib/v3/agent/tools/fillform.js.map +1 -1
- package/dist/cjs/lib/v3/agent/utils/captchaSolver.d.ts +76 -0
- package/dist/cjs/lib/v3/agent/utils/captchaSolver.js +175 -0
- package/dist/cjs/lib/v3/agent/utils/captchaSolver.js.map +1 -0
- package/dist/cjs/lib/v3/agent/utils/variables.d.ts +5 -0
- package/dist/cjs/lib/v3/agent/utils/variables.js +9 -0
- package/dist/cjs/lib/v3/agent/utils/variables.js.map +1 -1
- package/dist/cjs/lib/v3/api.js +2 -9
- package/dist/cjs/lib/v3/api.js.map +1 -1
- package/dist/cjs/lib/v3/flowlogger/EventStore.js +1 -1
- package/dist/cjs/lib/v3/flowlogger/EventStore.js.map +1 -1
- package/dist/cjs/lib/v3/handlers/observeHandler.js +2 -1
- package/dist/cjs/lib/v3/handlers/observeHandler.js.map +1 -1
- package/dist/cjs/lib/v3/handlers/v3AgentHandler.d.ts +2 -1
- package/dist/cjs/lib/v3/handlers/v3AgentHandler.js +110 -46
- package/dist/cjs/lib/v3/handlers/v3AgentHandler.js.map +1 -1
- package/dist/cjs/lib/v3/handlers/v3CuaAgentHandler.d.ts +5 -0
- package/dist/cjs/lib/v3/handlers/v3CuaAgentHandler.js +125 -1
- package/dist/cjs/lib/v3/handlers/v3CuaAgentHandler.js.map +1 -1
- package/dist/cjs/lib/v3/types/private/cache.d.ts +0 -1
- package/dist/cjs/lib/v3/types/private/cache.js.map +1 -1
- package/dist/cjs/lib/v3/types/private/handlers.d.ts +1 -0
- package/dist/cjs/lib/v3/types/private/handlers.js.map +1 -1
- package/dist/cjs/lib/v3/types/public/api.d.ts +24 -7
- package/dist/cjs/lib/v3/types/public/api.js +41 -14
- package/dist/cjs/lib/v3/types/public/api.js.map +1 -1
- package/dist/cjs/lib/v3/types/public/methods.d.ts +1 -0
- package/dist/cjs/lib/v3/types/public/methods.js.map +1 -1
- package/dist/cjs/lib/v3/types/public/variables.d.ts +7 -0
- package/dist/cjs/lib/v3/types/public/variables.js +22 -0
- package/dist/cjs/lib/v3/types/public/variables.js.map +1 -0
- package/dist/cjs/lib/v3/v3.d.ts +5 -0
- package/dist/cjs/lib/v3/v3.js +19 -4
- package/dist/cjs/lib/v3/v3.js.map +1 -1
- package/dist/cjs/lib/version.d.ts +1 -1
- package/dist/cjs/lib/version.js +1 -1
- package/dist/cjs/lib/version.js.map +1 -1
- package/dist/cjs/tests/integration/agent-captcha-autosolve.spec.d.ts +1 -0
- package/dist/cjs/tests/integration/agent-captcha-autosolve.spec.js +56 -0
- package/dist/cjs/tests/integration/agent-captcha-autosolve.spec.js.map +1 -0
- package/dist/cjs/tests/integration/agent-hybrid-mode.spec.js +6 -6
- package/dist/cjs/tests/integration/agent-hybrid-mode.spec.js.map +1 -1
- package/dist/cjs/tests/integration/timeouts.spec.js +1 -1
- package/dist/cjs/tests/integration/timeouts.spec.js.map +1 -1
- package/dist/cjs/tests/unit/agent-captcha-hooks.test.d.ts +1 -0
- package/dist/cjs/tests/unit/agent-captcha-hooks.test.js +285 -0
- package/dist/cjs/tests/unit/agent-captcha-hooks.test.js.map +1 -0
- package/dist/cjs/tests/unit/agent-execution-model.test.js +25 -3
- package/dist/cjs/tests/unit/agent-execution-model.test.js.map +1 -1
- package/dist/cjs/tests/unit/agent-system-prompt-variables.test.d.ts +1 -0
- package/dist/cjs/tests/unit/agent-system-prompt-variables.test.js +23 -0
- package/dist/cjs/tests/unit/agent-system-prompt-variables.test.js.map +1 -0
- package/dist/cjs/tests/unit/api-client-observe-variables.test.d.ts +1 -0
- package/dist/cjs/tests/unit/api-client-observe-variables.test.js +86 -0
- package/dist/cjs/tests/unit/api-client-observe-variables.test.js.map +1 -0
- package/dist/cjs/tests/unit/api-variables-schema.test.d.ts +1 -0
- package/dist/cjs/tests/unit/api-variables-schema.test.js +37 -0
- package/dist/cjs/tests/unit/api-variables-schema.test.js.map +1 -0
- package/dist/cjs/tests/unit/browserbase-session-accessors.test.js +20 -0
- package/dist/cjs/tests/unit/browserbase-session-accessors.test.js.map +1 -1
- package/dist/cjs/tests/unit/captcha-solver.test.d.ts +1 -0
- package/dist/cjs/tests/unit/captcha-solver.test.js +154 -0
- package/dist/cjs/tests/unit/captcha-solver.test.js.map +1 -0
- package/dist/cjs/tests/unit/flowlogger-eventstore.test.js +1 -1
- package/dist/cjs/tests/unit/flowlogger-eventstore.test.js.map +1 -1
- package/dist/cjs/tests/unit/openai-cua-client.test.d.ts +1 -0
- package/dist/cjs/tests/unit/openai-cua-client.test.js +71 -0
- package/dist/cjs/tests/unit/openai-cua-client.test.js.map +1 -0
- package/dist/cjs/tests/unit/prompt-observe-variables.test.d.ts +1 -0
- package/dist/cjs/tests/unit/prompt-observe-variables.test.js +19 -0
- package/dist/cjs/tests/unit/prompt-observe-variables.test.js.map +1 -0
- package/dist/cjs/tests/unit/public-api/public-types.test.js.map +1 -1
- package/dist/cjs/tests/unit/timeout-handlers.test.js +50 -0
- package/dist/cjs/tests/unit/timeout-handlers.test.js.map +1 -1
- package/dist/esm/lib/inference.d.ts +3 -1
- package/dist/esm/lib/inference.js +2 -2
- package/dist/esm/lib/inference.js.map +1 -1
- package/dist/esm/lib/prompt.d.ts +1 -1
- package/dist/esm/lib/prompt.js +11 -2
- package/dist/esm/lib/prompt.js.map +1 -1
- package/dist/esm/lib/v3/agent/AgentClient.d.ts +8 -0
- package/dist/esm/lib/v3/agent/AgentClient.js +13 -0
- package/dist/esm/lib/v3/agent/AgentClient.js.map +1 -1
- package/dist/esm/lib/v3/agent/AnthropicCUAClient.js +1 -0
- package/dist/esm/lib/v3/agent/AnthropicCUAClient.js.map +1 -1
- package/dist/esm/lib/v3/agent/GoogleCUAClient.js +1 -0
- package/dist/esm/lib/v3/agent/GoogleCUAClient.js.map +1 -1
- package/dist/esm/lib/v3/agent/MicrosoftCUAClient.js +1 -0
- package/dist/esm/lib/v3/agent/MicrosoftCUAClient.js.map +1 -1
- package/dist/esm/lib/v3/agent/OpenAICUAClient.d.ts +4 -4
- package/dist/esm/lib/v3/agent/OpenAICUAClient.js +62 -1
- package/dist/esm/lib/v3/agent/OpenAICUAClient.js.map +1 -1
- package/dist/esm/lib/v3/agent/prompts/agentSystemPrompt.d.ts +2 -2
- package/dist/esm/lib/v3/agent/prompts/agentSystemPrompt.js +10 -11
- package/dist/esm/lib/v3/agent/prompts/agentSystemPrompt.js.map +1 -1
- package/dist/esm/lib/v3/agent/tools/fillform.d.ts +0 -1
- package/dist/esm/lib/v3/agent/tools/fillform.js +7 -10
- package/dist/esm/lib/v3/agent/tools/fillform.js.map +1 -1
- package/dist/esm/lib/v3/agent/utils/captchaSolver.d.ts +76 -0
- package/dist/esm/lib/v3/agent/utils/captchaSolver.js +171 -0
- package/dist/esm/lib/v3/agent/utils/captchaSolver.js.map +1 -0
- package/dist/esm/lib/v3/agent/utils/variables.d.ts +5 -0
- package/dist/esm/lib/v3/agent/utils/variables.js +8 -0
- package/dist/esm/lib/v3/agent/utils/variables.js.map +1 -1
- package/dist/esm/lib/v3/api.js +2 -9
- package/dist/esm/lib/v3/api.js.map +1 -1
- package/dist/esm/lib/v3/flowlogger/EventStore.js +1 -1
- package/dist/esm/lib/v3/flowlogger/EventStore.js.map +1 -1
- package/dist/esm/lib/v3/handlers/observeHandler.js +2 -1
- package/dist/esm/lib/v3/handlers/observeHandler.js.map +1 -1
- package/dist/esm/lib/v3/handlers/v3AgentHandler.d.ts +2 -1
- package/dist/esm/lib/v3/handlers/v3AgentHandler.js +110 -46
- package/dist/esm/lib/v3/handlers/v3AgentHandler.js.map +1 -1
- package/dist/esm/lib/v3/handlers/v3CuaAgentHandler.d.ts +5 -0
- package/dist/esm/lib/v3/handlers/v3CuaAgentHandler.js +125 -1
- package/dist/esm/lib/v3/handlers/v3CuaAgentHandler.js.map +1 -1
- package/dist/esm/lib/v3/types/private/cache.d.ts +0 -1
- package/dist/esm/lib/v3/types/private/cache.js.map +1 -1
- package/dist/esm/lib/v3/types/private/handlers.d.ts +1 -0
- package/dist/esm/lib/v3/types/private/handlers.js.map +1 -1
- package/dist/esm/lib/v3/types/public/api.d.ts +24 -7
- package/dist/esm/lib/v3/types/public/api.js +36 -12
- package/dist/esm/lib/v3/types/public/api.js.map +1 -1
- package/dist/esm/lib/v3/types/public/methods.d.ts +1 -0
- package/dist/esm/lib/v3/types/public/methods.js.map +1 -1
- package/dist/esm/lib/v3/types/public/variables.d.ts +7 -0
- package/dist/esm/lib/v3/types/public/variables.js +19 -0
- package/dist/esm/lib/v3/types/public/variables.js.map +1 -0
- package/dist/esm/lib/v3/v3.d.ts +5 -0
- package/dist/esm/lib/v3/v3.js +19 -4
- package/dist/esm/lib/v3/v3.js.map +1 -1
- package/dist/esm/lib/version.d.ts +1 -1
- package/dist/esm/lib/version.js +1 -1
- package/dist/esm/lib/version.js.map +1 -1
- package/dist/esm/tests/integration/agent-captcha-autosolve.spec.d.ts +1 -0
- package/dist/esm/tests/integration/agent-captcha-autosolve.spec.js +54 -0
- package/dist/esm/tests/integration/agent-captcha-autosolve.spec.js.map +1 -0
- package/dist/esm/tests/integration/agent-hybrid-mode.spec.js +6 -6
- package/dist/esm/tests/integration/agent-hybrid-mode.spec.js.map +1 -1
- package/dist/esm/tests/integration/timeouts.spec.js +1 -1
- package/dist/esm/tests/integration/timeouts.spec.js.map +1 -1
- package/dist/esm/tests/unit/agent-captcha-hooks.test.d.ts +1 -0
- package/dist/esm/tests/unit/agent-captcha-hooks.test.js +283 -0
- package/dist/esm/tests/unit/agent-captcha-hooks.test.js.map +1 -0
- package/dist/esm/tests/unit/agent-execution-model.test.js +25 -3
- package/dist/esm/tests/unit/agent-execution-model.test.js.map +1 -1
- package/dist/esm/tests/unit/agent-system-prompt-variables.test.d.ts +1 -0
- package/dist/esm/tests/unit/agent-system-prompt-variables.test.js +21 -0
- package/dist/esm/tests/unit/agent-system-prompt-variables.test.js.map +1 -0
- package/dist/esm/tests/unit/api-client-observe-variables.test.d.ts +1 -0
- package/dist/esm/tests/unit/api-client-observe-variables.test.js +84 -0
- package/dist/esm/tests/unit/api-client-observe-variables.test.js.map +1 -0
- package/dist/esm/tests/unit/api-variables-schema.test.d.ts +1 -0
- package/dist/esm/tests/unit/api-variables-schema.test.js +35 -0
- package/dist/esm/tests/unit/api-variables-schema.test.js.map +1 -0
- package/dist/esm/tests/unit/browserbase-session-accessors.test.js +20 -0
- package/dist/esm/tests/unit/browserbase-session-accessors.test.js.map +1 -1
- package/dist/esm/tests/unit/captcha-solver.test.d.ts +1 -0
- package/dist/esm/tests/unit/captcha-solver.test.js +152 -0
- package/dist/esm/tests/unit/captcha-solver.test.js.map +1 -0
- package/dist/esm/tests/unit/flowlogger-eventstore.test.js +1 -1
- package/dist/esm/tests/unit/flowlogger-eventstore.test.js.map +1 -1
- package/dist/esm/tests/unit/openai-cua-client.test.d.ts +1 -0
- package/dist/esm/tests/unit/openai-cua-client.test.js +69 -0
- package/dist/esm/tests/unit/openai-cua-client.test.js.map +1 -0
- package/dist/esm/tests/unit/prompt-observe-variables.test.d.ts +1 -0
- package/dist/esm/tests/unit/prompt-observe-variables.test.js +17 -0
- package/dist/esm/tests/unit/prompt-observe-variables.test.js.map +1 -0
- package/dist/esm/tests/unit/public-api/public-types.test.js.map +1 -1
- package/dist/esm/tests/unit/timeout-handlers.test.js +50 -0
- package/dist/esm/tests/unit/timeout-handlers.test.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../../lib/version.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAgB,CAAC","sourcesContent":["/**\n * AUTO-GENERATED — DO NOT EDIT BY HAND\n * Run `pnpm run gen-version` to refresh.\n */\nexport const STAGEHAND_VERSION = \"3.
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../../lib/version.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAgB,CAAC","sourcesContent":["/**\n * AUTO-GENERATED — DO NOT EDIT BY HAND\n * Run `pnpm run gen-version` to refresh.\n */\nexport const STAGEHAND_VERSION = \"3.2.0\" as const;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { test, expect } from "@playwright/test";
|
|
2
|
+
import { V3 } from "../../lib/v3/v3.js";
|
|
3
|
+
import { getV3TestConfig } from "./v3.config.js";
|
|
4
|
+
const isBrowserbase = (process.env.STAGEHAND_BROWSER_TARGET ?? "local").toLowerCase() ===
|
|
5
|
+
"browserbase";
|
|
6
|
+
test.describe("Agent captcha auto-solve on Browserbase", () => {
|
|
7
|
+
test.skip(!isBrowserbase, "Requires Browserbase environment");
|
|
8
|
+
let v3;
|
|
9
|
+
let logs;
|
|
10
|
+
test.beforeEach(async () => {
|
|
11
|
+
logs = [];
|
|
12
|
+
v3 = new V3(getV3TestConfig({
|
|
13
|
+
env: "BROWSERBASE",
|
|
14
|
+
verbose: 2,
|
|
15
|
+
logger: (line) => {
|
|
16
|
+
logs.push(line);
|
|
17
|
+
console.log(`[${line.category}] ${line.message}`);
|
|
18
|
+
},
|
|
19
|
+
browserbaseSessionCreateParams: {
|
|
20
|
+
browserSettings: {
|
|
21
|
+
solveCaptchas: true,
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
}));
|
|
25
|
+
await v3.init();
|
|
26
|
+
console.log("BB session URL:", v3.browserbaseSessionURL);
|
|
27
|
+
});
|
|
28
|
+
test.afterEach(async () => {
|
|
29
|
+
await v3?.close?.().catch(() => { });
|
|
30
|
+
});
|
|
31
|
+
test("reCAPTCHA v2 auto-solve (Google demo)", async () => {
|
|
32
|
+
test.setTimeout(180_000);
|
|
33
|
+
const page = v3.context.pages()[0];
|
|
34
|
+
// Google's official reCAPTCHA v2 demo — same URL the stealth team tests.
|
|
35
|
+
// Use domcontentloaded since BB's route interception can delay full load.
|
|
36
|
+
await page.goto("https://www.google.com/recaptcha/api2/demo", {
|
|
37
|
+
waitUntil: "domcontentloaded",
|
|
38
|
+
});
|
|
39
|
+
// Give BB time to intercept the anchor request and solve the captcha
|
|
40
|
+
await new Promise((r) => setTimeout(r, 30_000));
|
|
41
|
+
const agent = v3.agent({
|
|
42
|
+
mode: "dom",
|
|
43
|
+
model: "anthropic/claude-haiku-4-5-20251001",
|
|
44
|
+
});
|
|
45
|
+
const result = await agent.execute({
|
|
46
|
+
instruction: 'Click the "Submit" button and report the exact text shown on the result page.',
|
|
47
|
+
maxSteps: 15,
|
|
48
|
+
});
|
|
49
|
+
console.log("reCAPTCHA v2 result:", result.message);
|
|
50
|
+
expect(result.completed).toBe(true);
|
|
51
|
+
expect(result.message.toLowerCase()).toContain("success");
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
//# sourceMappingURL=agent-captcha-autosolve.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-captcha-autosolve.spec.js","sourceRoot":"","sources":["../../../../tests/integration/agent-captcha-autosolve.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGjD,MAAM,aAAa,GACjB,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,OAAO,CAAC,CAAC,WAAW,EAAE;IAC/D,aAAa,CAAC;AAEhB,IAAI,CAAC,QAAQ,CAAC,yCAAyC,EAAE,GAAG,EAAE;IAC5D,IAAI,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,kCAAkC,CAAC,CAAC;IAE9D,IAAI,EAAM,CAAC;IACX,IAAI,IAAe,CAAC;IAEpB,IAAI,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE;QACzB,IAAI,GAAG,EAAE,CAAC;QACV,EAAE,GAAG,IAAI,EAAE,CACT,eAAe,CAAC;YACd,GAAG,EAAE,aAAa;YAClB,OAAO,EAAE,CAAC;YACV,MAAM,EAAE,CAAC,IAAa,EAAE,EAAE;gBACxB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAChB,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;YACpD,CAAC;YACD,8BAA8B,EAAE;gBAC9B,eAAe,EAAE;oBACf,aAAa,EAAE,IAAI;iBACpB;aACF;SACF,CAAC,CACH,CAAC;QACF,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,EAAE,CAAC,qBAAqB,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,EAAE;QACxB,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACvD,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACzB,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;QACnC,yEAAyE;QACzE,0EAA0E;QAC1E,MAAM,IAAI,CAAC,IAAI,CAAC,4CAA4C,EAAE;YAC5D,SAAS,EAAE,kBAAkB;SAC9B,CAAC,CAAC;QAEH,qEAAqE;QACrE,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QAEhD,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC;YACrB,IAAI,EAAE,KAAK;YACX,KAAK,EAAE,qCAAqC;SAC7C,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC;YACjC,WAAW,EACT,+EAA+E;YACjF,QAAQ,EAAE,EAAE;SACb,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;QAEpD,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { test, expect } from \"@playwright/test\";\nimport { V3 } from \"../../lib/v3/v3.js\";\nimport { getV3TestConfig } from \"./v3.config.js\";\nimport type { LogLine } from \"../../lib/v3/types/public/logs.js\";\n\nconst isBrowserbase =\n (process.env.STAGEHAND_BROWSER_TARGET ?? \"local\").toLowerCase() ===\n \"browserbase\";\n\ntest.describe(\"Agent captcha auto-solve on Browserbase\", () => {\n test.skip(!isBrowserbase, \"Requires Browserbase environment\");\n\n let v3: V3;\n let logs: LogLine[];\n\n test.beforeEach(async () => {\n logs = [];\n v3 = new V3(\n getV3TestConfig({\n env: \"BROWSERBASE\",\n verbose: 2,\n logger: (line: LogLine) => {\n logs.push(line);\n console.log(`[${line.category}] ${line.message}`);\n },\n browserbaseSessionCreateParams: {\n browserSettings: {\n solveCaptchas: true,\n },\n },\n }),\n );\n await v3.init();\n console.log(\"BB session URL:\", v3.browserbaseSessionURL);\n });\n\n test.afterEach(async () => {\n await v3?.close?.().catch(() => {});\n });\n\n test(\"reCAPTCHA v2 auto-solve (Google demo)\", async () => {\n test.setTimeout(180_000);\n const page = v3.context.pages()[0];\n // Google's official reCAPTCHA v2 demo — same URL the stealth team tests.\n // Use domcontentloaded since BB's route interception can delay full load.\n await page.goto(\"https://www.google.com/recaptcha/api2/demo\", {\n waitUntil: \"domcontentloaded\",\n });\n\n // Give BB time to intercept the anchor request and solve the captcha\n await new Promise((r) => setTimeout(r, 30_000));\n\n const agent = v3.agent({\n mode: \"dom\",\n model: \"anthropic/claude-haiku-4-5-20251001\",\n });\n\n const result = await agent.execute({\n instruction:\n 'Click the \"Submit\" button and report the exact text shown on the result page.',\n maxSteps: 15,\n });\n\n console.log(\"reCAPTCHA v2 result:\", result.message);\n\n expect(result.completed).toBe(true);\n expect(result.message.toLowerCase()).toContain(\"success\");\n });\n});\n"]}
|
|
@@ -108,24 +108,24 @@ test.describe("Stagehand agent hybrid mode", () => {
|
|
|
108
108
|
expect(prompt).toContain("customInstructions");
|
|
109
109
|
expect(prompt).toContain(customInstructions);
|
|
110
110
|
});
|
|
111
|
-
test("System prompt includes
|
|
111
|
+
test("System prompt includes captcha instructions when captchasAutoSolve is true", () => {
|
|
112
112
|
const prompt = buildAgentSystemPrompt({
|
|
113
113
|
url: "https://example.com",
|
|
114
114
|
executionInstruction: "Test instruction",
|
|
115
115
|
mode: "dom",
|
|
116
|
-
|
|
116
|
+
captchasAutoSolve: true,
|
|
117
117
|
});
|
|
118
118
|
expect(prompt).toContain("captcha");
|
|
119
|
-
expect(prompt).toContain("automatically
|
|
119
|
+
expect(prompt).toContain("automatically detected and solved");
|
|
120
120
|
});
|
|
121
|
-
test("System prompt does not include captcha
|
|
121
|
+
test("System prompt does not include captcha instructions when captchasAutoSolve is false", () => {
|
|
122
122
|
const prompt = buildAgentSystemPrompt({
|
|
123
123
|
url: "https://example.com",
|
|
124
124
|
executionInstruction: "Test instruction",
|
|
125
125
|
mode: "dom",
|
|
126
|
-
|
|
126
|
+
captchasAutoSolve: false,
|
|
127
127
|
});
|
|
128
|
-
expect(prompt).not.toContain("automatically
|
|
128
|
+
expect(prompt).not.toContain("automatically detected and solved");
|
|
129
129
|
});
|
|
130
130
|
});
|
|
131
131
|
test.describe("Agent creation with mode", () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-hybrid-mode.spec.js","sourceRoot":"","sources":["../../../../tests/integration/agent-hybrid-mode.spec.ts"],"names":[],"mappings":"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","sourcesContent":["import { test, expect } from \"@playwright/test\";\nimport { V3 } from \"../../lib/v3/v3.js\";\nimport { v3TestConfig } from \"./v3.config.js\";\nimport { createAgentTools } from \"../../lib/v3/agent/tools/index.js\";\nimport { buildAgentSystemPrompt } from \"../../lib/v3/agent/prompts/agentSystemPrompt.js\";\nimport type { StepResult, ToolSet } from \"ai\";\n\ntest.describe(\"Stagehand agent hybrid mode\", () => {\n let v3: V3;\n\n test.beforeEach(async () => {\n v3 = new V3({\n ...v3TestConfig,\n experimental: true,\n });\n await v3.init();\n });\n\n test.afterEach(async () => {\n await v3?.close?.().catch(() => {});\n });\n\n test.describe(\"Tool filtering by mode\", () => {\n test(\"DOM mode includes DOM-based tools and excludes coordinate-based tools\", () => {\n const tools = createAgentTools(v3, { mode: \"dom\" });\n\n // DOM mode should have these tools\n expect(tools).toHaveProperty(\"act\");\n expect(tools).toHaveProperty(\"fillForm\");\n expect(tools).toHaveProperty(\"ariaTree\");\n expect(tools).toHaveProperty(\"screenshot\");\n expect(tools).toHaveProperty(\"extract\");\n expect(tools).toHaveProperty(\"goto\");\n expect(tools).toHaveProperty(\"scroll\");\n expect(tools).toHaveProperty(\"wait\");\n expect(tools).toHaveProperty(\"navback\");\n expect(tools).toHaveProperty(\"keys\");\n expect(tools).toHaveProperty(\"think\");\n\n // DOM mode should NOT have coordinate-based tools\n expect(tools).not.toHaveProperty(\"click\");\n expect(tools).not.toHaveProperty(\"type\");\n expect(tools).not.toHaveProperty(\"dragAndDrop\");\n expect(tools).not.toHaveProperty(\"clickAndHold\");\n expect(tools).not.toHaveProperty(\"fillFormVision\");\n });\n\n test(\"Hybrid mode includes coordinate-based tools and excludes DOM fillForm\", () => {\n const tools = createAgentTools(v3, { mode: \"hybrid\" });\n\n // Hybrid mode should have coordinate-based tools\n expect(tools).toHaveProperty(\"click\");\n expect(tools).toHaveProperty(\"type\");\n expect(tools).toHaveProperty(\"dragAndDrop\");\n expect(tools).toHaveProperty(\"clickAndHold\");\n expect(tools).toHaveProperty(\"fillFormVision\");\n\n // Hybrid mode should also have common tools\n expect(tools).toHaveProperty(\"act\");\n expect(tools).toHaveProperty(\"ariaTree\");\n expect(tools).toHaveProperty(\"screenshot\");\n expect(tools).toHaveProperty(\"extract\");\n expect(tools).toHaveProperty(\"goto\");\n expect(tools).toHaveProperty(\"scroll\");\n expect(tools).toHaveProperty(\"wait\");\n expect(tools).toHaveProperty(\"navback\");\n expect(tools).toHaveProperty(\"keys\");\n expect(tools).toHaveProperty(\"think\");\n\n // Hybrid mode should NOT have DOM-based fillForm\n expect(tools).not.toHaveProperty(\"fillForm\");\n });\n\n test(\"Default mode is DOM when not specified\", () => {\n const tools = createAgentTools(v3, {});\n\n // Should behave like DOM mode\n expect(tools).toHaveProperty(\"fillForm\");\n expect(tools).not.toHaveProperty(\"click\");\n expect(tools).not.toHaveProperty(\"type\");\n });\n });\n\n test.describe(\"System prompt generation\", () => {\n test(\"DOM mode system prompt emphasizes ariaTree and act tool\", () => {\n const prompt = buildAgentSystemPrompt({\n url: \"https://example.com\",\n executionInstruction: \"Test instruction\",\n mode: \"dom\",\n });\n\n // DOM mode should prioritize ariaTree\n expect(prompt).toContain(\"ariaTree\");\n expect(prompt).toContain(\"act\");\n expect(prompt).toContain(\"fillForm\");\n\n // Should have DOM-specific strategy\n expect(prompt).toContain(\"Use act tool for all clicking and typing\");\n expect(prompt).toContain(\"Always check ariaTree first\");\n });\n\n test(\"Hybrid mode system prompt emphasizes screenshot and coordinate tools\", () => {\n const prompt = buildAgentSystemPrompt({\n url: \"https://example.com\",\n executionInstruction: \"Test instruction\",\n mode: \"hybrid\",\n });\n\n // Hybrid mode should have coordinate-based tools mentioned\n expect(prompt).toContain(\"click\");\n expect(prompt).toContain(\"type\");\n expect(prompt).toContain(\"fillFormVision\");\n expect(prompt).toContain(\"dragAndDrop\");\n\n // Should have hybrid-specific strategy\n expect(prompt).toContain(\n \"Use specific tools (click, type) when elements are visible\",\n );\n expect(prompt).toContain(\"Always use screenshot\");\n });\n\n test(\"System prompt includes custom instructions when provided\", () => {\n const customInstructions = \"Always be polite and thorough\";\n const prompt = buildAgentSystemPrompt({\n url: \"https://example.com\",\n executionInstruction: \"Test instruction\",\n mode: \"dom\",\n systemInstructions: customInstructions,\n });\n\n expect(prompt).toContain(\"customInstructions\");\n expect(prompt).toContain(customInstructions);\n });\n\n test(\"System prompt includes Browserbase captcha message when isBrowserbase is true\", () => {\n const prompt = buildAgentSystemPrompt({\n url: \"https://example.com\",\n executionInstruction: \"Test instruction\",\n mode: \"dom\",\n isBrowserbase: true,\n });\n\n expect(prompt).toContain(\"captcha\");\n expect(prompt).toContain(\"automatically be solved\");\n });\n\n test(\"System prompt does not include captcha message when isBrowserbase is false\", () => {\n const prompt = buildAgentSystemPrompt({\n url: \"https://example.com\",\n executionInstruction: \"Test instruction\",\n mode: \"dom\",\n isBrowserbase: false,\n });\n\n expect(prompt).not.toContain(\"automatically be solved\");\n });\n });\n\n test.describe(\"Agent creation with mode\", () => {\n test(\"agent({ mode: 'dom' }) creates DOM-mode agent\", () => {\n const agent = v3.agent({\n mode: \"dom\",\n model: \"anthropic/claude-haiku-4-5-20251001\",\n });\n\n expect(agent).toHaveProperty(\"execute\");\n });\n\n test(\"agent({ mode: 'hybrid' }) creates hybrid-mode agent\", () => {\n const agent = v3.agent({\n mode: \"hybrid\",\n model: \"anthropic/claude-haiku-4-5-20251001\",\n });\n\n expect(agent).toHaveProperty(\"execute\");\n });\n\n test(\"agent without mode defaults to DOM mode\", () => {\n const agent = v3.agent({\n model: \"anthropic/claude-haiku-4-5-20251001\",\n });\n\n expect(agent).toHaveProperty(\"execute\");\n });\n\n test(\"hybrid mode can be combined with streaming\", () => {\n const agent = v3.agent({\n mode: \"hybrid\",\n stream: true,\n model: \"anthropic/claude-haiku-4-5-20251001\",\n });\n\n expect(agent).toHaveProperty(\"execute\");\n });\n });\n\n test.describe(\"Hybrid mode execution\", () => {\n test(\"hybrid mode agent uses coordinate-based tools when available\", async () => {\n test.setTimeout(90000);\n\n const toolCalls: Array<{ toolName: string; input: unknown }> = [];\n\n const agent = v3.agent({\n mode: \"hybrid\",\n model: \"anthropic/claude-haiku-4-5-20251001\",\n });\n\n const page = v3.context.pages()[0];\n await page.goto(\"https://example.com\");\n\n await agent.execute({\n instruction:\n \"Take a screenshot to see the page, then describe what you see briefly and mark the task as complete.\",\n maxSteps: 5,\n callbacks: {\n onStepFinish: async (event: StepResult<ToolSet>) => {\n if (event.toolCalls) {\n for (const tc of event.toolCalls) {\n toolCalls.push({\n toolName: tc.toolName,\n input: tc.input,\n });\n }\n }\n },\n },\n });\n\n // Should have captured tool calls\n expect(toolCalls.length).toBeGreaterThan(0);\n\n const toolNames = toolCalls.map((tc) => tc.toolName);\n // Should include screenshot (hybrid mode emphasizes visual)\n expect(toolNames).toContain(\"screenshot\");\n });\n\n test(\"DOM mode agent uses DOM-based tools\", async () => {\n test.setTimeout(90000);\n\n const toolCalls: Array<{ toolName: string; input: unknown }> = [];\n\n const agent = v3.agent({\n mode: \"dom\",\n model: \"anthropic/claude-haiku-4-5-20251001\",\n });\n\n const page = v3.context.pages()[0];\n await page.goto(\"https://example.com\");\n\n await agent.execute({\n instruction:\n \"Use the ariaTree to understand the page, then provide the final requested output or a summary of the page.\",\n maxSteps: 5,\n callbacks: {\n onStepFinish: async (event: StepResult<ToolSet>) => {\n if (event.toolCalls) {\n for (const tc of event.toolCalls) {\n toolCalls.push({\n toolName: tc.toolName,\n input: tc.input,\n });\n }\n }\n },\n },\n });\n\n // Should have captured tool calls\n expect(toolCalls.length).toBeGreaterThan(0);\n\n // Should include ariaTree (DOM mode emphasizes aria-based interaction)\n const toolNames = toolCalls.map((tc) => tc.toolName);\n expect(toolNames).toContain(\"ariaTree\");\n });\n });\n\n test.describe(\"Scroll tool variants by mode\", () => {\n test(\"DOM mode uses simple scroll tool without coordinates\", () => {\n const tools = createAgentTools(v3, { mode: \"dom\" });\n\n expect(tools).toHaveProperty(\"scroll\");\n // The DOM scroll tool should exist\n expect(typeof tools.scroll).toBe(\"object\");\n });\n\n test(\"Hybrid mode uses vision scroll tool with optional coordinates\", () => {\n const tools = createAgentTools(v3, { mode: \"hybrid\" });\n\n expect(tools).toHaveProperty(\"scroll\");\n // The hybrid scroll tool should exist\n expect(typeof tools.scroll).toBe(\"object\");\n });\n });\n\n test.describe(\"Keys tool availability in both modes\", () => {\n test(\"Keys tool is available in DOM mode\", () => {\n const tools = createAgentTools(v3, { mode: \"dom\" });\n expect(tools).toHaveProperty(\"keys\");\n });\n\n test(\"Keys tool is available in hybrid mode\", () => {\n const tools = createAgentTools(v3, { mode: \"hybrid\" });\n expect(tools).toHaveProperty(\"keys\");\n });\n });\n\n test.describe(\"Think tool availability\", () => {\n test(\"Think tool is available in DOM mode\", () => {\n const tools = createAgentTools(v3, { mode: \"dom\" });\n expect(tools).toHaveProperty(\"think\");\n });\n\n test(\"Think tool is available in hybrid mode\", () => {\n const tools = createAgentTools(v3, { mode: \"hybrid\" });\n expect(tools).toHaveProperty(\"think\");\n });\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"agent-hybrid-mode.spec.js","sourceRoot":"","sources":["../../../../tests/integration/agent-hybrid-mode.spec.ts"],"names":[],"mappings":"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","sourcesContent":["import { test, expect } from \"@playwright/test\";\nimport { V3 } from \"../../lib/v3/v3.js\";\nimport { v3TestConfig } from \"./v3.config.js\";\nimport { createAgentTools } from \"../../lib/v3/agent/tools/index.js\";\nimport { buildAgentSystemPrompt } from \"../../lib/v3/agent/prompts/agentSystemPrompt.js\";\nimport type { StepResult, ToolSet } from \"ai\";\n\ntest.describe(\"Stagehand agent hybrid mode\", () => {\n let v3: V3;\n\n test.beforeEach(async () => {\n v3 = new V3({\n ...v3TestConfig,\n experimental: true,\n });\n await v3.init();\n });\n\n test.afterEach(async () => {\n await v3?.close?.().catch(() => {});\n });\n\n test.describe(\"Tool filtering by mode\", () => {\n test(\"DOM mode includes DOM-based tools and excludes coordinate-based tools\", () => {\n const tools = createAgentTools(v3, { mode: \"dom\" });\n\n // DOM mode should have these tools\n expect(tools).toHaveProperty(\"act\");\n expect(tools).toHaveProperty(\"fillForm\");\n expect(tools).toHaveProperty(\"ariaTree\");\n expect(tools).toHaveProperty(\"screenshot\");\n expect(tools).toHaveProperty(\"extract\");\n expect(tools).toHaveProperty(\"goto\");\n expect(tools).toHaveProperty(\"scroll\");\n expect(tools).toHaveProperty(\"wait\");\n expect(tools).toHaveProperty(\"navback\");\n expect(tools).toHaveProperty(\"keys\");\n expect(tools).toHaveProperty(\"think\");\n\n // DOM mode should NOT have coordinate-based tools\n expect(tools).not.toHaveProperty(\"click\");\n expect(tools).not.toHaveProperty(\"type\");\n expect(tools).not.toHaveProperty(\"dragAndDrop\");\n expect(tools).not.toHaveProperty(\"clickAndHold\");\n expect(tools).not.toHaveProperty(\"fillFormVision\");\n });\n\n test(\"Hybrid mode includes coordinate-based tools and excludes DOM fillForm\", () => {\n const tools = createAgentTools(v3, { mode: \"hybrid\" });\n\n // Hybrid mode should have coordinate-based tools\n expect(tools).toHaveProperty(\"click\");\n expect(tools).toHaveProperty(\"type\");\n expect(tools).toHaveProperty(\"dragAndDrop\");\n expect(tools).toHaveProperty(\"clickAndHold\");\n expect(tools).toHaveProperty(\"fillFormVision\");\n\n // Hybrid mode should also have common tools\n expect(tools).toHaveProperty(\"act\");\n expect(tools).toHaveProperty(\"ariaTree\");\n expect(tools).toHaveProperty(\"screenshot\");\n expect(tools).toHaveProperty(\"extract\");\n expect(tools).toHaveProperty(\"goto\");\n expect(tools).toHaveProperty(\"scroll\");\n expect(tools).toHaveProperty(\"wait\");\n expect(tools).toHaveProperty(\"navback\");\n expect(tools).toHaveProperty(\"keys\");\n expect(tools).toHaveProperty(\"think\");\n\n // Hybrid mode should NOT have DOM-based fillForm\n expect(tools).not.toHaveProperty(\"fillForm\");\n });\n\n test(\"Default mode is DOM when not specified\", () => {\n const tools = createAgentTools(v3, {});\n\n // Should behave like DOM mode\n expect(tools).toHaveProperty(\"fillForm\");\n expect(tools).not.toHaveProperty(\"click\");\n expect(tools).not.toHaveProperty(\"type\");\n });\n });\n\n test.describe(\"System prompt generation\", () => {\n test(\"DOM mode system prompt emphasizes ariaTree and act tool\", () => {\n const prompt = buildAgentSystemPrompt({\n url: \"https://example.com\",\n executionInstruction: \"Test instruction\",\n mode: \"dom\",\n });\n\n // DOM mode should prioritize ariaTree\n expect(prompt).toContain(\"ariaTree\");\n expect(prompt).toContain(\"act\");\n expect(prompt).toContain(\"fillForm\");\n\n // Should have DOM-specific strategy\n expect(prompt).toContain(\"Use act tool for all clicking and typing\");\n expect(prompt).toContain(\"Always check ariaTree first\");\n });\n\n test(\"Hybrid mode system prompt emphasizes screenshot and coordinate tools\", () => {\n const prompt = buildAgentSystemPrompt({\n url: \"https://example.com\",\n executionInstruction: \"Test instruction\",\n mode: \"hybrid\",\n });\n\n // Hybrid mode should have coordinate-based tools mentioned\n expect(prompt).toContain(\"click\");\n expect(prompt).toContain(\"type\");\n expect(prompt).toContain(\"fillFormVision\");\n expect(prompt).toContain(\"dragAndDrop\");\n\n // Should have hybrid-specific strategy\n expect(prompt).toContain(\n \"Use specific tools (click, type) when elements are visible\",\n );\n expect(prompt).toContain(\"Always use screenshot\");\n });\n\n test(\"System prompt includes custom instructions when provided\", () => {\n const customInstructions = \"Always be polite and thorough\";\n const prompt = buildAgentSystemPrompt({\n url: \"https://example.com\",\n executionInstruction: \"Test instruction\",\n mode: \"dom\",\n systemInstructions: customInstructions,\n });\n\n expect(prompt).toContain(\"customInstructions\");\n expect(prompt).toContain(customInstructions);\n });\n\n test(\"System prompt includes captcha instructions when captchasAutoSolve is true\", () => {\n const prompt = buildAgentSystemPrompt({\n url: \"https://example.com\",\n executionInstruction: \"Test instruction\",\n mode: \"dom\",\n captchasAutoSolve: true,\n });\n\n expect(prompt).toContain(\"captcha\");\n expect(prompt).toContain(\"automatically detected and solved\");\n });\n\n test(\"System prompt does not include captcha instructions when captchasAutoSolve is false\", () => {\n const prompt = buildAgentSystemPrompt({\n url: \"https://example.com\",\n executionInstruction: \"Test instruction\",\n mode: \"dom\",\n captchasAutoSolve: false,\n });\n\n expect(prompt).not.toContain(\"automatically detected and solved\");\n });\n });\n\n test.describe(\"Agent creation with mode\", () => {\n test(\"agent({ mode: 'dom' }) creates DOM-mode agent\", () => {\n const agent = v3.agent({\n mode: \"dom\",\n model: \"anthropic/claude-haiku-4-5-20251001\",\n });\n\n expect(agent).toHaveProperty(\"execute\");\n });\n\n test(\"agent({ mode: 'hybrid' }) creates hybrid-mode agent\", () => {\n const agent = v3.agent({\n mode: \"hybrid\",\n model: \"anthropic/claude-haiku-4-5-20251001\",\n });\n\n expect(agent).toHaveProperty(\"execute\");\n });\n\n test(\"agent without mode defaults to DOM mode\", () => {\n const agent = v3.agent({\n model: \"anthropic/claude-haiku-4-5-20251001\",\n });\n\n expect(agent).toHaveProperty(\"execute\");\n });\n\n test(\"hybrid mode can be combined with streaming\", () => {\n const agent = v3.agent({\n mode: \"hybrid\",\n stream: true,\n model: \"anthropic/claude-haiku-4-5-20251001\",\n });\n\n expect(agent).toHaveProperty(\"execute\");\n });\n });\n\n test.describe(\"Hybrid mode execution\", () => {\n test(\"hybrid mode agent uses coordinate-based tools when available\", async () => {\n test.setTimeout(90000);\n\n const toolCalls: Array<{ toolName: string; input: unknown }> = [];\n\n const agent = v3.agent({\n mode: \"hybrid\",\n model: \"anthropic/claude-haiku-4-5-20251001\",\n });\n\n const page = v3.context.pages()[0];\n await page.goto(\"https://example.com\");\n\n await agent.execute({\n instruction:\n \"Take a screenshot to see the page, then describe what you see briefly and mark the task as complete.\",\n maxSteps: 5,\n callbacks: {\n onStepFinish: async (event: StepResult<ToolSet>) => {\n if (event.toolCalls) {\n for (const tc of event.toolCalls) {\n toolCalls.push({\n toolName: tc.toolName,\n input: tc.input,\n });\n }\n }\n },\n },\n });\n\n // Should have captured tool calls\n expect(toolCalls.length).toBeGreaterThan(0);\n\n const toolNames = toolCalls.map((tc) => tc.toolName);\n // Should include screenshot (hybrid mode emphasizes visual)\n expect(toolNames).toContain(\"screenshot\");\n });\n\n test(\"DOM mode agent uses DOM-based tools\", async () => {\n test.setTimeout(90000);\n\n const toolCalls: Array<{ toolName: string; input: unknown }> = [];\n\n const agent = v3.agent({\n mode: \"dom\",\n model: \"anthropic/claude-haiku-4-5-20251001\",\n });\n\n const page = v3.context.pages()[0];\n await page.goto(\"https://example.com\");\n\n await agent.execute({\n instruction:\n \"Use the ariaTree to understand the page, then provide the final requested output or a summary of the page.\",\n maxSteps: 5,\n callbacks: {\n onStepFinish: async (event: StepResult<ToolSet>) => {\n if (event.toolCalls) {\n for (const tc of event.toolCalls) {\n toolCalls.push({\n toolName: tc.toolName,\n input: tc.input,\n });\n }\n }\n },\n },\n });\n\n // Should have captured tool calls\n expect(toolCalls.length).toBeGreaterThan(0);\n\n // Should include ariaTree (DOM mode emphasizes aria-based interaction)\n const toolNames = toolCalls.map((tc) => tc.toolName);\n expect(toolNames).toContain(\"ariaTree\");\n });\n });\n\n test.describe(\"Scroll tool variants by mode\", () => {\n test(\"DOM mode uses simple scroll tool without coordinates\", () => {\n const tools = createAgentTools(v3, { mode: \"dom\" });\n\n expect(tools).toHaveProperty(\"scroll\");\n // The DOM scroll tool should exist\n expect(typeof tools.scroll).toBe(\"object\");\n });\n\n test(\"Hybrid mode uses vision scroll tool with optional coordinates\", () => {\n const tools = createAgentTools(v3, { mode: \"hybrid\" });\n\n expect(tools).toHaveProperty(\"scroll\");\n // The hybrid scroll tool should exist\n expect(typeof tools.scroll).toBe(\"object\");\n });\n });\n\n test.describe(\"Keys tool availability in both modes\", () => {\n test(\"Keys tool is available in DOM mode\", () => {\n const tools = createAgentTools(v3, { mode: \"dom\" });\n expect(tools).toHaveProperty(\"keys\");\n });\n\n test(\"Keys tool is available in hybrid mode\", () => {\n const tools = createAgentTools(v3, { mode: \"hybrid\" });\n expect(tools).toHaveProperty(\"keys\");\n });\n });\n\n test.describe(\"Think tool availability\", () => {\n test(\"Think tool is available in DOM mode\", () => {\n const tools = createAgentTools(v3, { mode: \"dom\" });\n expect(tools).toHaveProperty(\"think\");\n });\n\n test(\"Think tool is available in hybrid mode\", () => {\n const tools = createAgentTools(v3, { mode: \"hybrid\" });\n expect(tools).toHaveProperty(\"think\");\n });\n });\n});\n"]}
|
|
@@ -183,7 +183,7 @@ test.describe("V3 hard timeouts", () => {
|
|
|
183
183
|
});
|
|
184
184
|
test("agent toolTimeout enforces timeout for fillForm tool", async () => {
|
|
185
185
|
const { toolOutput } = await runAgentToolTimeoutScenario("fillForm", {
|
|
186
|
-
fields: [{ action: "type hello into name"
|
|
186
|
+
fields: [{ action: "type hello into name" }],
|
|
187
187
|
});
|
|
188
188
|
const output = toolOutput;
|
|
189
189
|
expect(output.success).toBe(false);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timeouts.spec.js","sourceRoot":"","sources":["../../../../tests/integration/timeouts.spec.ts"],"names":[],"mappings":"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","sourcesContent":["import { test, expect } from \"@playwright/test\";\nimport { V3 } from \"../../lib/v3/v3.js\";\nimport { v3DynamicTestConfig } from \"./v3.dynamic.config.js\";\nimport { z } from \"zod\";\nimport { closeV3 } from \"./testUtils.js\";\nimport type { LLMClient } from \"../../lib/v3/llm/LLMClient.js\";\nimport { generateText } from \"ai\";\n\ntype AgentToolNameWithTimeout =\n | \"act\"\n | \"extract\"\n | \"fillForm\"\n | \"ariaTree\"\n | \"click\"\n | \"type\"\n | \"dragAndDrop\"\n | \"clickAndHold\"\n | \"fillFormVision\"\n | \"goto\"\n | \"navback\"\n | \"screenshot\"\n | \"scroll\"\n | \"keys\";\n\ntype ToolTimeoutTestModel = {\n provider: string;\n modelId: string;\n specificationVersion: \"v2\";\n supportedUrls: Record<string, RegExp[]>;\n doGenerate: () => Promise<{\n content: Array<{\n type: \"tool-call\";\n toolCallId: string;\n toolName: string;\n input: string;\n }>;\n finishReason: \"tool-calls\";\n usage: { inputTokens: number; outputTokens: number; totalTokens: number };\n warnings: [];\n }>;\n doStream: (_options: unknown) => Promise<never>;\n};\n\ntype ToolTimeoutTestLLMClient = LLMClient & {\n model: ToolTimeoutTestModel;\n};\n\nfunction createToolTimeoutTestLlmClient(\n toolName: AgentToolNameWithTimeout,\n toolInput: Record<string, unknown>,\n): ToolTimeoutTestLLMClient {\n const usage = {\n prompt_tokens: 0,\n completion_tokens: 0,\n reasoning_tokens: 0,\n cached_input_tokens: 0,\n total_tokens: 0,\n };\n let generateCallCount = 0;\n\n const model: ToolTimeoutTestModel = {\n provider: \"mock\",\n modelId: \"mock/tool-timeout-test\",\n specificationVersion: \"v2\",\n supportedUrls: {},\n doGenerate: async () => {\n generateCallCount += 1;\n if (generateCallCount === 1) {\n return {\n content: [\n {\n type: \"tool-call\",\n toolCallId: \"tool-1\",\n toolName,\n input: JSON.stringify(toolInput),\n },\n ],\n finishReason: \"tool-calls\",\n usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },\n warnings: [],\n };\n }\n\n return {\n content: [\n {\n type: \"tool-call\",\n toolCallId: \"done-1\",\n toolName: \"done\",\n input: JSON.stringify({ reasoning: \"done\", taskComplete: true }),\n },\n ],\n finishReason: \"tool-calls\",\n usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },\n warnings: [],\n };\n },\n doStream: async () => {\n throw new Error(\"doStream not implemented in timeout test model\");\n },\n };\n\n const llm = {\n type: \"openai\",\n modelName: \"openai/gpt-4.1-mini\",\n hasVision: false,\n clientOptions: {},\n model,\n getLanguageModel: () => model,\n generateText,\n createChatCompletion: async <T = unknown>(options: unknown): Promise<T> => {\n const responseModelName = (\n options as { options?: { response_model?: { name?: string } } }\n )?.options?.response_model?.name;\n\n if (responseModelName === \"act\") {\n return {\n data: {\n elementId: \"1-0\",\n description: \"click body\",\n method: \"click\",\n arguments: [],\n twoStep: false,\n },\n usage,\n } as T;\n }\n if (responseModelName === \"Observation\") {\n return { data: { elements: [] }, usage } as T;\n }\n if (responseModelName === \"Extraction\") {\n return { data: {}, usage } as T;\n }\n if (responseModelName === \"Metadata\") {\n return { data: { completed: true, progress: \"\" }, usage } as T;\n }\n return { data: {}, usage } as T;\n },\n };\n\n return llm as unknown as ToolTimeoutTestLLMClient;\n}\n\nfunction findToolOutput(\n stepEvents: Array<{\n toolCalls?: Array<{ toolName?: string }>;\n toolResults?: Array<{ output?: unknown }>;\n }>,\n toolName: string,\n) {\n for (const event of stepEvents) {\n if (!event.toolCalls || !event.toolResults) continue;\n const toolIndex = event.toolCalls.findIndex(\n (tc) => tc.toolName === toolName,\n );\n if (toolIndex !== -1) {\n return event.toolResults[toolIndex]?.output;\n }\n }\n return undefined;\n}\n\nasync function runAgentToolTimeoutScenario(\n toolName: AgentToolNameWithTimeout,\n toolInput: Record<string, unknown>,\n options?: { mode?: \"dom\" | \"hybrid\" },\n) {\n const llmClient = createToolTimeoutTestLlmClient(toolName, toolInput);\n const stepEvents: Array<{\n toolCalls?: Array<{ toolName?: string }>;\n toolResults?: Array<{ output?: unknown }>;\n }> = [];\n const v3 = new V3({\n ...v3DynamicTestConfig,\n experimental: true,\n llmClient,\n });\n await v3.init();\n try {\n const page = v3.context.pages()[0];\n await page.goto(\"https://example.com\");\n const agent = v3.agent({\n ...(options?.mode ? { mode: options.mode } : {}),\n });\n await agent.execute({\n instruction: `Use ${toolName} and then finish`,\n maxSteps: 2,\n toolTimeout: 1,\n callbacks: {\n onStepFinish: (event) => {\n stepEvents.push({\n toolCalls: event.toolCalls?.map((tc) => ({\n toolName: tc.toolName,\n })),\n toolResults: event.toolResults?.map((tr) => ({\n output: tr.output,\n })),\n });\n },\n },\n });\n const toolOutput = findToolOutput(stepEvents, toolName);\n if (!toolOutput) {\n throw new Error(`No tool output captured for ${toolName}`);\n }\n return { toolOutput };\n } finally {\n await closeV3(v3);\n }\n}\n\ntest.describe(\"V3 hard timeouts\", () => {\n let v3: V3;\n\n test.beforeEach(async () => {\n v3 = new V3(v3DynamicTestConfig);\n await v3.init();\n });\n\n test.afterEach(async () => {\n await closeV3(v3);\n });\n\n test(\"observe() enforces timeoutMs\", async () => {\n // Tiny timeout to force the race to hit the timeout branch\n await expect(v3.observe(\"find something\", { timeout: 5 })).rejects.toThrow(\n /timed out/i,\n );\n });\n\n test(\"extract() enforces timeoutMs\", async () => {\n const schema = z.object({ title: z.string().optional() });\n await expect(\n v3.extract(\"Extract title\", schema, { timeout: 5 }),\n ).rejects.toThrow(/timed out/i);\n });\n\n test(\"act() enforces timeoutMs\", async () => {\n await expect(v3.act(\"do nothing\", { timeout: 5 })).rejects.toThrow(\n /timed out/i,\n );\n });\n\n test(\"agent toolTimeout enforces timeout for act tool\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"act\", {\n action: \"click somewhere\",\n });\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for extract tool\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"extract\", {\n instruction: \"extract the page title\",\n schema: { type: \"object\", properties: { title: { type: \"string\" } } },\n });\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for fillForm tool\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"fillForm\", {\n fields: [{ action: \"type hello into name\", value: \"hello\" }],\n });\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for ariaTree\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"ariaTree\", {});\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for goto tool\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"goto\", {\n url: \"https://example.com/slow\",\n });\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for navback tool\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"navback\", {\n reasoningText: \"going back\",\n });\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for screenshot tool\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"screenshot\", {});\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for scroll tool\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"scroll\", {\n direction: \"down\",\n });\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for keys tool\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"keys\", {\n method: \"press\",\n value: \"Enter\",\n });\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for click tool (hybrid)\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\n \"click\",\n { describe: \"click element\", coordinates: [100, 100] },\n { mode: \"hybrid\" },\n );\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for type tool (hybrid)\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\n \"type\",\n {\n describe: \"type into field\",\n text: \"hello\",\n coordinates: [100, 100],\n },\n { mode: \"hybrid\" },\n );\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for dragAndDrop tool (hybrid)\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\n \"dragAndDrop\",\n {\n describe: \"drag element\",\n startCoordinates: [100, 100],\n endCoordinates: [200, 200],\n },\n { mode: \"hybrid\" },\n );\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for clickAndHold tool (hybrid)\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\n \"clickAndHold\",\n {\n describe: \"hold element\",\n coordinates: [100, 100],\n duration: 1000,\n },\n { mode: \"hybrid\" },\n );\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for fillFormVision tool (hybrid)\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\n \"fillFormVision\",\n {\n fields: [\n {\n action: \"type hello into name\",\n value: \"hello\",\n coordinates: { x: 100, y: 100 },\n },\n {\n action: \"type world into email\",\n value: \"world\",\n coordinates: { x: 100, y: 200 },\n },\n ],\n },\n { mode: \"hybrid\" },\n );\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"timeouts.spec.js","sourceRoot":"","sources":["../../../../tests/integration/timeouts.spec.ts"],"names":[],"mappings":"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","sourcesContent":["import { test, expect } from \"@playwright/test\";\nimport { V3 } from \"../../lib/v3/v3.js\";\nimport { v3DynamicTestConfig } from \"./v3.dynamic.config.js\";\nimport { z } from \"zod\";\nimport { closeV3 } from \"./testUtils.js\";\nimport type { LLMClient } from \"../../lib/v3/llm/LLMClient.js\";\nimport { generateText } from \"ai\";\n\ntype AgentToolNameWithTimeout =\n | \"act\"\n | \"extract\"\n | \"fillForm\"\n | \"ariaTree\"\n | \"click\"\n | \"type\"\n | \"dragAndDrop\"\n | \"clickAndHold\"\n | \"fillFormVision\"\n | \"goto\"\n | \"navback\"\n | \"screenshot\"\n | \"scroll\"\n | \"keys\";\n\ntype ToolTimeoutTestModel = {\n provider: string;\n modelId: string;\n specificationVersion: \"v2\";\n supportedUrls: Record<string, RegExp[]>;\n doGenerate: () => Promise<{\n content: Array<{\n type: \"tool-call\";\n toolCallId: string;\n toolName: string;\n input: string;\n }>;\n finishReason: \"tool-calls\";\n usage: { inputTokens: number; outputTokens: number; totalTokens: number };\n warnings: [];\n }>;\n doStream: (_options: unknown) => Promise<never>;\n};\n\ntype ToolTimeoutTestLLMClient = LLMClient & {\n model: ToolTimeoutTestModel;\n};\n\nfunction createToolTimeoutTestLlmClient(\n toolName: AgentToolNameWithTimeout,\n toolInput: Record<string, unknown>,\n): ToolTimeoutTestLLMClient {\n const usage = {\n prompt_tokens: 0,\n completion_tokens: 0,\n reasoning_tokens: 0,\n cached_input_tokens: 0,\n total_tokens: 0,\n };\n let generateCallCount = 0;\n\n const model: ToolTimeoutTestModel = {\n provider: \"mock\",\n modelId: \"mock/tool-timeout-test\",\n specificationVersion: \"v2\",\n supportedUrls: {},\n doGenerate: async () => {\n generateCallCount += 1;\n if (generateCallCount === 1) {\n return {\n content: [\n {\n type: \"tool-call\",\n toolCallId: \"tool-1\",\n toolName,\n input: JSON.stringify(toolInput),\n },\n ],\n finishReason: \"tool-calls\",\n usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },\n warnings: [],\n };\n }\n\n return {\n content: [\n {\n type: \"tool-call\",\n toolCallId: \"done-1\",\n toolName: \"done\",\n input: JSON.stringify({ reasoning: \"done\", taskComplete: true }),\n },\n ],\n finishReason: \"tool-calls\",\n usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },\n warnings: [],\n };\n },\n doStream: async () => {\n throw new Error(\"doStream not implemented in timeout test model\");\n },\n };\n\n const llm = {\n type: \"openai\",\n modelName: \"openai/gpt-4.1-mini\",\n hasVision: false,\n clientOptions: {},\n model,\n getLanguageModel: () => model,\n generateText,\n createChatCompletion: async <T = unknown>(options: unknown): Promise<T> => {\n const responseModelName = (\n options as { options?: { response_model?: { name?: string } } }\n )?.options?.response_model?.name;\n\n if (responseModelName === \"act\") {\n return {\n data: {\n elementId: \"1-0\",\n description: \"click body\",\n method: \"click\",\n arguments: [],\n twoStep: false,\n },\n usage,\n } as T;\n }\n if (responseModelName === \"Observation\") {\n return { data: { elements: [] }, usage } as T;\n }\n if (responseModelName === \"Extraction\") {\n return { data: {}, usage } as T;\n }\n if (responseModelName === \"Metadata\") {\n return { data: { completed: true, progress: \"\" }, usage } as T;\n }\n return { data: {}, usage } as T;\n },\n };\n\n return llm as unknown as ToolTimeoutTestLLMClient;\n}\n\nfunction findToolOutput(\n stepEvents: Array<{\n toolCalls?: Array<{ toolName?: string }>;\n toolResults?: Array<{ output?: unknown }>;\n }>,\n toolName: string,\n) {\n for (const event of stepEvents) {\n if (!event.toolCalls || !event.toolResults) continue;\n const toolIndex = event.toolCalls.findIndex(\n (tc) => tc.toolName === toolName,\n );\n if (toolIndex !== -1) {\n return event.toolResults[toolIndex]?.output;\n }\n }\n return undefined;\n}\n\nasync function runAgentToolTimeoutScenario(\n toolName: AgentToolNameWithTimeout,\n toolInput: Record<string, unknown>,\n options?: { mode?: \"dom\" | \"hybrid\" },\n) {\n const llmClient = createToolTimeoutTestLlmClient(toolName, toolInput);\n const stepEvents: Array<{\n toolCalls?: Array<{ toolName?: string }>;\n toolResults?: Array<{ output?: unknown }>;\n }> = [];\n const v3 = new V3({\n ...v3DynamicTestConfig,\n experimental: true,\n llmClient,\n });\n await v3.init();\n try {\n const page = v3.context.pages()[0];\n await page.goto(\"https://example.com\");\n const agent = v3.agent({\n ...(options?.mode ? { mode: options.mode } : {}),\n });\n await agent.execute({\n instruction: `Use ${toolName} and then finish`,\n maxSteps: 2,\n toolTimeout: 1,\n callbacks: {\n onStepFinish: (event) => {\n stepEvents.push({\n toolCalls: event.toolCalls?.map((tc) => ({\n toolName: tc.toolName,\n })),\n toolResults: event.toolResults?.map((tr) => ({\n output: tr.output,\n })),\n });\n },\n },\n });\n const toolOutput = findToolOutput(stepEvents, toolName);\n if (!toolOutput) {\n throw new Error(`No tool output captured for ${toolName}`);\n }\n return { toolOutput };\n } finally {\n await closeV3(v3);\n }\n}\n\ntest.describe(\"V3 hard timeouts\", () => {\n let v3: V3;\n\n test.beforeEach(async () => {\n v3 = new V3(v3DynamicTestConfig);\n await v3.init();\n });\n\n test.afterEach(async () => {\n await closeV3(v3);\n });\n\n test(\"observe() enforces timeoutMs\", async () => {\n // Tiny timeout to force the race to hit the timeout branch\n await expect(v3.observe(\"find something\", { timeout: 5 })).rejects.toThrow(\n /timed out/i,\n );\n });\n\n test(\"extract() enforces timeoutMs\", async () => {\n const schema = z.object({ title: z.string().optional() });\n await expect(\n v3.extract(\"Extract title\", schema, { timeout: 5 }),\n ).rejects.toThrow(/timed out/i);\n });\n\n test(\"act() enforces timeoutMs\", async () => {\n await expect(v3.act(\"do nothing\", { timeout: 5 })).rejects.toThrow(\n /timed out/i,\n );\n });\n\n test(\"agent toolTimeout enforces timeout for act tool\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"act\", {\n action: \"click somewhere\",\n });\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for extract tool\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"extract\", {\n instruction: \"extract the page title\",\n schema: { type: \"object\", properties: { title: { type: \"string\" } } },\n });\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for fillForm tool\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"fillForm\", {\n fields: [{ action: \"type hello into name\" }],\n });\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for ariaTree\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"ariaTree\", {});\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for goto tool\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"goto\", {\n url: \"https://example.com/slow\",\n });\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for navback tool\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"navback\", {\n reasoningText: \"going back\",\n });\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for screenshot tool\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"screenshot\", {});\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for scroll tool\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"scroll\", {\n direction: \"down\",\n });\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for keys tool\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\"keys\", {\n method: \"press\",\n value: \"Enter\",\n });\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for click tool (hybrid)\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\n \"click\",\n { describe: \"click element\", coordinates: [100, 100] },\n { mode: \"hybrid\" },\n );\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for type tool (hybrid)\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\n \"type\",\n {\n describe: \"type into field\",\n text: \"hello\",\n coordinates: [100, 100],\n },\n { mode: \"hybrid\" },\n );\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for dragAndDrop tool (hybrid)\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\n \"dragAndDrop\",\n {\n describe: \"drag element\",\n startCoordinates: [100, 100],\n endCoordinates: [200, 200],\n },\n { mode: \"hybrid\" },\n );\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for clickAndHold tool (hybrid)\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\n \"clickAndHold\",\n {\n describe: \"hold element\",\n coordinates: [100, 100],\n duration: 1000,\n },\n { mode: \"hybrid\" },\n );\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n\n test(\"agent toolTimeout enforces timeout for fillFormVision tool (hybrid)\", async () => {\n const { toolOutput } = await runAgentToolTimeoutScenario(\n \"fillFormVision\",\n {\n fields: [\n {\n action: \"type hello into name\",\n value: \"hello\",\n coordinates: { x: 100, y: 100 },\n },\n {\n action: \"type world into email\",\n value: \"world\",\n coordinates: { x: 100, y: 200 },\n },\n ],\n },\n { mode: \"hybrid\" },\n );\n const output = toolOutput as { success: boolean; error: string };\n expect(output.success).toBe(false);\n expect(output.error).toContain(\"TimeoutError\");\n expect(output.error).toContain(\"1ms\");\n });\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { CaptchaSolver } from "../../lib/v3/agent/utils/captchaSolver.js";
|
|
3
|
+
import { V3AgentHandler } from "../../lib/v3/handlers/v3AgentHandler.js";
|
|
4
|
+
const SOLVING_STARTED = "browserbase-solving-started";
|
|
5
|
+
const SOLVING_FINISHED = "browserbase-solving-finished";
|
|
6
|
+
const SOLVING_ERRORED = "browserbase-solving-errored";
|
|
7
|
+
class MockPage {
|
|
8
|
+
listeners = new Set();
|
|
9
|
+
captchaBoxes = [];
|
|
10
|
+
on(event, listener) {
|
|
11
|
+
if (event === "console") {
|
|
12
|
+
this.listeners.add(listener);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
off(event, listener) {
|
|
16
|
+
if (event === "console") {
|
|
17
|
+
this.listeners.delete(listener);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
emitConsole(text) {
|
|
21
|
+
const message = { text: () => text };
|
|
22
|
+
for (const listener of this.listeners) {
|
|
23
|
+
listener(message);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
url() {
|
|
27
|
+
return "https://example.com";
|
|
28
|
+
}
|
|
29
|
+
async screenshot() {
|
|
30
|
+
return Buffer.from("fake-image");
|
|
31
|
+
}
|
|
32
|
+
async evaluate() {
|
|
33
|
+
return this.captchaBoxes;
|
|
34
|
+
}
|
|
35
|
+
mainFrame() {
|
|
36
|
+
return {
|
|
37
|
+
evaluate: async () => ({ w: 1288, h: 711 }),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
class FakeCuaClient {
|
|
42
|
+
contextNotes = [];
|
|
43
|
+
preStepHook;
|
|
44
|
+
actionHandler;
|
|
45
|
+
executeImpl = vi.fn(async (options) => {
|
|
46
|
+
void options;
|
|
47
|
+
return {
|
|
48
|
+
success: true,
|
|
49
|
+
message: "ok",
|
|
50
|
+
actions: [],
|
|
51
|
+
completed: true,
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
captureScreenshot = vi.fn(async () => null);
|
|
55
|
+
setViewport = vi.fn();
|
|
56
|
+
setCurrentUrl = vi.fn();
|
|
57
|
+
setScreenshotProvider = vi.fn();
|
|
58
|
+
setSafetyConfirmationHandler = vi.fn();
|
|
59
|
+
setActionHandler(handler) {
|
|
60
|
+
this.actionHandler = handler;
|
|
61
|
+
}
|
|
62
|
+
setPreStepHook(handler) {
|
|
63
|
+
this.preStepHook = handler;
|
|
64
|
+
}
|
|
65
|
+
addContextNote(note) {
|
|
66
|
+
this.contextNotes.push(note);
|
|
67
|
+
}
|
|
68
|
+
async execute(options) {
|
|
69
|
+
return this.executeImpl(options);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
let fakeCuaClient;
|
|
73
|
+
vi.mock("../../lib/v3/agent/AgentProvider", () => ({
|
|
74
|
+
AgentProvider: class {
|
|
75
|
+
constructor(logger) {
|
|
76
|
+
void logger;
|
|
77
|
+
}
|
|
78
|
+
getClient() {
|
|
79
|
+
return fakeCuaClient;
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
}));
|
|
83
|
+
import { V3CuaAgentHandler } from "../../lib/v3/handlers/v3CuaAgentHandler.js";
|
|
84
|
+
function collectUserMessages(messages) {
|
|
85
|
+
return messages.filter((message) => message.role === "user" && typeof message.content === "string");
|
|
86
|
+
}
|
|
87
|
+
describe("agent captcha hooks", () => {
|
|
88
|
+
let page;
|
|
89
|
+
let logs;
|
|
90
|
+
let logger;
|
|
91
|
+
beforeEach(() => {
|
|
92
|
+
page = new MockPage();
|
|
93
|
+
logs = [];
|
|
94
|
+
logger = (line) => {
|
|
95
|
+
logs.push(line);
|
|
96
|
+
};
|
|
97
|
+
fakeCuaClient = new FakeCuaClient();
|
|
98
|
+
});
|
|
99
|
+
it("blocks regular agent prepareStep until the solver finishes and injects one solved message", async () => {
|
|
100
|
+
const handler = new V3AgentHandler({
|
|
101
|
+
isCaptchaAutoSolveEnabled: true,
|
|
102
|
+
}, logger, {});
|
|
103
|
+
const solver = new CaptchaSolver();
|
|
104
|
+
solver.init(async () => page);
|
|
105
|
+
const userCallback = vi.fn(async (options) => options);
|
|
106
|
+
const prepareStep = handler.createPrepareStep(userCallback, solver);
|
|
107
|
+
const options = {
|
|
108
|
+
messages: [{ role: "user", content: "start" }],
|
|
109
|
+
};
|
|
110
|
+
await prepareStep(options);
|
|
111
|
+
page.emitConsole(SOLVING_STARTED);
|
|
112
|
+
const secondCall = prepareStep(options);
|
|
113
|
+
await Promise.resolve();
|
|
114
|
+
expect(userCallback).toHaveBeenCalledTimes(1);
|
|
115
|
+
page.emitConsole(SOLVING_FINISHED);
|
|
116
|
+
await secondCall;
|
|
117
|
+
expect(userCallback).toHaveBeenCalledTimes(2);
|
|
118
|
+
expect(collectUserMessages(options.messages).filter((message) => message.content.includes("automatically detected and solved"))).toHaveLength(1);
|
|
119
|
+
});
|
|
120
|
+
it("injects one error message when the regular agent solver errors", async () => {
|
|
121
|
+
const handler = new V3AgentHandler({
|
|
122
|
+
isCaptchaAutoSolveEnabled: true,
|
|
123
|
+
}, logger, {});
|
|
124
|
+
const solver = new CaptchaSolver();
|
|
125
|
+
solver.init(async () => page);
|
|
126
|
+
const prepareStep = handler.createPrepareStep(undefined, solver);
|
|
127
|
+
const options = {
|
|
128
|
+
messages: [{ role: "user", content: "start" }],
|
|
129
|
+
};
|
|
130
|
+
await prepareStep(options);
|
|
131
|
+
page.emitConsole(SOLVING_STARTED);
|
|
132
|
+
const pending = prepareStep(options);
|
|
133
|
+
page.emitConsole(SOLVING_ERRORED);
|
|
134
|
+
await pending;
|
|
135
|
+
expect(collectUserMessages(options.messages).filter((message) => message.content.includes("automatic captcha solver failed"))).toHaveLength(1);
|
|
136
|
+
});
|
|
137
|
+
it("pauses the CUA loop at prepareStep while Browserbase solves a captcha", async () => {
|
|
138
|
+
let secondPrepareStarted = false;
|
|
139
|
+
fakeCuaClient.executeImpl = vi.fn(async () => {
|
|
140
|
+
await fakeCuaClient.preStepHook?.();
|
|
141
|
+
page.emitConsole(SOLVING_STARTED);
|
|
142
|
+
const blockedPrepare = fakeCuaClient.preStepHook?.() ?? Promise.resolve();
|
|
143
|
+
secondPrepareStarted = true;
|
|
144
|
+
await blockedPrepare;
|
|
145
|
+
return {
|
|
146
|
+
success: true,
|
|
147
|
+
message: "ok",
|
|
148
|
+
actions: [],
|
|
149
|
+
completed: true,
|
|
150
|
+
};
|
|
151
|
+
});
|
|
152
|
+
const handler = new V3CuaAgentHandler({
|
|
153
|
+
context: {
|
|
154
|
+
awaitActivePage: async () => page,
|
|
155
|
+
},
|
|
156
|
+
bus: { emit: vi.fn() },
|
|
157
|
+
isCaptchaAutoSolveEnabled: true,
|
|
158
|
+
isAdvancedStealth: false,
|
|
159
|
+
configuredViewport: { width: 1288, height: 711 },
|
|
160
|
+
isAgentReplayActive: () => false,
|
|
161
|
+
updateMetrics: vi.fn(),
|
|
162
|
+
}, logger, {
|
|
163
|
+
modelName: "anthropic/claude-haiku-4-5-20251001",
|
|
164
|
+
clientOptions: { waitBetweenActions: 1 },
|
|
165
|
+
});
|
|
166
|
+
const execution = handler.execute({
|
|
167
|
+
instruction: "Describe the page briefly.",
|
|
168
|
+
highlightCursor: false,
|
|
169
|
+
});
|
|
170
|
+
await vi.waitFor(() => {
|
|
171
|
+
expect(secondPrepareStarted).toBe(true);
|
|
172
|
+
expect(logs.some((line) => line.message.includes("waiting for Browserbase to solve"))).toBe(true);
|
|
173
|
+
});
|
|
174
|
+
expect(logs.some((line) => line.message.includes("Captcha solved"))).toBe(false);
|
|
175
|
+
page.emitConsole(SOLVING_FINISHED);
|
|
176
|
+
await execution;
|
|
177
|
+
expect(fakeCuaClient.contextNotes).toEqual([
|
|
178
|
+
expect.stringContaining("automatically detected and solved"),
|
|
179
|
+
]);
|
|
180
|
+
expect(logs.some((line) => line.message.includes("Captcha solved"))).toBe(true);
|
|
181
|
+
});
|
|
182
|
+
it("pauses CUA actions until the captcha solver finishes", async () => {
|
|
183
|
+
let actionStarted = false;
|
|
184
|
+
fakeCuaClient.executeImpl = vi.fn(async () => {
|
|
185
|
+
await fakeCuaClient.preStepHook?.();
|
|
186
|
+
page.emitConsole(SOLVING_STARTED);
|
|
187
|
+
const pendingAction = fakeCuaClient.actionHandler?.({ type: "screenshot" }) ??
|
|
188
|
+
Promise.resolve();
|
|
189
|
+
actionStarted = true;
|
|
190
|
+
await pendingAction;
|
|
191
|
+
return {
|
|
192
|
+
success: true,
|
|
193
|
+
message: "ok",
|
|
194
|
+
actions: [],
|
|
195
|
+
completed: true,
|
|
196
|
+
};
|
|
197
|
+
});
|
|
198
|
+
const handler = new V3CuaAgentHandler({
|
|
199
|
+
context: {
|
|
200
|
+
awaitActivePage: async () => page,
|
|
201
|
+
},
|
|
202
|
+
bus: { emit: vi.fn() },
|
|
203
|
+
isCaptchaAutoSolveEnabled: true,
|
|
204
|
+
isAdvancedStealth: false,
|
|
205
|
+
configuredViewport: { width: 1288, height: 711 },
|
|
206
|
+
isAgentReplayActive: () => false,
|
|
207
|
+
updateMetrics: vi.fn(),
|
|
208
|
+
}, logger, {
|
|
209
|
+
modelName: "anthropic/claude-haiku-4-5-20251001",
|
|
210
|
+
clientOptions: { waitBetweenActions: 1 },
|
|
211
|
+
});
|
|
212
|
+
const executeActionSpy = vi
|
|
213
|
+
.spyOn(handler, "executeAction")
|
|
214
|
+
.mockResolvedValue({ success: true });
|
|
215
|
+
vi.spyOn(handler, "captureAndSendScreenshot").mockResolvedValue(null);
|
|
216
|
+
const execution = handler.execute({
|
|
217
|
+
instruction: "Describe the page briefly.",
|
|
218
|
+
highlightCursor: false,
|
|
219
|
+
});
|
|
220
|
+
await vi.waitFor(() => {
|
|
221
|
+
expect(actionStarted).toBe(true);
|
|
222
|
+
});
|
|
223
|
+
expect(executeActionSpy).not.toHaveBeenCalled();
|
|
224
|
+
page.emitConsole(SOLVING_FINISHED);
|
|
225
|
+
await execution;
|
|
226
|
+
expect(executeActionSpy).toHaveBeenCalledTimes(1);
|
|
227
|
+
expect(fakeCuaClient.contextNotes).toEqual([
|
|
228
|
+
expect.stringContaining("automatically detected and solved"),
|
|
229
|
+
]);
|
|
230
|
+
expect(logs.some((line) => line.message.includes("Captcha solved"))).toBe(true);
|
|
231
|
+
});
|
|
232
|
+
it("skips post-solve clicks on the captcha widget and injects another note", async () => {
|
|
233
|
+
page.captchaBoxes = [{ left: 0, top: 400, right: 140, bottom: 470 }];
|
|
234
|
+
fakeCuaClient.executeImpl = vi.fn(async () => {
|
|
235
|
+
await fakeCuaClient.preStepHook?.();
|
|
236
|
+
page.emitConsole(SOLVING_STARTED);
|
|
237
|
+
const blockedPrepare = fakeCuaClient.preStepHook?.() ?? Promise.resolve();
|
|
238
|
+
page.emitConsole(SOLVING_FINISHED);
|
|
239
|
+
await blockedPrepare;
|
|
240
|
+
await fakeCuaClient.actionHandler?.({
|
|
241
|
+
type: "click",
|
|
242
|
+
button: "left",
|
|
243
|
+
x: 63,
|
|
244
|
+
y: 436,
|
|
245
|
+
});
|
|
246
|
+
return {
|
|
247
|
+
success: true,
|
|
248
|
+
message: "ok",
|
|
249
|
+
actions: [],
|
|
250
|
+
completed: true,
|
|
251
|
+
};
|
|
252
|
+
});
|
|
253
|
+
const handler = new V3CuaAgentHandler({
|
|
254
|
+
context: {
|
|
255
|
+
awaitActivePage: async () => page,
|
|
256
|
+
},
|
|
257
|
+
bus: { emit: vi.fn() },
|
|
258
|
+
isCaptchaAutoSolveEnabled: true,
|
|
259
|
+
isAdvancedStealth: false,
|
|
260
|
+
configuredViewport: { width: 1288, height: 711 },
|
|
261
|
+
isAgentReplayActive: () => false,
|
|
262
|
+
updateMetrics: vi.fn(),
|
|
263
|
+
}, logger, {
|
|
264
|
+
modelName: "anthropic/claude-haiku-4-5-20251001",
|
|
265
|
+
clientOptions: { waitBetweenActions: 1 },
|
|
266
|
+
});
|
|
267
|
+
const executeActionSpy = vi
|
|
268
|
+
.spyOn(handler, "executeAction")
|
|
269
|
+
.mockResolvedValue({ success: true });
|
|
270
|
+
vi.spyOn(handler, "captureAndSendScreenshot").mockResolvedValue(null);
|
|
271
|
+
await handler.execute({
|
|
272
|
+
instruction: "Describe the page briefly.",
|
|
273
|
+
highlightCursor: false,
|
|
274
|
+
});
|
|
275
|
+
expect(executeActionSpy).not.toHaveBeenCalled();
|
|
276
|
+
expect(fakeCuaClient.contextNotes).toEqual([
|
|
277
|
+
expect.stringContaining("automatically detected and solved"),
|
|
278
|
+
expect.stringContaining("Original task: Describe the page briefly."),
|
|
279
|
+
]);
|
|
280
|
+
expect(logs.some((line) => line.message.includes("Skipped click on solved captcha widget"))).toBe(true);
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
//# sourceMappingURL=agent-captcha-hooks.test.js.map
|