Skip to content

Commit 423f579

Browse files
MagMuellerclaude
andauthored
chore: update OpenAPI v3 spec + llms.txt for cache_script (#115)
- Pull latest v3 OpenAPI spec from production (includes cacheScript field) - Regenerate llms.txt and llms-full.txt (includes Deterministic rerun page) Co-authored-by: MagMueller <MagMueller@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 7de308e commit 423f579

5 files changed

Lines changed: 612 additions & 246 deletions

File tree

docs/cloud/llms-full.txt

Lines changed: 233 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ for f in files.files:
474474
print(f.path, f.size)
475475

476476
# Delete a single file
477-
await client.workspaces.delete_file(workspace.id, "old-report.pdf")
477+
await client.workspaces.delete_file(workspace.id, path="old-report.pdf")
478478

479479
# Check workspace storage usage
480480
size = await client.workspaces.size(workspace.id)
@@ -498,6 +498,238 @@ You can also manage workspaces from [cloud.browser-use.com/settings](https://clo
498498
Deleting a workspace permanently removes all its files. This cannot be undone.
499499

500500

501+
# Deterministic rerun
502+
Source: https://docs.browser-use.com/cloud/agent/cache-script
503+
504+
505+
Deterministic rerun lets you run a browser task once with a full agent, then **re-execute the same task instantly** using a cached script — no LLM, up to 99% cheaper.
506+
507+
## Quick start
508+
509+
Use `{{double brackets}}` around values that can change between runs. The first call runs the full agent. Every subsequent call with the same template uses the cached script.
510+
511+
```python Python
512+
from browser_use_sdk.v3 import AsyncBrowserUse
513+
514+
client = AsyncBrowserUse()
515+
workspace = await client.workspaces.create(name="my-scraper")
516+
517+
# First call — agent explores, creates script (~$0.10, ~60s)
518+
result = await client.run(
519+
"Get the top {{5}} stories from https://news.ycombinator.com as JSON",
520+
workspace_id=str(workspace.id),
521+
)
522+
523+
# Second call — cached script, different param ($0 LLM, ~5s)
524+
result2 = await client.run(
525+
"Get the top {{10}} stories from https://news.ycombinator.com as JSON",
526+
workspace_id=str(workspace.id),
527+
)
528+
```
529+
```typescript TypeScript
530+
import { BrowserUse } from "browser-use-sdk/v3";
531+
532+
const client = new BrowserUse();
533+
const workspace = await client.workspaces.create({ name: "my-scraper" });
534+
535+
// First call — agent explores, creates script (~$0.10, ~60s)
536+
const result = await client.run(
537+
"Get the top {{5}} stories from https://news.ycombinator.com as JSON",
538+
{ workspaceId: workspace.id },
539+
);
540+
541+
// Second call — cached script, different param ($0 LLM, ~5s)
542+
const result2 = await client.run(
543+
"Get the top {{10}} stories from https://news.ycombinator.com as JSON",
544+
{ workspaceId: workspace.id },
545+
);
546+
```
547+
548+
## How it works
549+
550+
The brackets mark which parts are parameters:
551+
552+
```
553+
"Get prices from {{example.com}} for {{electronics}}"
554+
```
555+
556+
- `{{example.com}}` → parameter 1
557+
- `{{electronics}}` → parameter 2
558+
559+
The system strips the values to create a **template**: `"Get prices from {{}} for {{}}"`.
560+
Template `"Get prices from {{}} for {{}}"` is hashed to a unique ID like `a7f3b2c1`.
561+
The system checks the workspace for `scripts/a7f3b2c1.py`.
562+
If no script exists, the full agent runs your task. After completing it, the agent saves a standalone Python script that reproduces the result deterministically — no AI needed.
563+
If the script exists, it runs directly with the new parameter values. No agent, no LLM. Just the script in a sandbox with browser and proxy.
564+
565+
## Auto-detection
566+
567+
Caching activates **automatically** when both conditions are met:
568+
- The task contains `{{` and `}}`
569+
- A `workspace_id` is provided
570+
571+
No extra flags needed. You can override with `cache_script`:
572+
573+
| Value | Behavior |
574+
|-------|----------|
575+
| `None` (default) | Auto-detect from `{{brackets}}` + workspace |
576+
| `True` | Force-enable, even without brackets |
577+
| `False` | Force-disable, even if brackets are present |
578+
579+
## Examples
580+
581+
### Parameterized scraping
582+
583+
Run once, then loop over different keywords at $0 LLM each:
584+
585+
```python Python
586+
# Agent figures out how to scrape intro.co on first call
587+
result = await client.run(
588+
"Go to {{https://intro.co/marketplace}} and get all {{logistics}} experts as JSON",
589+
workspace_id=str(workspace.id),
590+
)
591+
592+
# Instant reruns with different keywords
593+
for keyword in ["CEO", "marketing", "finance", "e-commerce"]:
594+
result = await client.run(
595+
f"Go to {{{{https://intro.co/marketplace}}}} and get all {{{{{keyword}}}}} experts as JSON",
596+
workspace_id=str(workspace.id),
597+
)
598+
print(f"{keyword}: {len(result.output)} experts, LLM cost: ${result.llm_cost_usd}")
599+
```
600+
```typescript TypeScript
601+
// Agent figures out how to scrape intro.co on first call
602+
let result = await client.run(
603+
"Go to {{https://intro.co/marketplace}} and get all {{logistics}} experts as JSON",
604+
{ workspaceId: workspace.id },
605+
);
606+
607+
// Instant reruns with different keywords
608+
for (const keyword of ["CEO", "marketing", "finance", "e-commerce"]) {
609+
result = await client.run(
610+
`Go to {{https://intro.co/marketplace}} and get all {{${keyword}}} experts as JSON`,
611+
{ workspaceId: workspace.id },
612+
);
613+
console.log(`${keyword}: ${result.output.length} experts`);
614+
}
615+
```
616+
617+
### No parameters — cache the exact task
618+
619+
Append empty brackets `{{}}` to signal "cache this exact task":
620+
621+
```python Python
622+
result = await client.run(
623+
"Get the current Bitcoin price from coinmarketcap.com {{}}",
624+
workspace_id=str(workspace.id),
625+
)
626+
627+
# Same task again — cached
628+
result2 = await client.run(
629+
"Get the current Bitcoin price from coinmarketcap.com {{}}",
630+
workspace_id=str(workspace.id),
631+
)
632+
```
633+
```typescript TypeScript
634+
let result = await client.run(
635+
"Get the current Bitcoin price from coinmarketcap.com {{}}",
636+
{ workspaceId: workspace.id },
637+
);
638+
639+
// Same task again — cached
640+
result = await client.run(
641+
"Get the current Bitcoin price from coinmarketcap.com {{}}",
642+
{ workspaceId: workspace.id },
643+
);
644+
```
645+
646+
### Multiple parameters
647+
648+
```python Python
649+
result = await client.run(
650+
"Go to https://help.netflix.com/en/node/24926/ax and get subscription prices for {{Germany,France,Japan}}",
651+
workspace_id=str(workspace.id),
652+
)
653+
654+
# Different countries — cached
655+
result2 = await client.run(
656+
"Go to https://help.netflix.com/en/node/24926/ax and get subscription prices for {{US,UK,Brazil}}",
657+
workspace_id=str(workspace.id),
658+
)
659+
```
660+
```typescript TypeScript
661+
let result = await client.run(
662+
"Go to https://help.netflix.com/en/node/24926/ax and get subscription prices for {{Germany,France,Japan}}",
663+
{ workspaceId: workspace.id },
664+
);
665+
666+
// Different countries — cached
667+
result = await client.run(
668+
"Go to https://help.netflix.com/en/node/24926/ax and get subscription prices for {{US,UK,Brazil}}",
669+
{ workspaceId: workspace.id },
670+
);
671+
```
672+
673+
### Force enable / disable
674+
675+
```python Python
676+
# Force-enable without brackets
677+
result = await client.run(
678+
"Get the top stories from Hacker News",
679+
workspace_id=str(workspace.id),
680+
cache_script=True,
681+
)
682+
683+
# Force-disable even with brackets
684+
result = await client.run(
685+
"Explain what {{templates}} means in Jinja",
686+
workspace_id=str(workspace.id),
687+
cache_script=False,
688+
)
689+
```
690+
```typescript TypeScript
691+
// Force-enable without brackets
692+
let result = await client.run(
693+
"Get the top stories from Hacker News",
694+
{ workspaceId: workspace.id, cacheScript: true },
695+
);
696+
697+
// Force-disable even with brackets
698+
result = await client.run(
699+
"Explain what {{templates}} means in Jinja",
700+
{ workspaceId: workspace.id, cacheScript: false },
701+
);
702+
```
703+
704+
## Inspecting cached scripts
705+
706+
You can download and inspect the scripts the agent created:
707+
708+
```python Python
709+
files = await client.workspaces.files(workspace.id, prefix="scripts/")
710+
for f in files.files:
711+
print(f"{f.path} ({f.size} bytes)")
712+
713+
# Download a script to inspect it
714+
await client.workspaces.download(workspace.id, "scripts/a7f3b2c1.py", to="./my_script.py")
715+
```
716+
```typescript TypeScript
717+
const files = await client.workspaces.files(workspace.id, { prefix: "scripts/" });
718+
for (const f of files.files) {
719+
console.log(`${f.path} (${f.size} bytes)`);
720+
}
721+
```
722+
723+
## Cost comparison
724+
725+
| | LLM cost | Browser + proxy | Time |
726+
|---|---|---|---|
727+
| First call (agent) | ~$0.05–1.00 | Yes | ~30–120s |
728+
| Cached calls | **$0** | Yes | ~3–10s |
729+
730+
The browser and proxy still run for cached calls (the script may need them), so there is a small infrastructure cost per execution. LLM cost drops to zero.
731+
732+
501733
# Human in the loop
502734
Source: https://docs.browser-use.com/cloud/agent/human-in-the-loop
503735

docs/cloud/llms.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export BROWSER_USE_API_KEY=bu_your_key_here
3131
- [Follow-up tasks](https://docs.browser-use.com/cloud/agent/follow-up-tasks): Run multiple tasks in the same browser session.
3232
- [Live messages](https://docs.browser-use.com/cloud/agent/streaming): Stream the agent's messages in real time to build custom UIs or monitor progress.
3333
- [Workspaces & files](https://docs.browser-use.com/cloud/agent/workspaces): Upload files for the agent, download files the agent creates.
34+
- [Deterministic rerun](https://docs.browser-use.com/cloud/agent/cache-script): Run a task once, then re-execute it for $0 LLM cost.
3435
- [Human in the loop](https://docs.browser-use.com/cloud/agent/human-in-the-loop): Let a human interact with the live browser while the agent is running. Useful for approvals, payments, complex auth flows, or reviewing agent work before continuing.
3536

3637
## Browser

0 commit comments

Comments
 (0)