mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-10 09:22:45 +00:00
fix(browser): close tracked tabs on session cleanup (#36666)
This commit is contained in:
@@ -129,6 +129,7 @@ export function createOpenClawTools(options?: {
|
||||
createBrowserTool({
|
||||
sandboxBridgeUrl: options?.sandboxBrowserBridgeUrl,
|
||||
allowHostControl: options?.allowHostBrowserControl,
|
||||
agentSessionKey: options?.agentSessionKey,
|
||||
}),
|
||||
createCanvasTool({ config: options?.config }),
|
||||
createNodesTool({
|
||||
|
||||
@@ -82,6 +82,12 @@ const configMocks = vi.hoisted(() => ({
|
||||
}));
|
||||
vi.mock("../../config/config.js", () => configMocks);
|
||||
|
||||
const sessionTabRegistryMocks = vi.hoisted(() => ({
|
||||
trackSessionBrowserTab: vi.fn(),
|
||||
untrackSessionBrowserTab: vi.fn(),
|
||||
}));
|
||||
vi.mock("../../browser/session-tab-registry.js", () => sessionTabRegistryMocks);
|
||||
|
||||
const toolCommonMocks = vi.hoisted(() => ({
|
||||
imageResultFromFile: vi.fn(),
|
||||
}));
|
||||
@@ -292,6 +298,23 @@ describe("browser tool url alias support", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("tracks opened tabs when session context is available", async () => {
|
||||
browserClientMocks.browserOpenTab.mockResolvedValueOnce({
|
||||
targetId: "tab-123",
|
||||
title: "Example",
|
||||
url: "https://example.com",
|
||||
});
|
||||
const tool = createBrowserTool({ agentSessionKey: "agent:main:main" });
|
||||
await tool.execute?.("call-1", { action: "open", url: "https://example.com" });
|
||||
|
||||
expect(sessionTabRegistryMocks.trackSessionBrowserTab).toHaveBeenCalledWith({
|
||||
sessionKey: "agent:main:main",
|
||||
targetId: "tab-123",
|
||||
baseUrl: undefined,
|
||||
profile: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
it("accepts url alias for navigate", async () => {
|
||||
const tool = createBrowserTool();
|
||||
await tool.execute?.("call-1", {
|
||||
@@ -317,6 +340,26 @@ describe("browser tool url alias support", () => {
|
||||
"targetUrl required",
|
||||
);
|
||||
});
|
||||
|
||||
it("untracks explicit tab close for tracked sessions", async () => {
|
||||
const tool = createBrowserTool({ agentSessionKey: "agent:main:main" });
|
||||
await tool.execute?.("call-1", {
|
||||
action: "close",
|
||||
targetId: "tab-xyz",
|
||||
});
|
||||
|
||||
expect(browserClientMocks.browserCloseTab).toHaveBeenCalledWith(
|
||||
undefined,
|
||||
"tab-xyz",
|
||||
expect.objectContaining({ profile: undefined }),
|
||||
);
|
||||
expect(sessionTabRegistryMocks.untrackSessionBrowserTab).toHaveBeenCalledWith({
|
||||
sessionKey: "agent:main:main",
|
||||
targetId: "tab-xyz",
|
||||
baseUrl: undefined,
|
||||
profile: undefined,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("browser tool act compatibility", () => {
|
||||
|
||||
@@ -19,6 +19,10 @@ import {
|
||||
import { resolveBrowserConfig } from "../../browser/config.js";
|
||||
import { DEFAULT_UPLOAD_DIR, resolveExistingPathsWithinRoot } from "../../browser/paths.js";
|
||||
import { applyBrowserProxyPaths, persistBrowserProxyFiles } from "../../browser/proxy-files.js";
|
||||
import {
|
||||
trackSessionBrowserTab,
|
||||
untrackSessionBrowserTab,
|
||||
} from "../../browser/session-tab-registry.js";
|
||||
import { loadConfig } from "../../config/config.js";
|
||||
import {
|
||||
executeActAction,
|
||||
@@ -275,6 +279,7 @@ function resolveBrowserBaseUrl(params: {
|
||||
export function createBrowserTool(opts?: {
|
||||
sandboxBridgeUrl?: string;
|
||||
allowHostControl?: boolean;
|
||||
agentSessionKey?: string;
|
||||
}): AnyAgentTool {
|
||||
const targetDefault = opts?.sandboxBridgeUrl ? "sandbox" : "host";
|
||||
const hostHint =
|
||||
@@ -418,7 +423,14 @@ export function createBrowserTool(opts?: {
|
||||
});
|
||||
return jsonResult(result);
|
||||
}
|
||||
return jsonResult(await browserOpenTab(baseUrl, targetUrl, { profile }));
|
||||
const opened = await browserOpenTab(baseUrl, targetUrl, { profile });
|
||||
trackSessionBrowserTab({
|
||||
sessionKey: opts?.agentSessionKey,
|
||||
targetId: opened.targetId,
|
||||
baseUrl,
|
||||
profile,
|
||||
});
|
||||
return jsonResult(opened);
|
||||
}
|
||||
case "focus": {
|
||||
const targetId = readStringParam(params, "targetId", {
|
||||
@@ -455,6 +467,12 @@ export function createBrowserTool(opts?: {
|
||||
}
|
||||
if (targetId) {
|
||||
await browserCloseTab(baseUrl, targetId, { profile });
|
||||
untrackSessionBrowserTab({
|
||||
sessionKey: opts?.agentSessionKey,
|
||||
targetId,
|
||||
baseUrl,
|
||||
profile,
|
||||
});
|
||||
} else {
|
||||
await browserAct(baseUrl, { kind: "close" }, { profile });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user