From 74dfaa675d779e47f05b7dd8d1bb4197606dda94 Mon Sep 17 00:00:00 2001 From: tkattkat Date: Thu, 23 Oct 2025 15:37:29 -0700 Subject: [PATCH 1/3] add cua replay example script --- packages/core/examples/v3/cuaReplay.ts | 84 +++++++++++++++++++++++--- 1 file changed, 76 insertions(+), 8 deletions(-) diff --git a/packages/core/examples/v3/cuaReplay.ts b/packages/core/examples/v3/cuaReplay.ts index ab811d104..48bd86da4 100644 --- a/packages/core/examples/v3/cuaReplay.ts +++ b/packages/core/examples/v3/cuaReplay.ts @@ -1,6 +1,18 @@ import { V3 } from "../../lib/v3"; +import { v3Logger } from "../../lib/v3/logger"; +import dotenv from "dotenv"; + +dotenv.config(); + +async function runDemo(runNumber: number) { + const startTime = Date.now(); + + v3Logger({ + level: 1, + category: "demo", + message: `RUN ${runNumber}: ${runNumber === 1 ? "BUILDING CACHE" : "USING CACHE"}`, + }); -async function main() { const v3 = new V3({ env: "LOCAL", verbose: 1, @@ -9,21 +21,77 @@ async function main() { await v3.init(); - const startPage = v3.context.pages()[0]; - await startPage.goto( - "https://browserbase.github.io/stagehand-eval-sites/sites/drag-drop/", - ); + const page = v3.context.pages()[0]; + + await page.goto("https://v0-modern-login-flow.vercel.app/", { + waitUntil: "networkidle", + }); + const agent = v3.agent({ cua: true, model: "anthropic/claude-sonnet-4-20250514", }); const result = await agent.execute({ - instruction: "drag 'text' to zone A.", + instruction: `Sign in with the email address 'test@browserbaser.com' and the password 'stagehand=goated'`, maxSteps: 20, }); - console.log(JSON.stringify(result, null, 2)); + const endTime = Date.now(); + const duration = (endTime - startTime) / 1000; + + await v3.context.close(); + + return { + duration, + success: result.success, + result, + }; +} + +async function main() { + const metrics1 = await runDemo(1); + + v3Logger({ + level: 1, + category: "demo", + message: "⏳ Waiting 2 seconds before cached run...", + }); + await new Promise((resolve) => setTimeout(resolve, 2000)); + + v3Logger({ + level: 1, + category: "demo", + message: "Starting second run with cache...", + }); + const metrics2 = await runDemo(2); + + const duration1 = `${metrics1.duration.toFixed(2)}s`; + const duration2 = `${metrics2.duration.toFixed(2)}s`; + + v3Logger({ + level: 1, + category: "demo", + message: ` +╔════════════════════════════════════════════════════════════╗ +║ 📊 PERFORMANCE COMPARISON ║ +╚════════════════════════════════════════════════════════════╝ + +┌─────────────────────┬──────────────────┬──────────────────┐ +│ Metric │ Run 1 (Cold) │ Run 2 (Cached) │ +├─────────────────────┼──────────────────┼──────────────────┤ +│ Duration │ ${duration1.padEnd(16)} │ ${duration2.padEnd(16)} │ +└─────────────────────┴──────────────────┴──────────────────┘ + + Performance Comparison: + • Speed: ${((1 - metrics2.duration / metrics1.duration) * 100).toFixed(1)}% faster with cache + • Time saved: ${(metrics1.duration - metrics2.duration).toFixed(2)} seconds + + Insights: + • First run establishes the CUA action cache + • Second run reuses cached actions for instant execution + • Zero LLM tokens used on cached run`, + }); } -main(); +main().catch(console.error); From 579e5686d193b40f6e9909afb85d3e40806782d1 Mon Sep 17 00:00:00 2001 From: Sean McGuire Date: Wed, 5 Nov 2025 10:30:53 -0800 Subject: [PATCH 2/3] change v3 to stagehand --- packages/core/examples/v3/cuaReplay.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/core/examples/v3/cuaReplay.ts b/packages/core/examples/v3/cuaReplay.ts index 48bd86da4..2ddd3ca59 100644 --- a/packages/core/examples/v3/cuaReplay.ts +++ b/packages/core/examples/v3/cuaReplay.ts @@ -1,4 +1,4 @@ -import { V3 } from "../../lib/v3"; +import { Stagehand } from "../../lib/v3"; import { v3Logger } from "../../lib/v3/logger"; import dotenv from "dotenv"; @@ -13,21 +13,21 @@ async function runDemo(runNumber: number) { message: `RUN ${runNumber}: ${runNumber === 1 ? "BUILDING CACHE" : "USING CACHE"}`, }); - const v3 = new V3({ + const stagehand = new Stagehand({ env: "LOCAL", verbose: 1, cacheDir: "cua-agent-cache", }); - await v3.init(); + await stagehand.init(); - const page = v3.context.pages()[0]; + const page = stagehand.context.pages()[0]; await page.goto("https://v0-modern-login-flow.vercel.app/", { waitUntil: "networkidle", }); - const agent = v3.agent({ + const agent = stagehand.agent({ cua: true, model: "anthropic/claude-sonnet-4-20250514", }); @@ -40,7 +40,7 @@ async function runDemo(runNumber: number) { const endTime = Date.now(); const duration = (endTime - startTime) / 1000; - await v3.context.close(); + await stagehand.context.close(); return { duration, From b346ad6d6f660bf192985f002b3f37029216adf0 Mon Sep 17 00:00:00 2001 From: Sean McGuire Date: Wed, 5 Nov 2025 10:33:56 -0800 Subject: [PATCH 3/3] call stagehand.close() --- packages/core/examples/v3/cuaReplay.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/examples/v3/cuaReplay.ts b/packages/core/examples/v3/cuaReplay.ts index 2ddd3ca59..448ca6fb9 100644 --- a/packages/core/examples/v3/cuaReplay.ts +++ b/packages/core/examples/v3/cuaReplay.ts @@ -40,7 +40,7 @@ async function runDemo(runNumber: number) { const endTime = Date.now(); const duration = (endTime - startTime) / 1000; - await stagehand.context.close(); + await stagehand.close(); return { duration,