mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-18 14:27:27 +00:00
fix(browser): retry chrome act when target tab is stale
When a Chrome relay targetId becomes stale between snapshot and action, the browser tool now retries once without targetId so the relay falls back to the currently attached tab. Drop the unknown recovered field from the test mock return value to satisfy tsc strict checking against BrowserActResponse.
This commit is contained in:
committed by
Peter Steinberger
parent
910c654807
commit
732c4f3921
@@ -523,3 +523,43 @@ describe("browser tool external content wrapping", () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("browser tool act stale target recovery", () => {
|
||||
afterEach(() => {
|
||||
vi.clearAllMocks();
|
||||
configMocks.loadConfig.mockReturnValue({ browser: {} });
|
||||
nodesUtilsMocks.listNodes.mockResolvedValue([]);
|
||||
});
|
||||
|
||||
it("retries chrome act once without targetId when tab id is stale", async () => {
|
||||
browserActionsMocks.browserAct
|
||||
.mockRejectedValueOnce(new Error("404: tab not found"))
|
||||
.mockResolvedValueOnce({ ok: true });
|
||||
|
||||
const tool = createBrowserTool();
|
||||
const result = await tool.execute?.("call-1", {
|
||||
action: "act",
|
||||
profile: "chrome",
|
||||
request: {
|
||||
action: "click",
|
||||
targetId: "stale-tab",
|
||||
ref: "btn-1",
|
||||
},
|
||||
});
|
||||
|
||||
expect(browserActionsMocks.browserAct).toHaveBeenCalledTimes(2);
|
||||
expect(browserActionsMocks.browserAct).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
undefined,
|
||||
expect.objectContaining({ targetId: "stale-tab", action: "click", ref: "btn-1" }),
|
||||
expect.objectContaining({ profile: "chrome" }),
|
||||
);
|
||||
expect(browserActionsMocks.browserAct).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
undefined,
|
||||
expect.not.objectContaining({ targetId: expect.anything() }),
|
||||
expect.objectContaining({ profile: "chrome" }),
|
||||
);
|
||||
expect(result?.details).toMatchObject({ ok: true });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -862,6 +862,29 @@ export function createBrowserTool(opts?: {
|
||||
} catch (err) {
|
||||
const msg = String(err);
|
||||
if (msg.includes("404:") && msg.includes("tab not found") && profile === "chrome") {
|
||||
const targetId =
|
||||
typeof request.targetId === "string" ? request.targetId.trim() : undefined;
|
||||
// Some Chrome relay targetIds can go stale between snapshots and actions.
|
||||
// Retry once without targetId to let relay use the currently attached tab.
|
||||
if (targetId) {
|
||||
const retryRequest = { ...request };
|
||||
delete retryRequest.targetId;
|
||||
try {
|
||||
const retryResult = proxyRequest
|
||||
? await proxyRequest({
|
||||
method: "POST",
|
||||
path: "/act",
|
||||
profile,
|
||||
body: retryRequest,
|
||||
})
|
||||
: await browserAct(baseUrl, retryRequest as Parameters<typeof browserAct>[1], {
|
||||
profile,
|
||||
});
|
||||
return jsonResult(retryResult);
|
||||
} catch {
|
||||
// Fall through to explicit stale-target guidance.
|
||||
}
|
||||
}
|
||||
const tabs = proxyRequest
|
||||
? ((
|
||||
(await proxyRequest({
|
||||
|
||||
Reference in New Issue
Block a user