Skip to content

Magnus/browser use rust main integration#68

Open
MagMueller wants to merge 54 commits into
mainfrom
magnus/browser-use-rust-main-integration
Open

Magnus/browser use rust main integration#68
MagMueller wants to merge 54 commits into
mainfrom
magnus/browser-use-rust-main-integration

Conversation

@MagMueller
Copy link
Copy Markdown
Contributor

@MagMueller MagMueller commented Jun 5, 2026

Summary by cubic

Integrates Remote CDP browser mode, Anthropic prompt caching, and bounded-run controls while upgrading browser scripting, result handling, and tracing across the Rust and Python paths. This improves reliability, reduces prompt size, and aligns usage accounting and finalization with Browser Use behavior.

  • New Features
    • Remote CDP mode: direct browser_script page work with clear prompt guidance; no connect/start commands.
    • Anthropic prompt cache: adds cache breakpoints and ephemeral tool caching; normalizes usage with cache_creation_input_tokens.
    • Bounded runs: honors max_turns and injects progress/final nudges; CLI applies runtime config overrides.
    • Finalization: done tool now accepts { "result"?, "result_file"?, "text"? }; registry and tests updated.
    • Browser scripting: adds http_get_many, browser_fetch, and browser_fetch_many; retries transient bridge errors; sturdier startup/waits; caps inline stdout to 4 KB (summaries preserved) and image dimension to 8k; structured fallback when text is empty.
    • Browser profile/runtime: applies user agent, launch args, viewport, permissions, download behavior, storage state, and domain constraints in worker and Rust.
    • Tracing/replay: records full LLM input messages and tool definitions; avoids duplicate prompt replay tails.

Written for commit 98c530c. Summary will update on new commits.

Review in cubic

gregpr07 added 30 commits June 3, 2026 07:25
…st-main-integration

# Conflicts:
#	crates/browser-use-agent/src/tools/handlers/browser.rs
…st-main-integration

# Conflicts:
#	crates/browser-use-browser/src/browser_script_helpers.py
#	crates/browser-use-browser/src/lib.rs
gregpr07 added 24 commits June 4, 2026 10:34
…st-main-integration

# Conflicts:
#	crates/browser-use-agent/src/entrypoint/mod.rs
#	crates/browser-use-agent/src/tools/handlers/browser.rs
#	crates/browser-use-agent/src/tools/handlers/browser_tests.rs
#	crates/browser-use-agent/src/turn/sampling.rs
#	crates/browser-use-browser/src/lib.rs
#	crates/browser-use-cli/src/main.rs
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

7 issues found across 36 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="crates/browser-use-agent/src/tools/handlers/browser_tests.rs">

<violation number="1" location="crates/browser-use-agent/src/tools/handlers/browser_tests.rs:476">
P3: These tests are flaky under parallel execution because they share mutable global env state without synchronization. Serialize BU_CDP_URL mutations (or run these tests serially) to avoid cross-test interference.</violation>
</file>

<file name="crates/browser-use-agent/src/entrypoint/mod.rs">

<violation number="1" location="crates/browser-use-agent/src/entrypoint/mod.rs:2558">
P2: Disabling recorded-tail replay unconditionally can drop all prompt context when runtime journal reads fail. This turns a transient runtime read error into context loss for subsequent sampling.</violation>
</file>

<file name="python/llm_browser_worker/worker.py">

<violation number="1" location="python/llm_browser_worker/worker.py:257">
P2: Domain constraints are enforced even when no constraint env vars are set. This can wrongly block valid relative navigations in the Python worker and diverges from the Rust runtime behavior.</violation>
</file>

<file name="crates/browser-use-browser/src/browser_script_helpers.py">

<violation number="1" location="crates/browser-use-browser/src/browser_script_helpers.py:429">
P2: Unconditional `ensure_real_tab()` makes `page_info`/screenshot helpers switch tabs implicitly. In multi-tab runs this can make subsequent actions inspect or act on the wrong page.</violation>

<violation number="2" location="crates/browser-use-browser/src/browser_script_helpers.py:1169">
P1: `browser_fetch` silently corrupts binary request bodies by converting bytes to latin1 text before JS fetch. Requests that require exact byte payloads will be sent with different bytes.</violation>
</file>

<file name="crates/browser-use-browser/src/lib.rs">

<violation number="1" location="crates/browser-use-browser/src/lib.rs:3845">
P1: Domain allow/block enforcement misses `Target.createTarget` URL navigation path. A blocked domain can still be opened by creating a target with that URL.</violation>

<violation number="2" location="crates/browser-use-browser/src/lib.rs:3861">
P2: Profile runtime setup dedup persists across reconnects, so required setup may not run on a new connection. This can silently drop permissions/download/storage initialization after browser restart or endpoint switch.</violation>
</file>

Tip: instead of fixing issues one by one fix them all with cubic

Re-trigger cubic

if not any(k.lower() == "content-type" for k in request_headers):
request_headers["Content-Type"] = "application/json"
if isinstance(request_body, bytes):
request_body = request_body.decode("latin1")
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot Jun 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: browser_fetch silently corrupts binary request bodies by converting bytes to latin1 text before JS fetch. Requests that require exact byte payloads will be sent with different bytes.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/browser-use-browser/src/browser_script_helpers.py, line 1169:

<comment>`browser_fetch` silently corrupts binary request bodies by converting bytes to latin1 text before JS fetch. Requests that require exact byte payloads will be sent with different bytes.</comment>

<file context>
@@ -992,3 +1096,240 @@ def http_get(url, headers=None, timeout=20.0, binary=None):
+        if not any(k.lower() == "content-type" for k in request_headers):
+            request_headers["Content-Type"] = "application/json"
+    if isinstance(request_body, bytes):
+        request_body = request_body.decode("latin1")
+    return {
+        "url": str(url),
</file context>
Suggested change
request_body = request_body.decode("latin1")
raise TypeError("browser_fetch body bytes are unsupported; pass str/json_body or base64-encode manually")
Fix with cubic

session_id: Option<&str>,
params: &Value,
) -> Result<()> {
if method == "Page.navigate" {
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot Jun 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Domain allow/block enforcement misses Target.createTarget URL navigation path. A blocked domain can still be opened by creating a target with that URL.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/browser-use-browser/src/lib.rs, line 3845:

<comment>Domain allow/block enforcement misses `Target.createTarget` URL navigation path. A blocked domain can still be opened by creating a target with that URL.</comment>

<file context>
@@ -3347,6 +3836,47 @@ impl BrowserSession {
+        session_id: Option<&str>,
+        params: &Value,
+    ) -> Result<()> {
+        if method == "Page.navigate" {
+            if let Some(url) = params.get("url").and_then(Value::as_str) {
+                if !browser_profile_url_allowed(url) {
</file context>
Suggested change
if method == "Page.navigate" {
if matches!(method, "Page.navigate" | "Target.createTarget") {
Fix with cubic

.with_runtime_handle(Some(runtime_handle.clone()))
.with_mailbox_delivery_phase(mailbox_delivery_phase);
.with_mailbox_delivery_phase(mailbox_delivery_phase)
.with_durable_prompt_replay();
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot Jun 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Disabling recorded-tail replay unconditionally can drop all prompt context when runtime journal reads fail. This turns a transient runtime read error into context loss for subsequent sampling.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/browser-use-agent/src/entrypoint/mod.rs, line 2558:

<comment>Disabling recorded-tail replay unconditionally can drop all prompt context when runtime journal reads fail. This turns a transient runtime read error into context loss for subsequent sampling.</comment>

<file context>
@@ -2499,13 +2547,15 @@ impl<Sd: SamplingDriver> RuntimeTurnLoopDriver<Sd> {
             .with_runtime_handle(Some(runtime_handle.clone()))
-            .with_mailbox_delivery_phase(mailbox_delivery_phase);
+            .with_mailbox_delivery_phase(mailbox_delivery_phase)
+            .with_durable_prompt_replay();
         // Enable REAL token accounting + model-based compaction when a sampler is
         // available (the real backend path). The Fake/no-credential path passes `None`
</file context>
Fix with cubic

raw = os.environ.get("BU_BROWSER_PERMISSIONS")
if not raw:
return []
try:
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot Jun 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Domain constraints are enforced even when no constraint env vars are set. This can wrongly block valid relative navigations in the Python worker and diverges from the Rust runtime behavior.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At python/llm_browser_worker/worker.py, line 257:

<comment>Domain constraints are enforced even when no constraint env vars are set. This can wrongly block valid relative navigations in the Python worker and diverges from the Rust runtime behavior.</comment>

<file context>
@@ -230,6 +234,275 @@ def _browser_mode() -> str:
+    raw = os.environ.get("BU_BROWSER_PERMISSIONS")
+    if not raw:
+        return []
+    try:
+        parsed = json.loads(raw)
+    except json.JSONDecodeError:
</file context>
Fix with cubic

@@ -12,9 +12,11 @@
import os
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot Jun 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Unconditional ensure_real_tab() makes page_info/screenshot helpers switch tabs implicitly. In multi-tab runs this can make subsequent actions inspect or act on the wrong page.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/browser-use-browser/src/browser_script_helpers.py, line 429:

<comment>Unconditional `ensure_real_tab()` makes `page_info`/screenshot helpers switch tabs implicitly. In multi-tab runs this can make subsequent actions inspect or act on the wrong page.</comment>

<file context>
@@ -386,6 +425,10 @@ def goto_url(url):
 def page_info():
     """Return url, title, viewport, scroll position, page size, and target info."""
+    try:
+        ensure_real_tab()
+    except Exception:
+        pass
</file context>
Fix with cubic

Comment on lines +3861 to +3875
if self
.browser_profile_runtime
.applied_setup_keys
.contains(&call.key)
{
continue;
}
if connection
.call(&call.method, call.session_id.as_deref(), call.params)
.is_ok()
{
self.browser_profile_runtime
.applied_setup_keys
.insert(call.key);
}
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot Jun 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Profile runtime setup dedup persists across reconnects, so required setup may not run on a new connection. This can silently drop permissions/download/storage initialization after browser restart or endpoint switch.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/browser-use-browser/src/lib.rs, line 3861:

<comment>Profile runtime setup dedup persists across reconnects, so required setup may not run on a new connection. This can silently drop permissions/download/storage initialization after browser restart or endpoint switch.</comment>

<file context>
@@ -3347,6 +3836,47 @@ impl BrowserSession {
+            return Ok(());
+        };
+        for call in setup_calls {
+            if self
+                .browser_profile_runtime
+                .applied_setup_keys
</file context>
Suggested change
if self
.browser_profile_runtime
.applied_setup_keys
.contains(&call.key)
{
continue;
}
if connection
.call(&call.method, call.session_id.as_deref(), call.params)
.is_ok()
{
self.browser_profile_runtime
.applied_setup_keys
.insert(call.key);
}
let scoped_key = format!("{}:{}", self.connection_generation, call.key.as_str());
if self
.browser_profile_runtime
.applied_setup_keys
.contains(&scoped_key)
{
continue;
}
if connection
.call(&call.method, call.session_id.as_deref(), call.params)
.is_ok()
{
self.browser_profile_runtime
.applied_setup_keys
.insert(scoped_key);
}
Fix with cubic


#[tokio::test]
async fn bare_browser_connect_resolves_to_selected_remote_cdp_mode() {
let _guard = EnvVarGuard::set(
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot Jun 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: These tests are flaky under parallel execution because they share mutable global env state without synchronization. Serialize BU_CDP_URL mutations (or run these tests serially) to avoid cross-test interference.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/browser-use-agent/src/tools/handlers/browser_tests.rs, line 476:

<comment>These tests are flaky under parallel execution because they share mutable global env state without synchronization. Serialize BU_CDP_URL mutations (or run these tests serially) to avoid cross-test interference.</comment>

<file context>
@@ -427,6 +471,60 @@ async fn bare_browser_connect_resolves_to_selected_cloud_mode() {
 
+#[tokio::test]
+async fn bare_browser_connect_resolves_to_selected_remote_cdp_mode() {
+    let _guard = EnvVarGuard::set(
+        "BU_CDP_URL",
+        "ws://127.0.0.1:9222/devtools/browser/session-id",
</file context>
Fix with cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants