Release binaries / Build macOS ARM64 (push) Has been cancelled
Release binaries / Build macOS x64 (push) Has been cancelled
Release binaries / Build Linux ARM64 (push) Has been cancelled
Release binaries / Build Linux musl ARM64 (push) Has been cancelled
Release binaries / Build Linux musl x64 (push) Has been cancelled
Release binaries / Build Linux x64 (push) Has been cancelled
Release binaries / Build Windows x64 (push) Has been cancelled
Release binaries / Attach binaries to GitHub Release (push) Has been cancelled
Standalone product rename across the whole repo (issue: project identity): - Binary/package/repo/skill/docs: agent-browser[-stealth] → chrome-use (single binary name `chrome-use`; old aliases agent-browser/abs dropped). - Version: 0.27.0-fork.51 → 1.0.0 (drop the upstream-fork counter). - Native-messaging host: com.agent_browser.connect → com.leeguoo.chrome_use (CLI + ab-connect extension in lockstep — this is a breaking handshake change, extension bumped 0.4.2 → 0.5.0, needs a Web Store republish). - Config dir: ~/.agent-browser → ~/.chrome-use. - README/zh: reframed from "stealth fork of agent-browser" to a standalone product with a small `originally based on vercel-labs/agent-browser` credit. - Kept AGENT_BROWSER_* env vars working (63 vars across the codebase; renaming them would break every existing script/skill for no user-facing gain). Build green, 802 unit tests pass, fmt + clippy clean. Upstream attribution to vercel-labs/agent-browser preserved.
155 lines
4.5 KiB
Rust
155 lines
4.5 KiB
Rust
//! Probe reachability of the Chrome for Testing CDN, AI Gateway (if
|
|
//! configured), and the currently-selected provider endpoint. Each probe
|
|
//! has a 3-second timeout.
|
|
|
|
use std::env;
|
|
use std::time::{Duration, Instant};
|
|
|
|
use super::{Check, Status};
|
|
|
|
pub(super) fn check(checks: &mut Vec<Check>) {
|
|
let category = "Network";
|
|
|
|
let rt = match tokio::runtime::Builder::new_current_thread()
|
|
.enable_all()
|
|
.build()
|
|
{
|
|
Ok(r) => r,
|
|
Err(e) => {
|
|
checks.push(Check::new(
|
|
"net.runtime",
|
|
category,
|
|
Status::Fail,
|
|
format!("Could not start tokio runtime for probes: {}", e),
|
|
));
|
|
return;
|
|
}
|
|
};
|
|
|
|
let client = match reqwest::Client::builder()
|
|
.user_agent(format!("chrome-use/{}", env!("CARGO_PKG_VERSION")))
|
|
.timeout(Duration::from_secs(3))
|
|
.connect_timeout(Duration::from_secs(3))
|
|
.build()
|
|
{
|
|
Ok(c) => c,
|
|
Err(e) => {
|
|
checks.push(Check::new(
|
|
"net.client",
|
|
category,
|
|
Status::Fail,
|
|
format!("Could not build HTTP client: {}", e),
|
|
));
|
|
return;
|
|
}
|
|
};
|
|
|
|
let chrome_url =
|
|
"https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json";
|
|
probe_url(
|
|
&rt,
|
|
&client,
|
|
checks,
|
|
category,
|
|
"net.chrome_cdn",
|
|
chrome_url,
|
|
"Chrome for Testing CDN",
|
|
);
|
|
|
|
if env::var("AI_GATEWAY_API_KEY").is_ok() {
|
|
let url = env::var("AI_GATEWAY_URL")
|
|
.unwrap_or_else(|_| "https://ai-gateway.vercel.sh".to_string());
|
|
probe_url(
|
|
&rt,
|
|
&client,
|
|
checks,
|
|
category,
|
|
"net.ai_gateway",
|
|
&url,
|
|
"AI Gateway",
|
|
);
|
|
}
|
|
|
|
if let Ok(provider) = env::var("AGENT_BROWSER_PROVIDER") {
|
|
let url: Option<String> = match provider.to_lowercase().as_str() {
|
|
"browserbase" => Some("https://api.browserbase.com".to_string()),
|
|
"browserless" => Some(
|
|
env::var("BROWSERLESS_API_URL")
|
|
.unwrap_or_else(|_| "https://production-sfo.browserless.io".to_string()),
|
|
),
|
|
"browseruse" | "browser-use" => Some("https://api.browser-use.com".to_string()),
|
|
"kernel" => Some(
|
|
env::var("KERNEL_ENDPOINT")
|
|
.unwrap_or_else(|_| "https://api.onkernel.com".to_string()),
|
|
),
|
|
_ => None,
|
|
};
|
|
if let Some(url) = url {
|
|
probe_url(
|
|
&rt,
|
|
&client,
|
|
checks,
|
|
category,
|
|
"net.provider",
|
|
&url,
|
|
&format!("Provider {}", provider),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn probe_url(
|
|
rt: &tokio::runtime::Runtime,
|
|
client: &reqwest::Client,
|
|
checks: &mut Vec<Check>,
|
|
category: &'static str,
|
|
id: &'static str,
|
|
url: &str,
|
|
label: &str,
|
|
) {
|
|
let started = Instant::now();
|
|
let result = rt.block_on(async { client.head(url).send().await });
|
|
let elapsed_ms = started.elapsed().as_millis();
|
|
match result {
|
|
Ok(resp) => {
|
|
let status = resp.status();
|
|
if status.is_success() || status.is_redirection() || status.as_u16() == 405 {
|
|
checks.push(Check::new(
|
|
id,
|
|
category,
|
|
Status::Pass,
|
|
format!(
|
|
"{} reachable ({}ms, HTTP {})",
|
|
label,
|
|
elapsed_ms,
|
|
status.as_u16()
|
|
),
|
|
));
|
|
} else {
|
|
checks.push(Check::new(
|
|
id,
|
|
category,
|
|
Status::Warn,
|
|
format!(
|
|
"{} returned HTTP {} after {}ms",
|
|
label,
|
|
status.as_u16(),
|
|
elapsed_ms
|
|
),
|
|
));
|
|
}
|
|
}
|
|
Err(e) => {
|
|
checks.push(
|
|
Check::new(
|
|
id,
|
|
category,
|
|
Status::Fail,
|
|
format!("{} unreachable after {}ms: {}", label, elapsed_ms, e),
|
|
)
|
|
.with_fix("check network connectivity / firewall / proxy settings"),
|
|
);
|
|
}
|
|
}
|
|
}
|