fix(browser): accept url alias for open and navigate (#29260)

* fix(browser): expose url alias in tool schema

* fix(browser): accept url alias for open and navigate

* test(browser): cover url alias for open and navigate
This commit is contained in:
Vincent Koc
2026-02-27 17:25:59 -08:00
committed by GitHub
parent e16d051d9f
commit ed51796d97
3 changed files with 55 additions and 6 deletions

View File

@@ -86,6 +86,7 @@ export const BrowserToolSchema = Type.Object({
node: Type.Optional(Type.String()),
profile: Type.Optional(Type.String()),
targetUrl: Type.Optional(Type.String()),
url: Type.Optional(Type.String()),
targetId: Type.Optional(Type.String()),
limit: Type.Optional(Type.Number()),
maxChars: Type.Optional(Type.Number()),

View File

@@ -262,6 +262,51 @@ describe("browser tool snapshot maxChars", () => {
});
});
describe("browser tool url alias support", () => {
afterEach(() => {
vi.clearAllMocks();
configMocks.loadConfig.mockReturnValue({ browser: {} });
nodesUtilsMocks.listNodes.mockResolvedValue([]);
});
it("accepts url alias for open", async () => {
const tool = createBrowserTool();
await tool.execute?.("call-1", { action: "open", url: "https://example.com" });
expect(browserClientMocks.browserOpenTab).toHaveBeenCalledWith(
undefined,
"https://example.com",
expect.objectContaining({ profile: undefined }),
);
});
it("accepts url alias for navigate", async () => {
const tool = createBrowserTool();
await tool.execute?.("call-1", {
action: "navigate",
url: "https://example.com",
targetId: "tab-1",
});
expect(browserActionsMocks.browserNavigate).toHaveBeenCalledWith(
undefined,
expect.objectContaining({
url: "https://example.com",
targetId: "tab-1",
profile: undefined,
}),
);
});
it("keeps targetUrl required error label when both params are missing", async () => {
const tool = createBrowserTool();
await expect(tool.execute?.("call-1", { action: "open" })).rejects.toThrow(
"targetUrl required",
);
});
});
describe("browser tool snapshot labels", () => {
afterEach(() => {
vi.clearAllMocks();

View File

@@ -84,6 +84,13 @@ function readOptionalTargetAndTimeout(params: Record<string, unknown>) {
return { targetId, timeoutMs };
}
function readTargetUrlParam(params: Record<string, unknown>) {
return (
readStringParam(params, "targetUrl") ??
readStringParam(params, "url", { required: true, label: "targetUrl" })
);
}
type BrowserProxyFile = {
path: string;
base64: string;
@@ -405,9 +412,7 @@ export function createBrowserTool(opts?: {
return formatTabsToolResult(tabs);
}
case "open": {
const targetUrl = readStringParam(params, "targetUrl", {
required: true,
});
const targetUrl = readTargetUrlParam(params);
if (proxyRequest) {
const result = await proxyRequest({
method: "POST",
@@ -635,9 +640,7 @@ export function createBrowserTool(opts?: {
});
}
case "navigate": {
const targetUrl = readStringParam(params, "targetUrl", {
required: true,
});
const targetUrl = readTargetUrlParam(params);
const targetId = readStringParam(params, "targetId");
if (proxyRequest) {
const result = await proxyRequest({