Commit Graph

231 Commits

Author SHA1 Message Date
Gregor Žunič 1bd773f7ad fix: preserve evaluate code in agent memory 2026-07-21 22:32:42 -07:00
Saurav Panda b88fd70481 fix(tools): truncate long URLs in save_as_pdf footer so page numbers stay visible
A flex item defaults to min-width:auto and won't shrink below its content,
so a long/unbroken URL in the default footer template overflowed and pushed
the page / totalPages span off the printable area. Give the url span
min-width:0 + overflow ellipsis so it truncates, and flex-shrink:0 on the
page-count span so it always renders. Adds a long-URL regression test.
2026-06-15 13:54:38 +05:30
Saurav Panda ad8f3a4dd7 feat(tools): print page metadata in save_as_pdf header/footer
The save_as_pdf action now renders page metadata into the PDF margins by
default, matching Chrome's Print dialog: the date in the header and the page
URL plus page numbers in the footer.

- Add display_header_footer (default True), header_template, and
  footer_template params to SaveAsPdfAction.
- Pass displayHeaderFooter + header/footer templates and explicit margins to
  CDP Page.printToPDF so the metadata has room to render (Chrome clips it
  otherwise, and defaults header/footer font-size to 0px).
- Default templates show the date / URL + page numbers; callers can override
  with custom HTML or disable entirely for a clean PDF.
2026-06-11 08:29:41 +05:30
Laith Weinberger 8bca742aba support claude fable 5
- fable for coord clicks
- explicit support
- model refusal response
- fable pricing with 5m/1h cache writes and inference geo multiplier
- anthropic fallback, thinking, output config, and inference geo request support
2026-06-09 13:22:04 -07:00
MagMueller af9d406419 Revert "fix(tools): refuse evaluate() on restricted browser profiles (#4871)"
This reverts commit d6a87c0961, reversing
changes made to eeff4d1984.
2026-05-23 12:13:38 -07:00
Saurav Panda e5f9b46f95 refactor(tools): tighten evaluate() guard comment
Drop the running narrative; the function name + the one-line why is
enough. Error message stays actionable but no longer reiterates the
threat model.

No behavior change; 6/6 tests pass.
2026-05-18 18:42:29 -07:00
Saurav Panda 8f2967a5c0 fix(tools): include prohibited_domains in evaluate guard
SecurityWatchdog enforces prohibited_domains as a navigation restriction
alongside allowed_domains. Without prohibited_domains in the evaluate()
guard, a profile using only the deny-list could still load an allowed page
and have the agent fetch() into a blocked domain via JS.

Add prohibited_domains to the restriction check.
2026-05-18 18:37:12 -07:00
Saurav Panda a7ce680948 fix(tools): refuse evaluate() on restricted browser profiles
The agent's evaluate() action called Runtime.evaluate directly through
CDP. SecurityWatchdog only subscribes to navigation events, so JS
running inside an already-allowed page could fetch() arbitrary internal
URLs, read cookies and localStorage from any allowed origin's context,
and otherwise act as if allowed_domains / block_ip_addresses weren't
configured.

When a profile has allowed_domains or block_ip_addresses set, the
operator has signalled the agent is constrained — exposing an unmediated
JS evaluation primitive contradicts that signal. Refuse evaluate()
outright on such profiles; agents that need JS can run on an unrestricted
profile.

Empty allowed_domains=[] is treated as 'no restriction' elsewhere in the
codebase (e.g. SecurityWatchdog); evaluate() behaves consistently and
does not refuse in that case.
2026-05-18 18:30:04 -07:00
Saurav Panda 65a377c20f fix(tools): only rewrite upload path to FileSystem on local sessions
Addresses codex review on #4865.

For remote (`is_local=False`) sessions, `params.path` is meant to reference
a file on the remote machine. A coincidental basename collision with a
local FileSystem-managed file (e.g. `/tmp/note.md` colliding with a local
managed `note.md`) would silently rewrite the upload to point at the local
file, uploading the wrong file with no indication to the agent.

Gate the FileSystem rewrite on `browser_session.is_local`. On remote
sessions, fall through to the existing pass-through branch that allows
remote-accessible absolute paths.

Add a regression test that exercises the remote-session basename-collision
case and asserts the local FileSystem path never appears in the resolved
upload path.
2026-05-18 15:05:08 -07:00
Saurav Panda a209c5ed38 fix(tools): contain upload_file path inside FileSystem dir
GHSA-j9hj-92j8-jv9h.

The `upload_file` action constructed the absolute upload path by joining
`file_system.get_dir()` with the agent-controlled `params.path`. Because
`FileSystem.get_file()` matches by basename (`os.path.basename` first), an
agent-controlled path like `../note.md` would:

1. Pass `get_file()` lookup if a file named `note.md` exists in the FileSystem.
2. Be naively joined to `data_dir`, producing `data_dir/../note.md` — which
   resolves to a sibling file outside the FileSystem directory.
3. Be uploaded to the browser as the resolved (escaped) file, surfacing
   arbitrary contents from outside `browseruse_agent_data` to whatever file
   input was targeted.

Use the FileSystem-owned `file_obj.full_name` for the join. Add a
`os.path.realpath` containment check as defense in depth; if it ever resolves
outside `data_dir`, refuse the upload.
2026-05-18 13:43:34 -07:00
Saurav Panda 32416bb48c address codex review: validate tools.act(action_timeout=...) override
P2 codex comment on 9a09c4d7: the public `action_timeout` parameter on
tools.act() skipped the same defensive validation that the env-var path
already had. Passing nan made every action time out instantly; inf /
<=0 disabled the guard entirely. Either mode silently defeats the safety
this module exists to provide, especially for callers sourcing timeouts
from runtime config.

Extracted _coerce_valid_action_timeout() (pairs with _parse_env_action_
timeout) and routed the override through it. None / nan / inf /
non-positive all fall back to the env-derived default with a warning.

New test_act_rejects_invalid_action_timeout_override asserts the
fallback by passing bad values and verifying the fast handler actually
executes to completion (which wouldn't happen if nan → immediate
timeout or if inf → hang would leak through).
2026-04-20 17:55:59 -07:00
Saurav Panda d2985dcab9 review: reject non-finite timeouts + restore module after reload tests
Two more issues from automated review on #4711:

1. (P2, Codex) float() accepts 'nan' and 'inf' — both parse successfully
   and bypass the fallback path. 'nan' makes asyncio.wait_for time out
   immediately for every action; 'inf' effectively disables the hang
   guard. Extracted the parse into _parse_env_action_timeout() which
   rejects non-finite and non-positive values (including 0 and negatives)
   with a warning + fallback.

2. (P2, Cubic) The previous reload test left browser_use.tools.service
   pinned at _DEFAULT_ACTION_TIMEOUT_S=45.0 (the last monkeypatch value),
   which would leak into any later test in the same worker. Added a
   _restore_service_module fixture that pops the env var and reloads
   cleanly on teardown.

Expanded test coverage to include 'nan', 'NaN', 'inf', '-inf', '0', '-5'
alongside the existing '' / 'abc' cases — all fall back to 180s.
2026-04-20 15:45:36 -07:00
Saurav Panda 1488a39b7f address PR review: raise default cap + tolerate bad env values
Two issues flagged by automated review on #4711:

1. (P1, Codex) The 90s default was *below* the extract action's intentional
   120s page_extraction_llm.ainvoke timeout (tools/service.py:1096,1172).
   Slow-but-valid extractions against large pages would be truncated into
   timeout errors — a regression. Raised default to 180s, which sits above
   that 120s inner cap with grace.

2. (P2, Cubic + Codex) float(os.getenv('BROWSER_USE_ACTION_TIMEOUT_S', '90'))
   ran at import time. An empty or non-numeric value (common with env
   templating) raised ValueError and prevented browser_use.tools.service
   from importing at all — turning a config typo into a process-wide
   startup failure. Wrapped in try/except with a warning and fallback to
   the hardcoded 180s default.

Tests:
- test_default_action_timeout_accommodates_extract_action — pins the
  default >= 150s so future edits can't silently regress extract.
- test_malformed_env_timeout_does_not_break_import — reloads the module
  with empty / non-numeric env values and asserts it falls back cleanly,
  plus verifies a valid numeric env value still takes effect.
2026-04-20 15:36:15 -07:00
Saurav Panda ce81ada89a fix(tools): enforce per-action timeout to prevent hung event handlers
Individual CDP calls like Page.navigate() have their own 20s timeouts, but
the surrounding event-bus plumbing (await event, event_result()) does not.
When a cloud browser's CDP WebSocket goes silent mid-session, agent handlers
hang indefinitely — agents never emit a step, any outer watchdog eventually
fires, and the run returns with zero history.

Observed in practice: a 170k-task collector run produced 1,090 empty-history
traces (21% of output). 100% hit the 240s outer watchdog; median 582s, max
2214s. Cloud HTTP layer was clean (all 200/201) — hang was entirely in CDP.

Wrap registry.execute_action in asyncio.wait_for with a configurable per-
action cap (default 90s, BROWSER_USE_ACTION_TIMEOUT_S env var or
tools.act(action_timeout=...)). On timeout, the action returns
ActionResult(error=...) so the agent can record the step and recover.

New tests/ci/test_action_timeout.py covers both hung and fast handlers.
Existing tools.act tests (test_multi_act_guards, test_action_blank_page)
still pass.
2026-04-20 15:22:30 -07:00
Laith Weinberger 4476f6e16e fix input clear fallbacks and clarify clear-then-type behavior 2026-04-15 17:31:04 -04:00
Saurav Panda 4a65aea6a9 Merge branch 'main' into auto-switch-new-tab 2026-03-21 17:17:32 -07:00
Laith Weinberger 43b5e4ce1d rm code agent 2026-03-21 02:05:42 -04:00
Saurav Panda e7a05cbe86 fix: auto-switch to new tabs after click and add checkbox toggle fallback
- AGI-569: after any click that opens a new tab, automatically dispatch
  SwitchTabEvent so the agent lands on the new page immediately instead
  of requiring a manual switch step (~877 occurrences)

- AGI-548: for <input type="checkbox/radio">, capture checked state
  before the CDP mouse click and verify it toggled afterward; if
  unchanged (custom-styled or shadow-DOM-backed inputs), fall back to
  JS element.click() and report the final checked state in metadata
  (~1,241 occurrences)
2026-03-20 12:43:58 -07:00
ShawnPana 91c02012c3 merge origin/main into cli, resolve agent.py delete conflict 2026-03-19 21:06:38 -07:00
Saurav Panda c53ff656f5 check root before llm_representation fallback 2026-03-19 20:17:46 -07:00
Saurav Panda 6d86be3a6b fix: detect skeleton screens and retry navigation for blank SPA pages 2026-03-19 18:48:47 -07:00
ShawnPana 694a111fad add upload command to CLI, extract find_file_input_near_element to BrowserSession
- Add `browser-use upload <index> <path>` command for uploading files to
  file input elements via the CLI
- Extract find_file_input_near_element from nested closures in tools/service.py
  to a reusable method on BrowserSession, deduplicating two copies
- Add BrowserWrapper.upload() for the Python REPL
- Resolve file paths to absolute on the client side before sending to daemon
- Update SKILL.md files and README with upload command docs
2026-03-19 17:02:34 -07:00
Saurav Panda cc1cf2b1c7 Merge branch 'main' into fix-image-url-stripping 2026-03-19 15:34:27 -07:00
Saurav Panda 9445a9ff9e fix image URLs stripped from extracted markdown 2026-03-19 15:29:06 -07:00
Saurav Panda 0dea9480ee Merge branch 'main' into fix-compaction-hallucination 2026-03-17 15:43:11 -07:00
Saurav Panda 02349f1d9c fix: prevent compaction hallucination 2026-03-17 15:39:35 -07:00
Saurav Panda 73d64d7bb5 remove read long content action 2026-03-12 12:44:10 -07:00
Saurav Panda 990e0ce828 Merge branch 'main' into fix-duplicate-extraction 2026-03-10 16:22:10 -07:00
Saurav Panda ce25884751 fix: prevent duplicate items in multi-page extraction via already_collected parameter 2026-03-10 16:12:46 -07:00
Saurav Panda 53b0239677 recompute the url scheme after refresh 2026-03-10 15:56:21 -07:00
Saurav Panda 1d9049fcad fix: detect empty DOM after navigation and retry before reporting failur 2026-03-10 15:40:19 -07:00
Saurav Panda 95215d6211 Add save_as_pdf agent action for CDP-based page-to-PDF export 2026-02-24 18:35:34 -08:00
Saurav Panda 86b12491dc fixed remote urls in tests 2026-02-19 16:04:06 -08:00
Saurav Panda c18ee5412f add file atttachments to structured output. 2026-02-19 12:43:05 -08:00
Saurav Panda 7833fcd137 added cookie overlay fix 2026-02-17 11:47:23 -08:00
Laith Weinberger 04da1fd30c strip success from JSON schema so invisible to the LLM, avoiding confusion 2026-02-05 16:49:36 -05:00
Laith Weinberger 7455b3c1af deduplicate code; allow CDP events to propagate; error handling 2026-02-04 21:14:14 -05:00
Laith Weinberger d66181cdc6 notify agent if new tab opened 2026-02-04 21:02:13 -05:00
Saurav Panda d24dea0aa4 Merge branch 'main' into improve-input-field-handling 2026-02-03 18:22:19 -08:00
Saurav Panda 5d7ff041d3 improved concatenation heuristic 2026-02-03 18:02:58 -08:00
Laith Weinberger f9c36f11a4 lint 2026-02-03 17:59:24 -05:00
Laith Weinberger 799e714c2b mitigate injection; don't drop overbudget pages
- restricted read_long_content file access to only paths in available_file_paths or browser_session.download_files to mitigate injection
- made PDF page selection truncate pages that exceed char budget instead of dropping them entirely
- fixed truncation hint in file_system.py to reference read_long_context instead of search_page
2026-02-03 17:42:02 -05:00
Saurav Panda 749fa56d1a improve text field handling 2026-02-03 12:52:56 -08:00
Laith Weinberger 38fb5b12df Merge remote-tracking branch 'origin/main' into feat/smart-pdf-reading 2026-02-03 14:15:49 -05:00
Saurav Panda b88e440b75 Merge branch 'main' into markdown-chunking-for-extraction 2026-02-02 16:10:00 -08:00
Saurav Panda defe37dd28 Improve multiact for agent 2026-02-02 12:50:03 -08:00
Saurav Panda 7c05e73bbf improve markdown splitting based on header 2026-02-02 12:37:28 -08:00
Saurav Panda e66eac8a37 Improve Markdown Chunker 2026-02-02 00:05:09 -08:00
Saurav Panda beefe832af Merge branch 'main' into schema-enforced-extraction-v2 2026-02-01 20:33:32 -08:00
Saurav Panda db832bcb83 added extraction schema 2026-02-01 20:26:50 -08:00