Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions crates/browser-use-agent/src/entrypoint/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1111,8 +1111,9 @@ fn resolve_provider_with_python(
/// The registry registers the backend-free handlers — `shell`, `apply_patch`,
/// `view_image`, `update_plan`, `done`, `tool_search` (catalog populated from the registered tools' defs),
/// `web_search` (ENABLED; the Responses builder encodes it as the hosted
/// `web_search_preview` tool) — plus the two product-surface tools that drive
/// real subsystems:
/// `web_search_preview` tool), `search` (a locally-executed DuckDuckGo search,
/// distinct from the hosted `web_search`) — plus the two product-surface tools
/// that drive real subsystems:
/// * `browser` ([`BrowserTool::new`]): standalone — the production
/// [`RealBackend`](crate::tools::handlers::browser::RealBackend) wraps the
/// `browser-use-browser` crate and manages CDP sessions internally (keyed by
Expand Down Expand Up @@ -1208,6 +1209,7 @@ fn build_tool_dispatcher_with_cwd_and_goal_store(
use crate::tools::handlers::done::{DoneRequest, DoneTool};
use crate::tools::handlers::mcp::McpToolCallRequest;
use crate::tools::handlers::python::{PythonRequest, PythonTool};
use crate::tools::handlers::search::{SearchRequest, SearchTool};
use crate::tools::handlers::shell::{
ExecCommandRequest, ExecCommandTool, ShellRequest, ShellTool, WriteStdinRequest,
WriteStdinTool,
Expand Down Expand Up @@ -1292,6 +1294,10 @@ fn build_tool_dispatcher_with_cwd_and_goal_store(
true,
WebSearchTool::new(WebSearchConfig::enabled()),
);
// `search`: locally-executed DuckDuckGo (Lite) web search — the client runs
// the HTTP request and parses the results itself (distinct from the hosted
// `web_search` above). Read-only, so parallel_safe = true.
reg.register::<_, SearchRequest>("search", definitions::search(), true, SearchTool::new());
let browser_backend = browser_backend_for_runtime_or_config(
config,
runtime_handle.as_ref(),
Expand Down Expand Up @@ -3188,6 +3194,13 @@ mod tests {
assert!(names.contains(&"browser"));
assert!(names.contains(&"done"));
assert!(names.contains(&"update_plan"));
// Both web searches are wired into the production dispatcher: the hosted
// `web_search` and the locally-executed DuckDuckGo `search`.
assert!(names.contains(&"web_search"));
assert!(
names.contains(&"search"),
"the locally-executed `search` tool must be reachable by the live model"
);
}

/// A non-empty `mcp_servers` map registers the `mcp` tool. The stdio server
Expand Down
8 changes: 8 additions & 0 deletions crates/browser-use-agent/src/tools/handlers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub mod done;
pub mod goal;
pub mod mcp;
pub mod python;
pub mod search;
pub mod shell;
pub mod subagent;
pub mod tool_search;
Expand All @@ -31,6 +32,8 @@ mod mcp_tests;
#[cfg(test)]
mod python_tests;
#[cfg(test)]
mod search_tests;
#[cfg(test)]
mod shell_tests;
#[cfg(test)]
mod tool_search_tests;
Expand All @@ -52,6 +55,11 @@ pub use mcp::{
MCP_ERROR_EXIT_CODE, MCP_EVENT_RESULT_MAX_CHARS,
};
pub use python::{PythonApprovalKey, PythonBackend, PythonRequest, PythonTool};
pub use search::{
classify_response, extract_real_url, format_results, normalize_whitespace, parse_lite_results,
HttpSearchBackend, SearchApprovalKey, SearchBackend, SearchError, SearchRequest, SearchResult,
SearchTool,
};
pub use shell::{
ExecCommandApprovalKey, ExecCommandRequest, ExecCommandTool, ShellApprovalKey, ShellRequest,
ShellTool, WriteStdinApprovalKey, WriteStdinRequest, WriteStdinTool,
Expand Down
Loading