The 400 status chosen for truncation errors (deliberately outside provider
retry lists — an identical retry truncates identically) also fell outside
Agent._try_switch_to_fallback_llm's allowlist, so a configured fallback_llm
could no longer rescue a truncated run. Before this PR the downstream parse
failure was wrapped as a 502 ModelProviderError, which did allow the switch.
Introduce ModelOutputTruncatedError(ModelProviderError, status 400): the
three providers raise it, provider retry loops still skip it, and the
agent's fallback check treats it as switchable explicitly — a fallback with
a different output cap can succeed where the primary truncated.
ChatBrowserUse now accepts provider-prefixed model ids (anthropic/*,
openai/*, google/*) alongside the bu-* aliases and browser-use/* models,
so a single BROWSER_USE_API_KEY can reach them. bu-* aliases and the
bu-latest -> bu-2-0 normalization are unchanged; bare ids are rejected
with guidance toward the provider/model form.
Also matches provider-prefixed Claude Sonnet ids in the Agent
llm_screenshot_size auto-config, so the screenshot optimization isn't
lost when Claude is reached via ChatBrowserUse.
Adds an example, a README FAQ entry, and tests.
ENG-5060
- 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
- Re-indent the except block to match the inner try (was a SyntaxError)
- Drop asyncio.CancelledError from the isinstance check (it's BaseException,
never reaches except Exception)
- Re-raise on _is_connection_like_error so _handle_step_error can run its
reconnect / browser-closed shutdown logic
- Include exception class name in the preserved ActionResult error
PHclaw pointed out that _check_stop_or_pause() raises InterruptedError
inside the multi_act loop. Converting it to an ActionResult would prevent
the agent from properly stopping/pausing between batched actions.
Re-raise InterruptedError and asyncio.CancelledError before wrapping
other exceptions as ActionResult with partial results.
When multi_act() executes a batch of actions and one fails mid-way,
the partial results from successfully executed earlier actions were
discarded by re-raising the exception. The agent lost visibility into
which actions completed before the failure.
Return the accumulated results with an error ActionResult appended,
which aligns with the existing post_process logic that explicitly
handles multi-action errors via loop detection and replan nudges
(lines 1221-1222).
The main execution loop already wraps _execute_step with asyncio.wait_for
using settings.step_timeout (default 180s). But _execute_initial_actions,
which runs before the main loop, is unwrapped — if it hangs (e.g. the
first navigate stalls on a silent CDP WebSocket before the per-action
timeout can catch it), the agent blocks indefinitely without ever
entering the main loop. No step gets recorded, history stays empty, and
any outer watchdog eventually kills the run with zero diagnostic data.
Wrap _execute_initial_actions with the same step_timeout. On timeout,
record the failure in state.last_result / consecutive_failures and fall
through to the main execution loop so the agent can still attempt to
recover. InterruptedError (from an interrupting callback) is still
swallowed silently — same contract as before.
Paired with the per-action asyncio.wait_for added in tools/service.py,
this closes the last unprotected path in the pre-main-loop flow.
- Add UTM params to all cloud-bound links across README, CLI, and error messages
- Rewrite README Open Source vs Cloud section: position cloud browsers as
recommended pairing for OSS users, remove separate Use Both section
- Rewrite error messages for use_cloud=True and ChatBrowserUse() to clearly
state what is wrong and what to do next
- Add missing URLs: invalid API key now links to key page, insufficient
credits now links to billing page
- Add cloud browser nudge on captcha detection (logger.warning)
- Add cloud browser nudge on local browser launch failure
_prepare_context passes last_model_output/last_result to the message
manager for the "previous action result" prompt section. Clearing
them before context preparation drops this context.
Move the clear to after _prepare_context but before _get_next_action,
so prompt assembly still sees the previous step's output while
preventing stale data on timeout during the LLM call or action phase.
Two related bugs when step() is cancelled by timeout:
1. step() does not clear last_model_output/last_result at the start,
so if timeout occurs before _get_next_action, _finalize() sees
stale values from the previous step and records a duplicate history
entry with wrong step numbers.
2. _finalize() early-returns when last_result is falsy, skipping the
n_steps increment. On timeout, this means the while loop retries
the same step number repeatedly.
Fix: clear last_model_output and last_result at step() entry, and
ensure _execute_step increments n_steps after a timeout if _finalize
did not already do so.
Add disabled parameter to SignalHandler class to allow opting out of
signal handling. This enables browser-use to be embedded in applications
like uvicorn/FastAPI that need to manage their own signal lifecycle.
Add enable_signal_handler parameter to Agent class (default True for
backward compatibility). When set to False, the Agent will not register
signal handlers, allowing the host application to control graceful
shutdown and signal handling.
Fixes#4385
The circuit breaker and agent error handler were using a hardcoded 20s
timeout, but the worst-case auto-reconnect window is ~48s (3 attempts *
15s + 7s delays). Handlers would raise ConnectionError while reconnection
was still in progress. Now both use BrowserSession.RECONNECT_WAIT_TIMEOUT
(54s) derived from the actual reconnect parameters.
Move action_name extraction before the try block so it's always
defined when the except block references it. Previously, if
_check_stop_or_pause() raised InterruptedError before action_name
was assigned, the exception handler would fail with:
UnboundLocalError: cannot access local variable 'action_name'
where it is not associated with a value
Also reuse the action_data dict for the 'done' action check since
it's now available earlier in the loop.
Co-authored-by: Magnus Müller <MagMueller@users.noreply.github.com>
- Add max_clickable_elements_length parameter to Agent.__init__ with default 40000
- Add max_clickable_elements_length to AgentSettings
- Pass parameter through MessageManager to AgentMessagePrompt
- Bump version to 0.11.10a2
Co-authored-by: Magnus Müller <MagMueller@users.noreply.github.com>