mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-25 17:02:46 +00:00
fix(browser): reuse running loopback browser after probe miss
This commit is contained in:
@@ -17,6 +17,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Browser/Chrome MCP: wait for existing-session browser tabs to become usable after attach instead of treating the initial Chrome MCP handshake as ready, which reduces user-profile timeouts and repeated consent churn on macOS Chrome attach flows. Fixes #52930. Thanks @vincentkoc.
|
||||
- Gateway/probe: stop successful gateway handshakes from timing out as unreachable while post-connect detail RPCs are still loading, so slow devices report a reachable RPC failure instead of a false negative dead gateway. Fixes #52927. Thanks @vincentkoc.
|
||||
- Config/plugins: treat stale unknown `plugins.allow` ids as warnings instead of fatal config errors, so recovery commands like `plugins install`, `doctor --fix`, and `status` still run when a plugin is missing locally. Fixes #52992. Thanks @vincentkoc.
|
||||
- Browser/CDP: reuse an already-running loopback browser after a short initial reachability miss instead of immediately falling back to relaunch detection, which fixes second-run browser start/open regressions on slower headless Linux setups. Fixes #53004. Thanks @vincentkoc.
|
||||
- Plugins/message tool: make Discord `components` and Slack `blocks` optional again so pin/unpin/react flows stop failing schema validation and Slack media sends are no longer forced into an invalid blocks-plus-media payload. Fixes #52970 and #52962. Thanks @vincentkoc.
|
||||
- Plugins/Feishu: route `message(..., media=...)` sends through the Feishu outbound media path so file and image attachments actually send instead of being silently dropped. Fixes #52962. Thanks @vincentkoc.
|
||||
- ClawHub/skills: resolve the local ClawHub auth token for gateway skill browsing and switch browse-all requests to search so ClawControl stops falling into unauthenticated 429s and empty authenticated skill lists. Fixes #52949. Thanks @vincentkoc.
|
||||
|
||||
@@ -197,6 +197,17 @@ export function createProfileAvailability({
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Browser control service can restart while a loopback OpenClaw browser is still
|
||||
// alive. Give that pre-existing browser one longer probe window before falling
|
||||
// back to local executable resolution.
|
||||
if (!attachOnly && !remoteCdp && profile.cdpIsLoopback && !profileState.running) {
|
||||
if (
|
||||
(await isHttpReachable(PROFILE_ATTACH_RETRY_TIMEOUT_MS)) &&
|
||||
(await isReachable(PROFILE_ATTACH_RETRY_TIMEOUT_MS))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (attachOnly || remoteCdp) {
|
||||
throw new BrowserProfileUnavailableError(
|
||||
remoteCdp
|
||||
|
||||
@@ -110,4 +110,32 @@ describe("browser server-context ensureBrowserAvailable", () => {
|
||||
expect(launchOpenClawChrome).toHaveBeenCalledTimes(1);
|
||||
expect(stopOpenClawChrome).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("reuses a pre-existing loopback browser after an initial short probe miss", async () => {
|
||||
const { launchOpenClawChrome, stopOpenClawChrome, isChromeCdpReady, profile } =
|
||||
setupEnsureBrowserAvailableHarness();
|
||||
const isChromeReachable = vi.mocked(chromeModule.isChromeReachable);
|
||||
|
||||
isChromeReachable
|
||||
.mockResolvedValueOnce(false)
|
||||
.mockResolvedValueOnce(true);
|
||||
isChromeCdpReady.mockResolvedValueOnce(true);
|
||||
|
||||
await expect(profile.ensureBrowserAvailable()).resolves.toBeUndefined();
|
||||
|
||||
expect(isChromeReachable).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
"http://127.0.0.1:18800",
|
||||
undefined,
|
||||
{ allowPrivateNetwork: true },
|
||||
);
|
||||
expect(isChromeReachable).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
"http://127.0.0.1:18800",
|
||||
1000,
|
||||
{ allowPrivateNetwork: true },
|
||||
);
|
||||
expect(launchOpenClawChrome).not.toHaveBeenCalled();
|
||||
expect(stopOpenClawChrome).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user