feat(domains): migrate handle_dialog
amankumarsingh77 amankumarsingh7702@gmal.com
Sat, 02 May 2026 16:16:24 +0530
3 files changed,
33 insertions(+),
42 deletions(-)
A
src/domains/dialog.ts
@@ -0,0 +1,31 @@
+import { Type } from "typebox"; +import { type Result, err, ok } from "../util/result"; +import { defineBrowserTool, type ToolErr, type ToolOk } from "../util/tool"; + +const HandleDialogArgs = Type.Object({ + accept: Type.Boolean({ description: "true = accept, false = dismiss" }), + promptText: Type.Optional(Type.String({ description: "Text to type if dialog is a prompt()" })), +}); + +export const handleDialogTool = defineBrowserTool({ + name: "browser_handle_dialog", + label: "Browser Handle Dialog", + description: + "Accept or dismiss the currently open JS dialog (alert/confirm/prompt/beforeunload).", + promptSnippet: "Accept or dismiss a JS dialog", + promptGuidelines: [ + "Use after browser_page_info reports a dialog is open. Until handled, no other browser action will work.", + "For prompt() dialogs, supply promptText with the value to submit.", + ], + parameters: HandleDialogArgs, + async handler(args, { client }): Promise<Result<ToolOk, ToolErr>> { + const params: Record<string, unknown> = { accept: args.accept }; + if (args.promptText !== undefined) params["promptText"] = args.promptText; + const r = await client.session().call("Page.handleJavaScriptDialog", params); + if (!r.success) return err({ kind: "cdp_error", message: r.error.message }); + return ok({ + text: `Dialog ${args.accept ? "accepted" : "dismissed"}`, + details: { accept: args.accept }, + }); + }, +});
M
src/registry.ts
→
src/registry.ts
@@ -5,6 +5,7 @@ import { clickTool } from "./domains/click";
import { typeTool, pressKeyTool, dispatchKeyTool } from "./domains/keyboard"; import { pageInfoTool, waitTool, waitForLoadTool } from "./domains/page"; import { scrollTool } from "./domains/scroll"; +import { handleDialogTool } from "./domains/dialog"; const TOOLS: ReadonlyArray<AnyBrowserToolDefinition> = [ clickTool,@@ -15,6 +16,7 @@ scrollTool,
pageInfoTool, waitTool, waitForLoadTool, + handleDialogTool, ]; export const registerAllTools = (pi: ExtensionAPI, client: BrowserClient): void => {
M
src/tools.ts
→
src/tools.ts
@@ -720,48 +720,6 @@ },
}); // ═══════════════════════════════════════════════════════════════════════════ - // browser_handle_dialog - // ═══════════════════════════════════════════════════════════════════════════ - pi.registerTool({ - name: "browser_handle_dialog", - label: "Browser Handle Dialog", - description: - "Handle a JavaScript dialog (alert, confirm, prompt, beforeunload). Use when browser_page_info reports an open dialog.", - promptSnippet: "Accept or dismiss a JavaScript dialog (alert/confirm/prompt)", - promptGuidelines: [ - "Check browser_page_info first — if it returns a dialog, use browser_handle_dialog before any other browser actions.", - "JS dialogs freeze the page's JS thread, so no other interaction works until the dialog is handled.", - 'Use action: "accept" for alerts and confirms, "dismiss" to cancel. For prompts, provide promptText.', - ], - parameters: Type.Object({ - action: Type.String({ description: '"accept" or "dismiss"' }), - promptText: Type.Optional(Type.String({ description: 'Text to enter for prompt dialogs (only used with "accept")' })), - }), - async execute(_id, params) { - try { - await daemon.ensureAlive(); - - if (params.action === "accept") { - await daemon.cdp("Page.handleJavaScriptDialog", { - accept: true, - ...(params.promptText !== undefined ? { promptText: params.promptText } : {}), - }); - } else { - await daemon.cdp("Page.handleJavaScriptDialog", { accept: false }); - } - - return { content: [{ type: "text" as const, text: `Dialog ${params.action}ed.` }], details: undefined }; - } catch (err) { - return { - isError: true, - content: [{ type: "text" as const, text: `Dialog handling failed: ${err instanceof Error ? err.message : String(err)}` }], - details: undefined, - }; - } - }, - }); - - // ═══════════════════════════════════════════════════════════════════════════ // browser_download // ═══════════════════════════════════════════════════════════════════════════ pi.registerTool({