diff --git a/extensions/browser/src/browser/client.test.ts b/extensions/browser/src/browser/client.test.ts index 67a3aaa0c39..88bfb2216f5 100644 --- a/extensions/browser/src/browser/client.test.ts +++ b/extensions/browser/src/browser/client.test.ts @@ -323,6 +323,12 @@ describe("browser client", () => { expect.stringMatching(/\/doctor\?profile=openclaw&deep=true$/), ]), ); + const status = calls.find((c) => c.url.endsWith("/")); + expect(status?.init?.timeoutMs).toBe(7_500); + const doctor = calls.find((c) => c.url.endsWith("/doctor")); + expect(doctor?.init?.timeoutMs).toBe(7_500); + const deepDoctor = calls.find((c) => c.url.endsWith("/doctor?profile=openclaw&deep=true")); + expect(deepDoctor?.init?.timeoutMs).toBe(10_000); const open = calls.find((c) => c.url.endsWith("/tabs/open")); expect(open?.init?.method).toBe("POST"); diff --git a/extensions/browser/src/browser/client.ts b/extensions/browser/src/browser/client.ts index c967d48066f..41fa6dd46ae 100644 --- a/extensions/browser/src/browser/client.ts +++ b/extensions/browser/src/browser/client.ts @@ -11,6 +11,10 @@ import type { BrowserDoctorReport } from "./doctor.js"; export type { BrowserStatus, BrowserTab, BrowserTransport } from "./client.types.js"; export type { BrowserDoctorCheck, BrowserDoctorReport } from "./doctor.js"; +const BROWSER_STATUS_REQUEST_TIMEOUT_MS = 7_500; +const BROWSER_DOCTOR_REQUEST_TIMEOUT_MS = 7_500; +const BROWSER_DEEP_DOCTOR_REQUEST_TIMEOUT_MS = 10_000; + export type ProfileStatus = { name: string; transport?: BrowserTransport; @@ -71,7 +75,7 @@ export async function browserStatus( timeoutMs: typeof opts?.timeoutMs === "number" && Number.isFinite(opts.timeoutMs) ? Math.max(1, Math.floor(opts.timeoutMs)) - : 1500, + : BROWSER_STATUS_REQUEST_TIMEOUT_MS, }); } @@ -88,7 +92,9 @@ export async function browserDoctor( } const q = params.size ? `?${params.toString()}` : ""; return await fetchBrowserJson(withBaseUrl(baseUrl, `/doctor${q}`), { - timeoutMs: opts?.deep ? 10000 : 3000, + timeoutMs: opts?.deep + ? BROWSER_DEEP_DOCTOR_REQUEST_TIMEOUT_MS + : BROWSER_DOCTOR_REQUEST_TIMEOUT_MS, }); } diff --git a/extensions/browser/src/browser/routes/basic.existing-session.test.ts b/extensions/browser/src/browser/routes/basic.existing-session.test.ts index 7276696bcb8..a955e4683a2 100644 --- a/extensions/browser/src/browser/routes/basic.existing-session.test.ts +++ b/extensions/browser/src/browser/routes/basic.existing-session.test.ts @@ -302,6 +302,7 @@ describe("basic browser routes", () => { expect(response.statusCode).toBe(200); expect(isTransportAvailable).toHaveBeenCalledTimes(1); + expect(isTransportAvailable).toHaveBeenCalledWith(5_000); expect(isHttpReachable).not.toHaveBeenCalled(); expect(response.body).toMatchObject({ cdpHttp: true, diff --git a/extensions/browser/src/browser/routes/basic.ts b/extensions/browser/src/browser/routes/basic.ts index b084b150982..971329c45c7 100644 --- a/extensions/browser/src/browser/routes/basic.ts +++ b/extensions/browser/src/browser/routes/basic.ts @@ -17,6 +17,10 @@ import { toStringOrEmpty, } from "./utils.js"; +const STATUS_CDP_HTTP_TIMEOUT_MS = 300; +const STATUS_CDP_TRANSPORT_TIMEOUT_MS = 600; +const STATUS_CHROME_MCP_TRANSPORT_TIMEOUT_MS = 5_000; + function handleBrowserRouteError(res: BrowserResponse, err: unknown) { const mapped = toBrowserErrorResponse(err); if (mapped) { @@ -72,10 +76,13 @@ async function buildBrowserStatus(req: BrowserRequest, ctx: BrowserRouteContext) const capabilities = getBrowserProfileCapabilities(profileCtx.profile); const [cdpHttp, cdpReady] = capabilities.usesChromeMcp ? await (async () => { - const ready = await profileCtx.isTransportAvailable(600); + const ready = await profileCtx.isTransportAvailable(STATUS_CHROME_MCP_TRANSPORT_TIMEOUT_MS); return [ready, ready] as const; })() - : await Promise.all([profileCtx.isHttpReachable(300), profileCtx.isTransportAvailable(600)]); + : await Promise.all([ + profileCtx.isHttpReachable(STATUS_CDP_HTTP_TIMEOUT_MS), + profileCtx.isTransportAvailable(STATUS_CDP_TRANSPORT_TIMEOUT_MS), + ]); const profileState = current.profiles.get(profileCtx.profile.name); let detectedBrowser: string | null = null;