Skip to content

Commit 1bbe35a

Browse files
add cua replay example script (#1162)
# why Update example script to show benefits from using cached actions image of what the final log looks like <img width="948" height="506" alt="image" src="https://github.com/user-attachments/assets/2307e7c2-6a59-4173-b459-14e062800f4c" /> # what changed # test plan --------- Co-authored-by: Sean McGuire <[email protected]>
1 parent 6fc9de2 commit 1bbe35a

File tree

1 file changed

+80
-12
lines changed

1 file changed

+80
-12
lines changed
Lines changed: 80 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,97 @@
1-
import { V3 } from "../../lib/v3";
1+
import { Stagehand } from "../../lib/v3";
2+
import { v3Logger } from "../../lib/v3/logger";
3+
import dotenv from "dotenv";
24

3-
async function main() {
4-
const v3 = new V3({
5+
dotenv.config();
6+
7+
async function runDemo(runNumber: number) {
8+
const startTime = Date.now();
9+
10+
v3Logger({
11+
level: 1,
12+
category: "demo",
13+
message: `RUN ${runNumber}: ${runNumber === 1 ? "BUILDING CACHE" : "USING CACHE"}`,
14+
});
15+
16+
const stagehand = new Stagehand({
517
env: "LOCAL",
618
verbose: 1,
719
cacheDir: "cua-agent-cache",
820
});
921

10-
await v3.init();
22+
await stagehand.init();
23+
24+
const page = stagehand.context.pages()[0];
1125

12-
const startPage = v3.context.pages()[0];
13-
await startPage.goto(
14-
"https://browserbase.github.io/stagehand-eval-sites/sites/drag-drop/",
15-
);
16-
const agent = v3.agent({
26+
await page.goto("https://v0-modern-login-flow.vercel.app/", {
27+
waitUntil: "networkidle",
28+
});
29+
30+
const agent = stagehand.agent({
1731
cua: true,
1832
model: "anthropic/claude-sonnet-4-20250514",
1933
});
2034

2135
const result = await agent.execute({
22-
instruction: "drag 'text' to zone A.",
36+
instruction: `Sign in with the email address '[email protected]' and the password 'stagehand=goated'`,
2337
maxSteps: 20,
2438
});
2539

26-
console.log(JSON.stringify(result, null, 2));
40+
const endTime = Date.now();
41+
const duration = (endTime - startTime) / 1000;
42+
43+
await stagehand.close();
44+
45+
return {
46+
duration,
47+
success: result.success,
48+
result,
49+
};
50+
}
51+
52+
async function main() {
53+
const metrics1 = await runDemo(1);
54+
55+
v3Logger({
56+
level: 1,
57+
category: "demo",
58+
message: "⏳ Waiting 2 seconds before cached run...",
59+
});
60+
await new Promise((resolve) => setTimeout(resolve, 2000));
61+
62+
v3Logger({
63+
level: 1,
64+
category: "demo",
65+
message: "Starting second run with cache...",
66+
});
67+
const metrics2 = await runDemo(2);
68+
69+
const duration1 = `${metrics1.duration.toFixed(2)}s`;
70+
const duration2 = `${metrics2.duration.toFixed(2)}s`;
71+
72+
v3Logger({
73+
level: 1,
74+
category: "demo",
75+
message: `
76+
╔════════════════════════════════════════════════════════════╗
77+
║ 📊 PERFORMANCE COMPARISON ║
78+
╚════════════════════════════════════════════════════════════╝
79+
80+
┌─────────────────────┬──────────────────┬──────────────────┐
81+
│ Metric │ Run 1 (Cold) │ Run 2 (Cached) │
82+
├─────────────────────┼──────────────────┼──────────────────┤
83+
│ Duration │ ${duration1.padEnd(16)}${duration2.padEnd(16)}
84+
└─────────────────────┴──────────────────┴──────────────────┘
85+
86+
Performance Comparison:
87+
• Speed: ${((1 - metrics2.duration / metrics1.duration) * 100).toFixed(1)}% faster with cache
88+
• Time saved: ${(metrics1.duration - metrics2.duration).toFixed(2)} seconds
89+
90+
Insights:
91+
• First run establishes the CUA action cache
92+
• Second run reuses cached actions for instant execution
93+
• Zero LLM tokens used on cached run`,
94+
});
2795
}
2896

29-
main();
97+
main().catch(console.error);

0 commit comments

Comments
 (0)