UNPKG

dina-agi

Version:

DINA AGI - Dynamic Intelligence Network Architecture. 128 Autonomous Agents with Claude Flow, Swarms, and 300+ MCPs. True AGI System.

503 lines (502 loc) 19.2 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var bidiPage_exports = {}; __export(bidiPage_exports, { BidiPage: () => BidiPage, kPlaywrightBindingChannel: () => kPlaywrightBindingChannel }); module.exports = __toCommonJS(bidiPage_exports); var import_utils = require("../../utils"); var import_eventsHelper = require("../utils/eventsHelper"); var dialog = __toESM(require("../dialog")); var dom = __toESM(require("../dom")); var import_page = require("../page"); var import_bidiExecutionContext = require("./bidiExecutionContext"); var import_bidiInput = require("./bidiInput"); var import_bidiNetworkManager = require("./bidiNetworkManager"); var import_bidiPdf = require("./bidiPdf"); var bidi = __toESM(require("./third_party/bidiProtocol")); const UTILITY_WORLD_NAME = "__playwright_utility_world__"; const kPlaywrightBindingChannel = "playwrightChannel"; class BidiPage { constructor(browserContext, bidiSession, opener) { this._sessionListeners = []; this._initScriptIds = /* @__PURE__ */ new Map(); this._session = bidiSession; this._opener = opener; this.rawKeyboard = new import_bidiInput.RawKeyboardImpl(bidiSession); this.rawMouse = new import_bidiInput.RawMouseImpl(bidiSession); this.rawTouchscreen = new import_bidiInput.RawTouchscreenImpl(bidiSession); this._realmToContext = /* @__PURE__ */ new Map(); this._page = new import_page.Page(this, browserContext); this._browserContext = browserContext; this._networkManager = new import_bidiNetworkManager.BidiNetworkManager(this._session, this._page, this._onNavigationResponseStarted.bind(this)); this._pdf = new import_bidiPdf.BidiPDF(this._session); this._page.on(import_page.Page.Events.FrameDetached, (frame) => this._removeContextsForFrame(frame, false)); this._sessionListeners = [ import_eventsHelper.eventsHelper.addEventListener(bidiSession, "script.realmCreated", this._onRealmCreated.bind(this)), import_eventsHelper.eventsHelper.addEventListener(bidiSession, "script.message", this._onScriptMessage.bind(this)), import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.contextDestroyed", this._onBrowsingContextDestroyed.bind(this)), import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.navigationStarted", this._onNavigationStarted.bind(this)), import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.navigationAborted", this._onNavigationAborted.bind(this)), import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.navigationFailed", this._onNavigationFailed.bind(this)), import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.fragmentNavigated", this._onFragmentNavigated.bind(this)), import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.domContentLoaded", this._onDomContentLoaded.bind(this)), import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.load", this._onLoad.bind(this)), import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.userPromptOpened", this._onUserPromptOpened.bind(this)), import_eventsHelper.eventsHelper.addEventListener(bidiSession, "log.entryAdded", this._onLogEntryAdded.bind(this)) ]; this._initialize().then( () => this._page.reportAsNew(this._opener?._page), (error) => this._page.reportAsNew(this._opener?._page, error) ); } async _initialize() { this._onFrameAttached(this._session.sessionId, null); await Promise.all([ this.updateHttpCredentials(), this.updateRequestInterception(), // If the page is created by the Playwright client's call, some initialization // may be pending. Wait for it to complete before reporting the page as new. // // TODO: ideally we'd wait only for the commands that created this page, but currently // there is no way in Bidi to track which command created this page. this._browserContext.waitForBlockingPageCreations() ]); } didClose() { this._session.dispose(); import_eventsHelper.eventsHelper.removeEventListeners(this._sessionListeners); this._page._didClose(); } _onFrameAttached(frameId, parentFrameId) { return this._page.frameManager.frameAttached(frameId, parentFrameId); } _removeContextsForFrame(frame, notifyFrame) { for (const [contextId, context] of this._realmToContext) { if (context.frame === frame) { this._realmToContext.delete(contextId); if (notifyFrame) frame._contextDestroyed(context); } } } _onRealmCreated(realmInfo) { if (this._realmToContext.has(realmInfo.realm)) return; if (realmInfo.type !== "window") return; const frame = this._page.frameManager.frame(realmInfo.context); if (!frame) return; let worldName; if (!realmInfo.sandbox) { worldName = "main"; this._touchUtilityWorld(realmInfo.context); } else if (realmInfo.sandbox === UTILITY_WORLD_NAME) { worldName = "utility"; } else { return; } const delegate = new import_bidiExecutionContext.BidiExecutionContext(this._session, realmInfo); const context = new dom.FrameExecutionContext(delegate, frame, worldName); frame._contextCreated(worldName, context); this._realmToContext.set(realmInfo.realm, context); } async _touchUtilityWorld(context) { await this._session.sendMayFail("script.evaluate", { expression: "1 + 1", target: { context, sandbox: UTILITY_WORLD_NAME }, serializationOptions: { maxObjectDepth: 10, maxDomDepth: 10 }, awaitPromise: true, userActivation: true }); } _onRealmDestroyed(params) { const context = this._realmToContext.get(params.realm); if (!context) return false; this._realmToContext.delete(params.realm); context.frame._contextDestroyed(context); return true; } // TODO: route the message directly to the browser _onBrowsingContextDestroyed(params) { this._browserContext._browser._onBrowsingContextDestroyed(params); } _onNavigationStarted(params) { const frameId = params.context; this._page.frameManager.frameRequestedNavigation(frameId, params.navigation); const url = params.url.toLowerCase(); if (url.startsWith("file:") || url.startsWith("data:") || url === "about:blank") { const frame = this._page.frameManager.frame(frameId); if (frame) this._page.frameManager.frameCommittedNewDocumentNavigation( frameId, params.url, "", params.navigation, /* initial */ false ); } } // TODO: there is no separate event for committed navigation, so we approximate it with responseStarted. _onNavigationResponseStarted(params) { const frameId = params.context; const frame = this._page.frameManager.frame(frameId); (0, import_utils.assert)(frame); this._page.frameManager.frameCommittedNewDocumentNavigation( frameId, params.response.url, "", params.navigation, /* initial */ false ); } _onDomContentLoaded(params) { const frameId = params.context; this._page.frameManager.frameLifecycleEvent(frameId, "domcontentloaded"); } _onLoad(params) { this._page.frameManager.frameLifecycleEvent(params.context, "load"); } _onNavigationAborted(params) { this._page.frameManager.frameAbortedNavigation(params.context, "Navigation aborted", params.navigation || void 0); } _onNavigationFailed(params) { this._page.frameManager.frameAbortedNavigation(params.context, "Navigation failed", params.navigation || void 0); } _onFragmentNavigated(params) { this._page.frameManager.frameCommittedSameDocumentNavigation(params.context, params.url); } _onUserPromptOpened(event) { this._page.browserContext.dialogManager.dialogDidOpen(new dialog.Dialog( this._page, event.type, event.message, async (accept, userText) => { await this._session.send("browsingContext.handleUserPrompt", { context: event.context, accept, userText }); }, event.defaultValue )); } _onLogEntryAdded(params) { if (params.type !== "console") return; const entry = params; const context = this._realmToContext.get(params.source.realm); if (!context) return; const callFrame = params.stackTrace?.callFrames[0]; const location = callFrame ?? { url: "", lineNumber: 1, columnNumber: 1 }; this._page.addConsoleMessage(entry.method, entry.args.map((arg) => (0, import_bidiExecutionContext.createHandle)(context, arg)), location, params.text || void 0); } async navigateFrame(frame, url, referrer) { const { navigation } = await this._session.send("browsingContext.navigate", { context: frame._id, url }); return { newDocumentId: navigation || void 0 }; } async updateExtraHTTPHeaders() { } async updateEmulateMedia() { } async updateUserAgent() { } async bringToFront() { await this._session.send("browsingContext.activate", { context: this._session.sessionId }); } async updateEmulatedViewportSize() { const options = this._browserContext._options; const emulatedSize = this._page.emulatedSize(); if (!emulatedSize) return; const viewportSize = emulatedSize.viewport; await this._session.send("browsingContext.setViewport", { context: this._session.sessionId, viewport: { width: viewportSize.width, height: viewportSize.height }, devicePixelRatio: options.deviceScaleFactor || 1 }); } async updateRequestInterception() { await this._networkManager.setRequestInterception(this._page.needsRequestInterception()); } async updateOffline() { } async updateHttpCredentials() { await this._networkManager.setCredentials(this._browserContext._options.httpCredentials); } async updateFileChooserInterception() { } async reload() { await this._session.send("browsingContext.reload", { context: this._session.sessionId, // ignoreCache: true, wait: bidi.BrowsingContext.ReadinessState.Interactive }); } async goBack() { return await this._session.send("browsingContext.traverseHistory", { context: this._session.sessionId, delta: -1 }).then(() => true).catch(() => false); } async goForward() { return await this._session.send("browsingContext.traverseHistory", { context: this._session.sessionId, delta: 1 }).then(() => true).catch(() => false); } async requestGC() { throw new Error("Method not implemented."); } async _onScriptMessage(event) { if (event.channel !== kPlaywrightBindingChannel) return; const pageOrError = await this._page.waitForInitializedOrError(); if (pageOrError instanceof Error) return; const context = this._realmToContext.get(event.source.realm); if (!context) return; if (event.data.type !== "string") return; await this._page.onBindingCalled(event.data.value, context); } async addInitScript(initScript) { const { script } = await this._session.send("script.addPreloadScript", { // TODO: remove function call from the source. functionDeclaration: `() => { return ${initScript.source} }`, // TODO: push to iframes? contexts: [this._session.sessionId] }); this._initScriptIds.set(initScript, script); } async removeInitScripts(initScripts) { const ids = []; for (const script of initScripts) { const id = this._initScriptIds.get(script); if (id) ids.push(id); this._initScriptIds.delete(script); } await Promise.all(ids.map((script) => this._session.send("script.removePreloadScript", { script }))); } async closePage(runBeforeUnload) { await this._session.send("browsingContext.close", { context: this._session.sessionId, promptUnload: runBeforeUnload }); } async setBackgroundColor(color) { } async takeScreenshot(progress, format, documentRect, viewportRect, quality, fitsViewport, scale) { const rect = documentRect || viewportRect; const { data } = await progress.race(this._session.send("browsingContext.captureScreenshot", { context: this._session.sessionId, format: { type: `image/${format === "png" ? "png" : "jpeg"}`, quality: quality ? quality / 100 : 0.8 }, origin: documentRect ? "document" : "viewport", clip: { type: "box", ...rect } })); return Buffer.from(data, "base64"); } async getContentFrame(handle) { const executionContext = toBidiExecutionContext(handle._context); const frameId = await executionContext.contentFrameIdForFrame(handle); if (!frameId) return null; return this._page.frameManager.frame(frameId); } async getOwnerFrame(handle) { const windowHandle = await handle.evaluateHandle((node) => { const doc = node.ownerDocument ?? node; return doc.defaultView; }); if (!windowHandle) return null; const executionContext = toBidiExecutionContext(handle._context); return executionContext.frameIdForWindowHandle(windowHandle); } async getBoundingBox(handle) { const box = await handle.evaluate((element) => { if (!(element instanceof Element)) return null; const rect = element.getBoundingClientRect(); return { x: rect.x, y: rect.y, width: rect.width, height: rect.height }; }); if (!box) return null; const position = await this._framePosition(handle._frame); if (!position) return null; box.x += position.x; box.y += position.y; return box; } // TODO: move to Frame. async _framePosition(frame) { if (frame === this._page.mainFrame()) return { x: 0, y: 0 }; const element = await frame.frameElement(); const box = await element.boundingBox(); if (!box) return null; const style = await element.evaluateInUtility(([injected, iframe]) => injected.describeIFrameStyle(iframe), {}).catch((e) => "error:notconnected"); if (style === "error:notconnected" || style === "transformed") return null; box.x += style.left; box.y += style.top; return box; } async scrollRectIntoViewIfNeeded(handle, rect) { return await handle.evaluateInUtility(([injected, node]) => { node.scrollIntoView({ block: "center", inline: "center", behavior: "instant" }); }, null).then(() => "done").catch((e) => { if (e instanceof Error && e.message.includes("Node is detached from document")) return "error:notconnected"; if (e instanceof Error && e.message.includes("Node does not have a layout object")) return "error:notvisible"; throw e; }); } async setScreencastOptions(options) { } rafCountForStablePosition() { return 1; } async getContentQuads(handle) { const quads = await handle.evaluateInUtility(([injected, node]) => { if (!node.isConnected) return "error:notconnected"; const rects = node.getClientRects(); if (!rects) return null; return [...rects].map((rect) => [ { x: rect.left, y: rect.top }, { x: rect.right, y: rect.top }, { x: rect.right, y: rect.bottom }, { x: rect.left, y: rect.bottom } ]); }, null); if (!quads || quads === "error:notconnected") return quads; const position = await this._framePosition(handle._frame); if (!position) return null; quads.forEach((quad) => quad.forEach((point) => { point.x += position.x; point.y += position.y; })); return quads; } async setInputFilePaths(handle, paths) { const fromContext = toBidiExecutionContext(handle._context); await this._session.send("input.setFiles", { context: this._session.sessionId, element: await fromContext.nodeIdForElementHandle(handle), files: paths }); } async adoptElementHandle(handle, to) { const fromContext = toBidiExecutionContext(handle._context); const nodeId = await fromContext.nodeIdForElementHandle(handle); const executionContext = toBidiExecutionContext(to); return await executionContext.remoteObjectForNodeId(to, nodeId); } async getAccessibilityTree(needle) { throw new Error("Method not implemented."); } async inputActionEpilogue() { } async resetForReuse(progress) { } async pdf(options) { return this._pdf.generate(options); } async getFrameElement(frame) { const parent = frame.parentFrame(); if (!parent) throw new Error("Frame has been detached."); const parentContext = await parent._mainContext(); const list = await parentContext.evaluateHandle(() => { return [...document.querySelectorAll("iframe,frame")]; }); const length = await list.evaluate((list2) => list2.length); let foundElement = null; for (let i = 0; i < length; i++) { const element = await list.evaluateHandle((list2, i2) => list2[i2], i); const candidate = await element.contentFrame(); if (frame === candidate) { foundElement = element; break; } else { element.dispose(); } } list.dispose(); if (!foundElement) throw new Error("Frame has been detached."); return foundElement; } shouldToggleStyleSheetToSyncAnimations() { return true; } } function toBidiExecutionContext(executionContext) { return executionContext.delegate; } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { BidiPage, kPlaywrightBindingChannel });