import { createLogger } from "../../../../utils/logger/index.js";
import { init_logger } from "../../../../utils/logger.js";
import { createBrowserActionRegistry } from "../../../../browser/actions/registry.js";
import { loadBrowserPipelineSource } from "../../../../browser/pipeline/source.js";
import { BrowserUseSchema } from "./schemas.js";
//#region src/agent/tools/browser/tool/browser-use-tool.ts
init_logger();
const log = createLogger("browser_use");
function createBrowserUseTool(deps) {
	const registry = createBrowserActionRegistry();
	function buildContext(page, signal) {
		return {
			page,
			manager: deps.getManager(),
			config: deps.getConfig(),
			taskId: deps.getTaskId(),
			supervisor: deps.getSupervisor?.(),
			signal
		};
	}
	/**
	* Render a {@link BrowserSetupHint} as a tool result. The text body is a
	* JSON envelope (`kind: 'browser_setup_required'`) so the chat surface can
	* detect it and render a Setup card; the embedded `message` keeps the
	* payload human-readable for the LLM so it stops the browser attempt and
	* tells the user to finish setup.
	*/
	function formatNotReady(hint) {
		const message = `⚠ Browser is not ready (backend=${hint.backend}, reason=${hint.reason}). Do NOT retry. Tell the user to open Settings → Browser to finish setup, then ask them to confirm before running any browser action again.`;
		const payload = {
			kind: "browser_setup_required",
			backend: hint.backend,
			reason: hint.reason,
			deepLink: hint.deepLink,
			detail: hint.detail,
			message
		};
		return {
			content: [{
				type: "text",
				text: JSON.stringify(payload)
			}],
			details: {
				ok: false,
				kind: "browser_setup_required",
				backend: hint.backend,
				reason: hint.reason,
				deepLink: hint.deepLink
			}
		};
	}
	function formatResult(result) {
		if (result.ok) {
			const parts = [];
			if (result.text) parts.push(result.text);
			if (result.data && !result.text) parts.push(JSON.stringify(result.data, null, 2));
			return {
				content: [{
					type: "text",
					text: parts.join("\n") || "OK"
				}],
				details: {
					ok: true,
					action: result.action,
					...result.artifacts?.length ? { artifacts: result.artifacts.length } : {}
				}
			};
		}
		const parts = [];
		if (result.error) parts.push(`[${result.error.code}] ${result.error.message}`);
		if (result.diagnostics?.url) parts.push(`URL: ${result.diagnostics.url}`);
		if (result.diagnostics?.snapshot) parts.push(`Snapshot: ${result.diagnostics.snapshot.slice(0, 2e3)}`);
		return {
			content: [{
				type: "text",
				text: parts.join("\n") || "Failed"
			}],
			details: {
				ok: false,
				action: result.action,
				error: result.error
			}
		};
	}
	return {
		name: "browser_use",
		label: "🌐 Browser",
		description: "Use a persistent browser for web navigation, page inspection, interaction, screenshots, network capture, and scripted browser pipelines. For non-trivial browser tasks, load the \"browser\" skill first with skill_view.",
		parameters: BrowserUseSchema,
		async execute(_toolCallId, params, signal, _onUpdate) {
			const { mode, command, args: cmdArgs, pipeline: pipelineParams, options: _options } = params;
			if (deps.getReadiness) try {
				const notReady = await deps.getReadiness();
				if (notReady) return formatNotReady(notReady.hint);
			} catch (e) {
				log.warn({ err: e }, "Readiness preflight threw; continuing with launch attempt");
			}
			if (mode === "inspect") {
				const mgr = deps.getManager();
				await mgr.ensureConnected();
				const ext = mgr.getExtensionProvider();
				if (ext) {
					const timeout = deps.getConfig?.()?.agents?.defaults?.browser?.commandTimeout;
					const timeoutMs = typeof timeout === "number" && Number.isFinite(timeout) && timeout > 0 ? Math.floor(timeout * 1e3) : 3e4;
					const urlRes = await ext.sendCommand("get_url", {}, { timeout: timeoutMs });
					const titleRes = await ext.sendCommand("get_title", {}, { timeout: timeoutMs });
					const snapRes = await ext.sendCommand("snapshot", {}, { timeout: timeoutMs });
					const url = urlRes.ok && urlRes.data ? String(urlRes.data.url ?? "") : "";
					const title = titleRes.ok && titleRes.data ? String(titleRes.data.title ?? "") : "";
					let snapText = "";
					if (snapRes.ok && snapRes.data) {
						snapText = (snapRes.data.nodes ?? []).map((n) => `${n.role ?? "?"}: ${n.name ?? ""}`).join("\n");
						if (snapText.length > 8e3) snapText = `${snapText.slice(0, 8e3)}\n... (truncated)`;
					}
					return {
						content: [{
							type: "text",
							text: `URL: ${url}\nTitle: ${title}\n${snapText ? `--- Page Snapshot ---\n${snapText}` : ""}`
						}],
						details: {
							ok: true,
							mode: "inspect",
							url,
							title
						}
					};
				}
				const page = await deps.getPageForTask();
				const ctx = buildContext(page, signal);
				const result = await registry.execute("state", ctx, {});
				const url = page.url();
				const title = await page.title().catch(() => "");
				return {
					content: [{
						type: "text",
						text: `URL: ${url}\nTitle: ${title}\n${result.text ?? ""}`
					}],
					details: {
						ok: true,
						mode: "inspect",
						url,
						title
					}
				};
			}
			if (mode === "close") {
				const taskId = deps.getTaskId();
				await deps.getManager().ensureConnected();
				await deps.getManager().closePage(taskId);
				deps.notifyBrowserPageClosed?.(taskId);
				return {
					content: [{
						type: "text",
						text: "Browser page closed."
					}],
					details: {
						ok: true,
						mode: "close"
					}
				};
			}
			if (mode === "command") {
				if (!command) return {
					content: [{
						type: "text",
						text: "Missing `command` parameter for command mode."
					}],
					details: {
						ok: false,
						mode: "command"
					}
				};
				const ctx = buildContext(await deps.getPageForTask(), signal);
				const args = cmdArgs ?? {};
				return formatResult(await registry.execute(command, ctx, args));
			}
			if (mode === "pipeline") {
				if (!pipelineParams) return {
					content: [{
						type: "text",
						text: "Missing `pipeline` parameter for pipeline mode."
					}],
					details: {
						ok: false,
						mode: "pipeline"
					}
				};
				let yamlSource = pipelineParams.yaml ?? pipelineParams.script ?? "";
				if (!yamlSource && pipelineParams.path) try {
					yamlSource = (await loadBrowserPipelineSource(pipelineParams.path)).source;
				} catch (e) {
					const msg = e instanceof Error ? e.message : String(e);
					return {
						content: [{
							type: "text",
							text: `Failed to read pipeline source: ${msg}`
						}],
						details: {
							ok: false,
							mode: "pipeline",
							error: msg
						}
					};
				}
				if (!yamlSource) return {
					content: [{
						type: "text",
						text: "Pipeline mode requires `yaml`, `script`, or `path`."
					}],
					details: {
						ok: false,
						mode: "pipeline"
					}
				};
				const pipelineArgs = pipelineParams.args ?? {};
				const dryRun = pipelineParams.dryRun === true;
				const ctx = buildContext(await deps.getPageForTask(), signal);
				if (deps.runPipeline) return formatResult(await deps.runPipeline(yamlSource, pipelineArgs, ctx, dryRun));
				try {
					const { runBrowserPipeline } = await import("../../../../browser/pipeline/runner.js");
					return formatResult(await runBrowserPipeline(yamlSource, pipelineArgs, ctx, registry, dryRun));
				} catch (e) {
					const msg = e instanceof Error ? e.message : String(e);
					log.error({ err: e }, `Pipeline execution failed: ${msg}`);
					return {
						content: [{
							type: "text",
							text: `Pipeline failed: ${msg}`
						}],
						details: {
							ok: false,
							mode: "pipeline",
							error: msg
						}
					};
				}
			}
			return {
				content: [{
					type: "text",
					text: `Unknown mode: ${mode}`
				}],
				details: { ok: false }
			};
		}
	};
}
//#endregion
export { createBrowserUseTool };

//# sourceMappingURL=browser-use-tool.js.map