feat: add Browser Use cloud browser as available provider (#138)

* feat: add Browser Use cloud browser
  integration

* feat: enhance Browser Use integration with provider flag support

- Updated README to reflect new usage instructions for enabling Browser Use with the `-p` flag.
- Modified CLI to parse and handle the `-p` flag for specifying the provider.
- Implemented logic in the main application to launch with the specified cloud provider.
- Adjusted BrowserManager to connect to Browser Use based on the provider flag or environment variable.
- Updated types and protocol schemas to include provider information.

* feat: add validation for mutually exclusive CLI options

- Implemented checks to prevent the use of both --cdp and --provider flags simultaneously.
- Added validation to ensure --extension cannot be used with the --provider flag.
- Enhanced error handling to provide clear feedback in both JSON and console output formats.
This commit is contained in:
Aitor
2026-01-21 18:01:19 -06:00
committed by GitHub
parent 7123d46e7f
commit c4139fa389
6 changed files with 194 additions and 7 deletions
+9 -1
View File
@@ -11,6 +11,7 @@ pub struct Flags {
pub cdp: Option<String>,
pub extensions: Vec<String>,
pub proxy: Option<String>,
pub provider: Option<String>,
}
pub fn parse_flags(args: &[String]) -> Flags {
@@ -30,6 +31,7 @@ pub fn parse_flags(args: &[String]) -> Flags {
cdp: None,
extensions: extensions_env,
proxy: None,
provider: env::var("AGENT_BROWSER_PROVIDER").ok(),
};
let mut i = 0;
@@ -75,6 +77,12 @@ pub fn parse_flags(args: &[String]) -> Flags {
i += 1;
}
}
"-p" | "--provider" => {
if let Some(p) = args.get(i + 1) {
flags.provider = Some(p.clone());
i += 1;
}
}
_ => {}
}
i += 1;
@@ -89,7 +97,7 @@ pub fn clean_args(args: &[String]) -> Vec<String> {
// Global flags that should be stripped from command args
const GLOBAL_FLAGS: &[&str] = &["--json", "--full", "--headed", "--debug"];
// Global flags that take a value (need to skip the next arg too)
const GLOBAL_FLAGS_WITH_VALUE: &[&str] = &["--session", "--headers", "--executable-path", "--cdp", "--extension", "--proxy"];
const GLOBAL_FLAGS_WITH_VALUE: &[&str] = &["--session", "--headers", "--executable-path", "--cdp", "--extension", "--proxy", "-p", "--provider"];
for arg in args.iter() {
if skip_next {
+47 -2
View File
@@ -216,6 +216,27 @@ fn main() {
}
}
// Validate mutually exclusive options
if flags.cdp.is_some() && flags.provider.is_some() {
let msg = "Cannot use --cdp and -p/--provider together";
if flags.json {
println!(r#"{{"success":false,"error":"{}"}}"#, msg);
} else {
eprintln!("\x1b[31m✗\x1b[0m {}", msg);
}
exit(1);
}
if flags.provider.is_some() && !flags.extensions.is_empty() {
let msg = "Cannot use --extension with -p/--provider (extensions require local browser)";
if flags.json {
println!(r#"{{"success":false,"error":"{}"}}"#, msg);
} else {
eprintln!("\x1b[31m✗\x1b[0m {}", msg);
}
exit(1);
}
// Connect via CDP if --cdp flag is set
if let Some(ref port) = flags.cdp {
let cdp_port: u16 = match port.parse::<u32>() {
@@ -271,8 +292,32 @@ fn main() {
}
}
// Launch headed browser or proxy if flags are set (without CDP)
if (flags.headed || flags.proxy.is_some()) && flags.cdp.is_none() {
// Launch with cloud provider if -p flag is set
if let Some(ref provider) = flags.provider {
let launch_cmd = json!({
"id": gen_id(),
"action": "launch",
"provider": provider
});
let err = match send_command(launch_cmd, &flags.session) {
Ok(resp) if resp.success => None,
Ok(resp) => Some(resp.error.unwrap_or_else(|| "Provider connection failed".to_string())),
Err(e) => Some(e.to_string()),
};
if let Some(msg) = err {
if flags.json {
println!(r#"{{"success":false,"error":"{}"}}"#, msg);
} else {
eprintln!("\x1b[31m✗\x1b[0m {}", msg);
}
exit(1);
}
}
// Launch headed browser or proxy if flags are set (without CDP or provider)
if (flags.headed || flags.proxy.is_some()) && flags.cdp.is_none() && flags.provider.is_none() {
let mut launch_cmd = json!({
"id": gen_id(),
"action": "launch",