@midscene/playground 0.30.10 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/adapters/base.mjs +4 -4
- package/dist/es/adapters/base.mjs.map +1 -1
- package/dist/es/adapters/local-execution.mjs +61 -35
- package/dist/es/adapters/local-execution.mjs.map +1 -1
- package/dist/es/adapters/remote-execution.mjs +13 -38
- package/dist/es/adapters/remote-execution.mjs.map +1 -1
- package/dist/es/common.mjs +16 -13
- package/dist/es/common.mjs.map +1 -1
- package/dist/es/index.browser.mjs.map +1 -1
- package/dist/es/launcher.mjs +12 -12
- package/dist/es/launcher.mjs.map +1 -1
- package/dist/es/sdk/index.mjs +14 -10
- package/dist/es/sdk/index.mjs.map +1 -1
- package/dist/es/server.mjs +37 -15
- package/dist/es/server.mjs.map +1 -1
- package/dist/lib/adapters/base.js +6 -6
- package/dist/lib/adapters/base.js.map +1 -1
- package/dist/lib/adapters/local-execution.js +63 -37
- package/dist/lib/adapters/local-execution.js.map +1 -1
- package/dist/lib/adapters/remote-execution.js +15 -40
- package/dist/lib/adapters/remote-execution.js.map +1 -1
- package/dist/lib/common.js +20 -17
- package/dist/lib/common.js.map +1 -1
- package/dist/lib/index.browser.js +10 -10
- package/dist/lib/index.browser.js.map +1 -1
- package/dist/lib/index.js +10 -10
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/launcher.js +14 -14
- package/dist/lib/launcher.js.map +1 -1
- package/dist/lib/sdk/index.js +16 -12
- package/dist/lib/sdk/index.js.map +1 -1
- package/dist/lib/server.js +41 -19
- package/dist/lib/server.js.map +1 -1
- package/dist/lib/types.js +1 -1
- package/dist/lib/types.js.map +1 -1
- package/dist/types/adapters/local-execution.d.ts +18 -6
- package/dist/types/adapters/remote-execution.d.ts +2 -5
- package/dist/types/sdk/index.d.ts +6 -2
- package/dist/types/server.d.ts +2 -1
- package/dist/types/types.d.ts +26 -0
- package/package.json +6 -6
- package/static/index.html +1 -1
- package/static/static/css/index.d32b7df9.css +2 -0
- package/static/static/css/index.d32b7df9.css.map +1 -0
- package/static/static/js/79.25af61dc.js +611 -0
- package/static/static/js/{931.dc961e99.js.LICENSE.txt → 79.25af61dc.js.LICENSE.txt} +0 -4
- package/static/static/js/79.25af61dc.js.map +1 -0
- package/static/static/js/async/195.0366f6e8.js +3 -0
- package/static/static/js/async/195.0366f6e8.js.map +1 -0
- package/static/static/js/async/{702.60261735.js → 199.f31e52e7.js} +20 -20
- package/static/static/js/async/199.f31e52e7.js.map +1 -0
- package/static/static/js/async/221.591b048e.js +21 -0
- package/static/static/js/async/221.591b048e.js.map +1 -0
- package/static/static/js/async/271.15d46ff8.js +30 -0
- package/static/static/js/async/271.15d46ff8.js.map +1 -0
- package/static/static/js/async/35.2b64fb0f.js +1 -0
- package/static/static/js/async/{644.6bdc4065.js → 467.710fa05a.js} +1 -1
- package/static/static/js/async/652.b5a7c7b4.js +3 -0
- package/static/static/js/async/652.b5a7c7b4.js.map +1 -0
- package/static/static/js/async/856.be9fd814.js +158 -0
- package/static/static/js/async/{212.e243c338.js.map → 856.be9fd814.js.map} +1 -1
- package/static/static/js/async/860.b56301d9.js +2 -0
- package/static/static/js/async/860.b56301d9.js.map +1 -0
- package/static/static/js/async/990.82a78a53.js +26 -0
- package/static/static/js/async/990.82a78a53.js.map +1 -0
- package/static/static/js/index.0930f837.js +10 -0
- package/static/static/js/index.0930f837.js.map +1 -0
- package/static/static/js/lib-react.7b1abe58.js +3 -0
- package/static/static/js/lib-react.7b1abe58.js.map +1 -0
- package/static/static/css/index.44466eb4.css +0 -2
- package/static/static/css/index.44466eb4.css.map +0 -1
- package/static/static/js/931.dc961e99.js +0 -620
- package/static/static/js/931.dc961e99.js.map +0 -1
- package/static/static/js/async/173.9cf6b074.js +0 -3
- package/static/static/js/async/173.9cf6b074.js.map +0 -1
- package/static/static/js/async/212.e243c338.js +0 -158
- package/static/static/js/async/329.f888b505.js +0 -26
- package/static/static/js/async/329.f888b505.js.map +0 -1
- package/static/static/js/async/364.1821e74b.js +0 -30
- package/static/static/js/async/364.1821e74b.js.map +0 -1
- package/static/static/js/async/544.b73fa603.js +0 -2
- package/static/static/js/async/544.b73fa603.js.map +0 -1
- package/static/static/js/async/582.5dccae2d.js +0 -21
- package/static/static/js/async/582.5dccae2d.js.map +0 -1
- package/static/static/js/async/624.45ee2b2c.js +0 -3
- package/static/static/js/async/624.45ee2b2c.js.map +0 -1
- package/static/static/js/async/659.9afd03db.js +0 -21
- package/static/static/js/async/659.9afd03db.js.map +0 -1
- package/static/static/js/async/702.60261735.js.map +0 -1
- package/static/static/js/async/920.7d9a9aa8.js +0 -2
- package/static/static/js/async/920.7d9a9aa8.js.map +0 -1
- package/static/static/js/async/983.8b91303f.js +0 -1
- package/static/static/js/index.2caaacaf.js +0 -10
- package/static/static/js/index.2caaacaf.js.map +0 -1
- package/static/static/js/lib-react.f566a9ed.js +0 -3
- package/static/static/js/lib-react.f566a9ed.js.map +0 -1
- /package/static/static/js/{index.2caaacaf.js.LICENSE.txt → index.0930f837.js.LICENSE.txt} +0 -0
- /package/static/static/js/{lib-react.f566a9ed.js.LICENSE.txt → lib-react.7b1abe58.js.LICENSE.txt} +0 -0
- /package/static/static/wasm/{9e906fbf55e08f98.module.wasm → 9e906fbf.module.wasm} +0 -0
package/dist/es/server.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.mjs","sources":["webpack://@midscene/playground/./src/server.ts"],"sourcesContent":["import { existsSync, readFileSync, writeFileSync } from 'node:fs';\nimport type { Server } from 'node:http';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { Agent as PageAgent } from '@midscene/core/agent';\nimport { getTmpDir } from '@midscene/core/utils';\nimport { PLAYGROUND_SERVER_PORT } from '@midscene/shared/constants';\nimport { overrideAIConfig } from '@midscene/shared/env';\nimport { uuid } from '@midscene/shared/utils';\nimport express, { type Request, type Response } from 'express';\nimport { executeAction, formatErrorMessage } from './common';\n\nimport 'dotenv/config';\n\nconst defaultPort = PLAYGROUND_SERVER_PORT;\n\n// Static path for playground files\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst STATIC_PATH = join(__dirname, '..', '..', 'static');\n\nconst errorHandler = (\n err: unknown,\n req: Request,\n res: Response,\n next: express.NextFunction,\n) => {\n console.error(err);\n const errorMessage =\n err instanceof Error ? err.message : 'Internal server error';\n res.status(500).json({\n error: errorMessage,\n });\n};\n\nclass PlaygroundServer {\n private _app: express.Application;\n tmpDir: string;\n server?: Server;\n port?: number | null;\n agent: PageAgent;\n staticPath: string;\n taskProgressTips: Record<string, string>;\n id: string; // Unique identifier for this server instance\n\n private _initialized = false;\n\n // Factory function for recreating agent\n private agentFactory?: (() => PageAgent | Promise<PageAgent>) | null;\n\n // Track current running task\n private currentTaskId: string | null = null;\n\n constructor(\n agent: PageAgent | (() => PageAgent) | (() => Promise<PageAgent>),\n staticPath = STATIC_PATH,\n id?: string, // Optional override ID\n ) {\n this._app = express();\n this.tmpDir = getTmpDir()!;\n this.staticPath = staticPath;\n this.taskProgressTips = {};\n // Use provided ID, or generate random UUID for each startup\n this.id = id || uuid();\n\n // Support both instance and factory function modes\n if (typeof agent === 'function') {\n this.agentFactory = agent;\n this.agent = null as any; // Will be initialized in launch()\n } else {\n this.agent = agent;\n this.agentFactory = null;\n }\n }\n\n /**\n * Get the Express app instance for custom configuration\n *\n * IMPORTANT: Add middleware (like CORS) BEFORE calling launch()\n * The routes are initialized when launch() is called, so middleware\n * added after launch() will not affect the API routes.\n *\n * @example\n * ```typescript\n * import cors from 'cors';\n *\n * const server = new PlaygroundServer(agent);\n *\n * // Add CORS middleware before launch\n * server.app.use(cors({\n * origin: true,\n * credentials: true,\n * methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']\n * }));\n *\n * await server.launch();\n * ```\n */\n get app(): express.Application {\n return this._app;\n }\n\n /**\n * Initialize Express app with all routes and middleware\n * Called automatically by launch() if not already initialized\n */\n private initializeApp(): void {\n if (this._initialized) return;\n\n // Built-in middleware to parse JSON bodies\n this._app.use(express.json({ limit: '50mb' }));\n\n // Context update middleware (after JSON parsing)\n this._app.use(\n (req: Request, _res: Response, next: express.NextFunction) => {\n const { context } = req.body || {};\n if (\n context &&\n 'updateContext' in this.agent.interface &&\n typeof this.agent.interface.updateContext === 'function'\n ) {\n this.agent.interface.updateContext(context);\n console.log('Context updated by PlaygroundServer middleware');\n }\n next();\n },\n );\n\n // NOTE: CORS middleware should be added externally via server.app.use()\n // before calling server.launch() if needed\n\n // API routes\n this.setupRoutes();\n\n // Static file serving (if staticPath is provided)\n this.setupStaticRoutes();\n\n // Error handler middleware (must be last)\n this._app.use(errorHandler);\n\n this._initialized = true;\n }\n\n filePathForUuid(uuid: string) {\n return join(this.tmpDir, `${uuid}.json`);\n }\n\n saveContextFile(uuid: string, context: string) {\n const tmpFile = this.filePathForUuid(uuid);\n console.log(`save context file: ${tmpFile}`);\n writeFileSync(tmpFile, context);\n return tmpFile;\n }\n\n /**\n * Recreate agent instance (for cancellation)\n */\n private async recreateAgent(): Promise<void> {\n if (!this.agentFactory) {\n console.warn(\n 'Cannot recreate agent: factory function not provided. Agent recreation is only available when using factory mode.',\n );\n return;\n }\n\n console.log('Recreating agent to cancel current task...');\n\n // Destroy old agent instance\n try {\n if (this.agent && typeof this.agent.destroy === 'function') {\n await this.agent.destroy();\n }\n } catch (error) {\n console.warn('Failed to destroy old agent:', error);\n }\n\n // Create new agent instance\n try {\n this.agent = await this.agentFactory();\n console.log('Agent recreated successfully');\n } catch (error) {\n console.error('Failed to recreate agent:', error);\n throw error;\n }\n }\n\n /**\n * Setup all API routes\n */\n private setupRoutes(): void {\n this._app.get('/status', async (req: Request, res: Response) => {\n res.send({\n status: 'ok',\n id: this.id,\n });\n });\n\n this._app.get('/context/:uuid', async (req: Request, res: Response) => {\n const { uuid } = req.params;\n const contextFile = this.filePathForUuid(uuid);\n\n if (!existsSync(contextFile)) {\n return res.status(404).json({\n error: 'Context not found',\n });\n }\n\n const context = readFileSync(contextFile, 'utf8');\n res.json({\n context,\n });\n });\n\n this._app.get(\n '/task-progress/:requestId',\n async (req: Request, res: Response) => {\n const { requestId } = req.params;\n res.json({\n tip: this.taskProgressTips[requestId] || '',\n });\n },\n );\n\n this._app.post('/action-space', async (req: Request, res: Response) => {\n try {\n let actionSpace = [];\n\n actionSpace = await this.agent.interface.actionSpace();\n\n // Process actionSpace to make paramSchema serializable with shape info\n const processedActionSpace = actionSpace.map((action: unknown) => {\n if (action && typeof action === 'object' && 'paramSchema' in action) {\n const typedAction = action as {\n paramSchema?: { shape?: object; [key: string]: unknown };\n [key: string]: unknown;\n };\n if (\n typedAction.paramSchema &&\n typeof typedAction.paramSchema === 'object'\n ) {\n // Extract shape information from Zod schema\n let processedSchema = null;\n\n try {\n // Extract shape from runtime Zod object\n if (\n typedAction.paramSchema.shape &&\n typeof typedAction.paramSchema.shape === 'object'\n ) {\n processedSchema = {\n type: 'ZodObject',\n shape: typedAction.paramSchema.shape,\n };\n }\n } catch (e) {\n const actionName =\n 'name' in typedAction && typeof typedAction.name === 'string'\n ? typedAction.name\n : 'unknown';\n console.warn(\n 'Failed to process paramSchema for action:',\n actionName,\n e,\n );\n }\n\n return {\n ...typedAction,\n paramSchema: processedSchema,\n };\n }\n }\n return action;\n });\n\n res.json(processedActionSpace);\n } catch (error: unknown) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error';\n console.error('Failed to get action space:', error);\n res.status(500).json({\n error: errorMessage,\n });\n }\n });\n\n // -------------------------\n // actions from report file\n this._app.post(\n '/playground-with-context',\n async (req: Request, res: Response) => {\n const context = req.body.context;\n\n if (!context) {\n return res.status(400).json({\n error: 'context is required',\n });\n }\n\n const requestId = uuid();\n this.saveContextFile(requestId, context);\n return res.json({\n location: `/playground/${requestId}`,\n uuid: requestId,\n });\n },\n );\n\n this._app.post('/execute', async (req: Request, res: Response) => {\n const {\n type,\n prompt,\n params,\n requestId,\n deepThink,\n screenshotIncluded,\n domIncluded,\n } = req.body;\n\n if (!type) {\n return res.status(400).json({\n error: 'type is required',\n });\n }\n\n // Check if another task is running\n if (this.currentTaskId) {\n return res.status(409).json({\n error: 'Another task is already running',\n currentTaskId: this.currentTaskId,\n });\n }\n\n // Lock this task\n if (requestId) {\n this.currentTaskId = requestId;\n this.taskProgressTips[requestId] = '';\n\n this.agent.onTaskStartTip = (tip: string) => {\n this.taskProgressTips[requestId] = tip;\n };\n }\n\n const response: {\n result: unknown;\n dump: string | null;\n error: string | null;\n reportHTML: string | null;\n requestId?: string;\n } = {\n result: null,\n dump: null,\n error: null,\n reportHTML: null,\n requestId,\n };\n\n const startTime = Date.now();\n try {\n // Get action space to check for dynamic actions\n const actionSpace = await this.agent.interface.actionSpace();\n\n // Prepare value object for executeAction\n const value = {\n type,\n prompt,\n params,\n };\n\n response.result = await executeAction(\n this.agent,\n type,\n actionSpace,\n value,\n {\n deepThink,\n screenshotIncluded,\n domIncluded,\n },\n );\n } catch (error: unknown) {\n response.error = formatErrorMessage(error);\n }\n\n try {\n response.dump = JSON.parse(this.agent.dumpDataString());\n response.reportHTML = this.agent.reportHTMLString() || null;\n\n this.agent.writeOutActionDumps();\n this.agent.resetDump();\n } catch (error: unknown) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error';\n console.error(\n `write out dump failed: requestId: ${requestId}, ${errorMessage}`,\n );\n }\n\n res.send(response);\n const timeCost = Date.now() - startTime;\n\n if (response.error) {\n console.error(\n `handle request failed after ${timeCost}ms: requestId: ${requestId}, ${response.error}`,\n );\n } else {\n console.log(\n `handle request done after ${timeCost}ms: requestId: ${requestId}`,\n );\n }\n\n // Clean up task progress tip and unlock after execution completes\n if (requestId) {\n delete this.taskProgressTips[requestId];\n // Release the lock\n if (this.currentTaskId === requestId) {\n this.currentTaskId = null;\n }\n }\n });\n\n this._app.post(\n '/cancel/:requestId',\n async (req: Request, res: Response) => {\n const { requestId } = req.params;\n\n if (!requestId) {\n return res.status(400).json({\n error: 'requestId is required',\n });\n }\n\n try {\n // Check if this is the current running task\n if (this.currentTaskId !== requestId) {\n return res.json({\n status: 'not_found',\n message: 'Task not found or already completed',\n });\n }\n\n console.log(`Cancelling task: ${requestId}`);\n\n // Recreate agent to cancel the current task\n await this.recreateAgent();\n\n // Clean up\n delete this.taskProgressTips[requestId];\n this.currentTaskId = null;\n\n res.json({\n status: 'cancelled',\n message: 'Task cancelled successfully by recreating agent',\n });\n } catch (error: unknown) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error';\n console.error(`Failed to cancel: ${errorMessage}`);\n res.status(500).json({\n error: `Failed to cancel: ${errorMessage}`,\n });\n }\n },\n );\n\n // Screenshot API for real-time screenshot polling\n this._app.get('/screenshot', async (_req: Request, res: Response) => {\n try {\n // Check if page has screenshotBase64 method\n if (typeof this.agent.interface.screenshotBase64 !== 'function') {\n return res.status(500).json({\n error: 'Screenshot method not available on current interface',\n });\n }\n\n const base64Screenshot = await this.agent.interface.screenshotBase64();\n\n res.json({\n screenshot: base64Screenshot,\n timestamp: Date.now(),\n });\n } catch (error: unknown) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error';\n console.error(`Failed to take screenshot: ${errorMessage}`);\n res.status(500).json({\n error: `Failed to take screenshot: ${errorMessage}`,\n });\n }\n });\n\n // Interface info API for getting interface type and description\n this._app.get('/interface-info', async (_req: Request, res: Response) => {\n try {\n const type = this.agent.interface.interfaceType || 'Unknown';\n const description = this.agent.interface.describe?.() || undefined;\n\n res.json({\n type,\n description,\n });\n } catch (error: unknown) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error';\n console.error(`Failed to get interface info: ${errorMessage}`);\n res.status(500).json({\n error: `Failed to get interface info: ${errorMessage}`,\n });\n }\n });\n\n this.app.post('/config', async (req: Request, res: Response) => {\n const { aiConfig } = req.body;\n\n if (!aiConfig || typeof aiConfig !== 'object') {\n return res.status(400).json({\n error: 'aiConfig is required and must be an object',\n });\n }\n\n if (Object.keys(aiConfig).length === 0) {\n return res.json({\n status: 'ok',\n message: 'AI config not changed due to empty object',\n });\n }\n\n try {\n overrideAIConfig(aiConfig);\n\n return res.json({\n status: 'ok',\n message: 'AI config updated successfully',\n });\n } catch (error: unknown) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error';\n console.error(`Failed to update AI config: ${errorMessage}`);\n return res.status(500).json({\n error: `Failed to update AI config: ${errorMessage}`,\n });\n }\n });\n }\n\n /**\n * Setup static file serving routes\n */\n private setupStaticRoutes(): void {\n // Handle index.html with port injection\n this._app.get('/', (_req: Request, res: Response) => {\n this.serveHtmlWithPorts(res);\n });\n\n this._app.get('/index.html', (_req: Request, res: Response) => {\n this.serveHtmlWithPorts(res);\n });\n\n // Use express.static middleware for secure static file serving\n this._app.use(express.static(this.staticPath));\n\n // Fallback to index.html for SPA routing\n this._app.get('*', (_req: Request, res: Response) => {\n this.serveHtmlWithPorts(res);\n });\n }\n\n /**\n * Serve HTML with injected port configuration\n */\n private serveHtmlWithPorts(res: Response): void {\n try {\n const htmlPath = join(this.staticPath, 'index.html');\n let html = readFileSync(htmlPath, 'utf8');\n\n // Get scrcpy server port from global\n const scrcpyPort = (global as any).scrcpyServerPort || this.port! + 1;\n\n // Inject scrcpy port configuration script into HTML head\n const configScript = `\n <script>\n window.SCRCPY_PORT = ${scrcpyPort};\n </script>\n `;\n\n // Insert the script before closing </head> tag\n html = html.replace('</head>', `${configScript}</head>`);\n\n res.setHeader('Content-Type', 'text/html');\n res.send(html);\n } catch (error) {\n console.error('Error serving HTML with ports:', error);\n res.status(500).send('Internal Server Error');\n }\n }\n\n /**\n * Launch the server on specified port\n */\n async launch(port?: number): Promise<PlaygroundServer> {\n // If using factory mode, initialize agent\n if (this.agentFactory) {\n console.log('Initializing agent from factory function...');\n this.agent = await this.agentFactory();\n console.log('Agent initialized successfully');\n }\n\n // Initialize routes now, after any middleware has been added\n this.initializeApp();\n\n this.port = port || defaultPort;\n\n return new Promise((resolve) => {\n const serverPort = this.port;\n this.server = this._app.listen(serverPort, () => {\n resolve(this);\n });\n });\n }\n\n /**\n * Close the server and clean up resources\n */\n async close(): Promise<void> {\n return new Promise((resolve, reject) => {\n if (this.server) {\n // Clean up the single agent\n try {\n this.agent.destroy();\n } catch (error) {\n console.warn('Failed to destroy agent:', error);\n }\n this.taskProgressTips = {};\n\n // Close the server\n this.server.close((error) => {\n if (error) {\n reject(error);\n } else {\n this.server = undefined;\n resolve();\n }\n });\n } else {\n resolve();\n }\n });\n }\n}\n\nexport default PlaygroundServer;\nexport { PlaygroundServer };\n"],"names":["defaultPort","PLAYGROUND_SERVER_PORT","__filename","fileURLToPath","__dirname","dirname","STATIC_PATH","join","errorHandler","err","req","res","next","console","errorMessage","Error","PlaygroundServer","express","_res","context","uuid","tmpFile","writeFileSync","error","contextFile","existsSync","readFileSync","requestId","actionSpace","processedActionSpace","action","typedAction","processedSchema","e","actionName","type","prompt","params","deepThink","screenshotIncluded","domIncluded","tip","response","startTime","Date","value","executeAction","formatErrorMessage","JSON","timeCost","_req","base64Screenshot","_this_agent_interface","description","undefined","aiConfig","Object","overrideAIConfig","htmlPath","html","scrcpyPort","global","configScript","port","Promise","resolve","serverPort","reject","agent","staticPath","id","getTmpDir"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"server.mjs","sources":["../../src/server.ts"],"sourcesContent":["import { existsSync, readFileSync, writeFileSync } from 'node:fs';\nimport type { Server } from 'node:http';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { ExecutionDump } from '@midscene/core';\nimport type { Agent as PageAgent } from '@midscene/core/agent';\nimport { paramStr, typeStr } from '@midscene/core/agent';\nimport { getTmpDir } from '@midscene/core/utils';\nimport { PLAYGROUND_SERVER_PORT } from '@midscene/shared/constants';\nimport { overrideAIConfig } from '@midscene/shared/env';\nimport { uuid } from '@midscene/shared/utils';\nimport express, { type Request, type Response } from 'express';\nimport { executeAction, formatErrorMessage } from './common';\nimport type { ProgressMessage } from './types';\n\nimport 'dotenv/config';\n\nconst defaultPort = PLAYGROUND_SERVER_PORT;\n\n// Static path for playground files\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst STATIC_PATH = join(__dirname, '..', '..', 'static');\n\nconst errorHandler = (\n err: unknown,\n req: Request,\n res: Response,\n next: express.NextFunction,\n) => {\n console.error(err);\n const errorMessage =\n err instanceof Error ? err.message : 'Internal server error';\n res.status(500).json({\n error: errorMessage,\n });\n};\n\nclass PlaygroundServer {\n private _app: express.Application;\n tmpDir: string;\n server?: Server;\n port?: number | null;\n agent: PageAgent;\n staticPath: string;\n taskProgressMessages: Record<string, ProgressMessage[]>; // Store full progress messages array\n id: string; // Unique identifier for this server instance\n\n private _initialized = false;\n\n // Factory function for recreating agent\n private agentFactory?: (() => PageAgent | Promise<PageAgent>) | null;\n\n // Track current running task\n private currentTaskId: string | null = null;\n\n constructor(\n agent: PageAgent | (() => PageAgent) | (() => Promise<PageAgent>),\n staticPath = STATIC_PATH,\n id?: string, // Optional override ID\n ) {\n this._app = express();\n this.tmpDir = getTmpDir()!;\n this.staticPath = staticPath;\n this.taskProgressMessages = {}; // Initialize as empty object\n // Use provided ID, or generate random UUID for each startup\n this.id = id || uuid();\n\n // Support both instance and factory function modes\n if (typeof agent === 'function') {\n this.agentFactory = agent;\n this.agent = null as any; // Will be initialized in launch()\n } else {\n this.agent = agent;\n this.agentFactory = null;\n }\n }\n\n /**\n * Get the Express app instance for custom configuration\n *\n * IMPORTANT: Add middleware (like CORS) BEFORE calling launch()\n * The routes are initialized when launch() is called, so middleware\n * added after launch() will not affect the API routes.\n *\n * @example\n * ```typescript\n * import cors from 'cors';\n *\n * const server = new PlaygroundServer(agent);\n *\n * // Add CORS middleware before launch\n * server.app.use(cors({\n * origin: true,\n * credentials: true,\n * methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']\n * }));\n *\n * await server.launch();\n * ```\n */\n get app(): express.Application {\n return this._app;\n }\n\n /**\n * Initialize Express app with all routes and middleware\n * Called automatically by launch() if not already initialized\n */\n private initializeApp(): void {\n if (this._initialized) return;\n\n // Built-in middleware to parse JSON bodies\n this._app.use(express.json({ limit: '50mb' }));\n\n // Context update middleware (after JSON parsing)\n this._app.use(\n (req: Request, _res: Response, next: express.NextFunction) => {\n const { context } = req.body || {};\n if (\n context &&\n 'updateContext' in this.agent.interface &&\n typeof this.agent.interface.updateContext === 'function'\n ) {\n this.agent.interface.updateContext(context);\n console.log('Context updated by PlaygroundServer middleware');\n }\n next();\n },\n );\n\n // NOTE: CORS middleware should be added externally via server.app.use()\n // before calling server.launch() if needed\n\n // API routes\n this.setupRoutes();\n\n // Static file serving (if staticPath is provided)\n this.setupStaticRoutes();\n\n // Error handler middleware (must be last)\n this._app.use(errorHandler);\n\n this._initialized = true;\n }\n\n filePathForUuid(uuid: string) {\n return join(this.tmpDir, `${uuid}.json`);\n }\n\n saveContextFile(uuid: string, context: string) {\n const tmpFile = this.filePathForUuid(uuid);\n console.log(`save context file: ${tmpFile}`);\n writeFileSync(tmpFile, context);\n return tmpFile;\n }\n\n /**\n * Recreate agent instance (for cancellation)\n */\n private async recreateAgent(): Promise<void> {\n if (!this.agentFactory) {\n console.warn(\n 'Cannot recreate agent: factory function not provided. Agent recreation is only available when using factory mode.',\n );\n return;\n }\n\n console.log('Recreating agent to cancel current task...');\n\n // Destroy old agent instance\n try {\n if (this.agent && typeof this.agent.destroy === 'function') {\n await this.agent.destroy();\n }\n } catch (error) {\n console.warn('Failed to destroy old agent:', error);\n }\n\n // Create new agent instance\n try {\n this.agent = await this.agentFactory();\n console.log('Agent recreated successfully');\n } catch (error) {\n console.error('Failed to recreate agent:', error);\n throw error;\n }\n }\n\n /**\n * Setup all API routes\n */\n private setupRoutes(): void {\n this._app.get('/status', async (req: Request, res: Response) => {\n res.send({\n status: 'ok',\n id: this.id,\n });\n });\n\n this._app.get('/context/:uuid', async (req: Request, res: Response) => {\n const { uuid } = req.params;\n const contextFile = this.filePathForUuid(uuid);\n\n if (!existsSync(contextFile)) {\n return res.status(404).json({\n error: 'Context not found',\n });\n }\n\n const context = readFileSync(contextFile, 'utf8');\n res.json({\n context,\n });\n });\n\n this._app.get(\n '/task-progress/:requestId',\n async (req: Request, res: Response) => {\n const { requestId } = req.params;\n const progressMessages = this.taskProgressMessages[requestId] || [];\n // For backward compatibility, also provide a tip string from the last message\n const lastMessage =\n progressMessages.length > 0\n ? progressMessages[progressMessages.length - 1]\n : undefined;\n const tip =\n lastMessage && typeof lastMessage.action === 'string'\n ? `${lastMessage.action} - ${lastMessage.description || ''}`\n : '';\n res.json({\n tip,\n progressMessages, // Provide full progress messages array\n });\n },\n );\n\n this._app.post('/action-space', async (req: Request, res: Response) => {\n try {\n let actionSpace = [];\n\n actionSpace = this.agent.interface.actionSpace();\n\n // Process actionSpace to make paramSchema serializable with shape info\n const processedActionSpace = actionSpace.map((action: unknown) => {\n if (action && typeof action === 'object' && 'paramSchema' in action) {\n const typedAction = action as {\n paramSchema?: { shape?: object; [key: string]: unknown };\n [key: string]: unknown;\n };\n if (\n typedAction.paramSchema &&\n typeof typedAction.paramSchema === 'object'\n ) {\n // Extract shape information from Zod schema\n let processedSchema = null;\n\n try {\n // Extract shape from runtime Zod object\n if (\n typedAction.paramSchema.shape &&\n typeof typedAction.paramSchema.shape === 'object'\n ) {\n processedSchema = {\n type: 'ZodObject',\n shape: typedAction.paramSchema.shape,\n };\n }\n } catch (e) {\n const actionName =\n 'name' in typedAction && typeof typedAction.name === 'string'\n ? typedAction.name\n : 'unknown';\n console.warn(\n 'Failed to process paramSchema for action:',\n actionName,\n e,\n );\n }\n\n return {\n ...typedAction,\n paramSchema: processedSchema,\n };\n }\n }\n return action;\n });\n\n res.json(processedActionSpace);\n } catch (error: unknown) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error';\n console.error('Failed to get action space:', error);\n res.status(500).json({\n error: errorMessage,\n });\n }\n });\n\n // -------------------------\n // actions from report file\n this._app.post(\n '/playground-with-context',\n async (req: Request, res: Response) => {\n const context = req.body.context;\n\n if (!context) {\n return res.status(400).json({\n error: 'context is required',\n });\n }\n\n const requestId = uuid();\n this.saveContextFile(requestId, context);\n return res.json({\n location: `/playground/${requestId}`,\n uuid: requestId,\n });\n },\n );\n\n this._app.post('/execute', async (req: Request, res: Response) => {\n const {\n type,\n prompt,\n params,\n requestId,\n deepThink,\n screenshotIncluded,\n domIncluded,\n deviceOptions,\n } = req.body;\n\n if (!type) {\n return res.status(400).json({\n error: 'type is required',\n });\n }\n\n // Update device options if provided\n if (\n deviceOptions &&\n this.agent.interface &&\n 'options' in this.agent.interface\n ) {\n this.agent.interface.options = {\n ...(this.agent.interface.options || {}),\n ...deviceOptions,\n };\n }\n\n // Check if another task is running\n if (this.currentTaskId) {\n return res.status(409).json({\n error: 'Another task is already running',\n currentTaskId: this.currentTaskId,\n });\n }\n\n // Lock this task\n if (requestId) {\n this.currentTaskId = requestId;\n this.taskProgressMessages[requestId] = [];\n\n // Use onDumpUpdate to receive executionDump and transform tasks to progress messages\n this.agent.onDumpUpdate = (\n _dump: string,\n executionDump?: ExecutionDump,\n ) => {\n if (executionDump?.tasks) {\n // Transform executionDump.tasks to ProgressMessage[] for API compatibility\n this.taskProgressMessages[requestId] = executionDump.tasks.map(\n (task, index) => {\n const action = typeStr(task);\n const description = paramStr(task) || '';\n\n // Map task status\n const taskStatus = task.status;\n const status: 'pending' | 'running' | 'finished' | 'failed' =\n taskStatus === 'cancelled' ? 'failed' : taskStatus;\n\n return {\n id: `progress-task-${index}`,\n taskId: `task-${index}`,\n action,\n description,\n status,\n timestamp: task.timing?.start || Date.now(),\n };\n },\n );\n }\n };\n }\n\n const response: {\n result: unknown;\n dump: string | null;\n error: string | null;\n reportHTML: string | null;\n requestId?: string;\n } = {\n result: null,\n dump: null,\n error: null,\n reportHTML: null,\n requestId,\n };\n\n const startTime = Date.now();\n try {\n // Get action space to check for dynamic actions\n const actionSpace = this.agent.interface.actionSpace();\n\n // Prepare value object for executeAction\n const value = {\n type,\n prompt,\n params,\n };\n\n response.result = await executeAction(\n this.agent,\n type,\n actionSpace,\n value,\n {\n deepThink,\n screenshotIncluded,\n domIncluded,\n deviceOptions,\n },\n );\n } catch (error: unknown) {\n response.error = formatErrorMessage(error);\n }\n\n try {\n response.dump = JSON.parse(this.agent.dumpDataString());\n response.reportHTML = this.agent.reportHTMLString() || null;\n\n this.agent.writeOutActionDumps();\n this.agent.resetDump();\n } catch (error: unknown) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error';\n console.error(\n `write out dump failed: requestId: ${requestId}, ${errorMessage}`,\n );\n }\n\n res.send(response);\n const timeCost = Date.now() - startTime;\n\n if (response.error) {\n console.error(\n `handle request failed after ${timeCost}ms: requestId: ${requestId}, ${response.error}`,\n );\n } else {\n console.log(\n `handle request done after ${timeCost}ms: requestId: ${requestId}`,\n );\n }\n\n // Clean up task progress messages and unlock after execution completes\n if (requestId) {\n delete this.taskProgressMessages[requestId];\n // Release the lock\n if (this.currentTaskId === requestId) {\n this.currentTaskId = null;\n }\n }\n });\n\n this._app.post(\n '/cancel/:requestId',\n async (req: Request, res: Response) => {\n const { requestId } = req.params;\n\n if (!requestId) {\n return res.status(400).json({\n error: 'requestId is required',\n });\n }\n\n try {\n // Check if this is the current running task\n if (this.currentTaskId !== requestId) {\n return res.json({\n status: 'not_found',\n message: 'Task not found or already completed',\n });\n }\n\n console.log(`Cancelling task: ${requestId}`);\n\n // Recreate agent to cancel the current task\n await this.recreateAgent();\n\n // Clean up\n delete this.taskProgressMessages[requestId];\n this.currentTaskId = null;\n\n res.json({\n status: 'cancelled',\n message: 'Task cancelled successfully by recreating agent',\n });\n } catch (error: unknown) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error';\n console.error(`Failed to cancel: ${errorMessage}`);\n res.status(500).json({\n error: `Failed to cancel: ${errorMessage}`,\n });\n }\n },\n );\n\n // Screenshot API for real-time screenshot polling\n this._app.get('/screenshot', async (_req: Request, res: Response) => {\n try {\n // Check if page has screenshotBase64 method\n if (typeof this.agent.interface.screenshotBase64 !== 'function') {\n return res.status(500).json({\n error: 'Screenshot method not available on current interface',\n });\n }\n\n const base64Screenshot = await this.agent.interface.screenshotBase64();\n\n res.json({\n screenshot: base64Screenshot,\n timestamp: Date.now(),\n });\n } catch (error: unknown) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error';\n console.error(`Failed to take screenshot: ${errorMessage}`);\n res.status(500).json({\n error: `Failed to take screenshot: ${errorMessage}`,\n });\n }\n });\n\n // Interface info API for getting interface type and description\n this._app.get('/interface-info', async (_req: Request, res: Response) => {\n try {\n const type = this.agent.interface.interfaceType || 'Unknown';\n const description = this.agent.interface.describe?.() || undefined;\n\n res.json({\n type,\n description,\n });\n } catch (error: unknown) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error';\n console.error(`Failed to get interface info: ${errorMessage}`);\n res.status(500).json({\n error: `Failed to get interface info: ${errorMessage}`,\n });\n }\n });\n\n this.app.post('/config', async (req: Request, res: Response) => {\n const { aiConfig } = req.body;\n\n if (!aiConfig || typeof aiConfig !== 'object') {\n return res.status(400).json({\n error: 'aiConfig is required and must be an object',\n });\n }\n\n if (Object.keys(aiConfig).length === 0) {\n return res.json({\n status: 'ok',\n message: 'AI config not changed due to empty object',\n });\n }\n\n try {\n overrideAIConfig(aiConfig);\n\n return res.json({\n status: 'ok',\n message: 'AI config updated successfully',\n });\n } catch (error: unknown) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error';\n console.error(`Failed to update AI config: ${errorMessage}`);\n return res.status(500).json({\n error: `Failed to update AI config: ${errorMessage}`,\n });\n }\n });\n }\n\n /**\n * Setup static file serving routes\n */\n private setupStaticRoutes(): void {\n // Handle index.html with port injection\n this._app.get('/', (_req: Request, res: Response) => {\n this.serveHtmlWithPorts(res);\n });\n\n this._app.get('/index.html', (_req: Request, res: Response) => {\n this.serveHtmlWithPorts(res);\n });\n\n // Use express.static middleware for secure static file serving\n this._app.use(express.static(this.staticPath));\n\n // Fallback to index.html for SPA routing\n this._app.get('*', (_req: Request, res: Response) => {\n this.serveHtmlWithPorts(res);\n });\n }\n\n /**\n * Serve HTML with injected port configuration\n */\n private serveHtmlWithPorts(res: Response): void {\n try {\n const htmlPath = join(this.staticPath, 'index.html');\n let html = readFileSync(htmlPath, 'utf8');\n\n // Get scrcpy server port from global\n const scrcpyPort = (global as any).scrcpyServerPort || this.port! + 1;\n\n // Inject scrcpy port configuration script into HTML head\n const configScript = `\n <script>\n window.SCRCPY_PORT = ${scrcpyPort};\n </script>\n `;\n\n // Insert the script before closing </head> tag\n html = html.replace('</head>', `${configScript}</head>`);\n\n res.setHeader('Content-Type', 'text/html');\n res.send(html);\n } catch (error) {\n console.error('Error serving HTML with ports:', error);\n res.status(500).send('Internal Server Error');\n }\n }\n\n /**\n * Launch the server on specified port\n */\n async launch(port?: number): Promise<PlaygroundServer> {\n // If using factory mode, initialize agent\n if (this.agentFactory) {\n console.log('Initializing agent from factory function...');\n this.agent = await this.agentFactory();\n console.log('Agent initialized successfully');\n }\n\n // Initialize routes now, after any middleware has been added\n this.initializeApp();\n\n this.port = port || defaultPort;\n\n return new Promise((resolve) => {\n const serverPort = this.port;\n this.server = this._app.listen(serverPort, () => {\n resolve(this);\n });\n });\n }\n\n /**\n * Close the server and clean up resources\n */\n async close(): Promise<void> {\n return new Promise((resolve, reject) => {\n if (this.server) {\n // Clean up the single agent\n try {\n this.agent.destroy();\n } catch (error) {\n console.warn('Failed to destroy agent:', error);\n }\n this.taskProgressMessages = {};\n\n // Close the server\n this.server.close((error) => {\n if (error) {\n reject(error);\n } else {\n this.server = undefined;\n resolve();\n }\n });\n } else {\n resolve();\n }\n });\n }\n}\n\nexport default PlaygroundServer;\nexport { PlaygroundServer };\n"],"names":["defaultPort","PLAYGROUND_SERVER_PORT","__filename","fileURLToPath","__dirname","dirname","STATIC_PATH","join","errorHandler","err","req","res","next","console","errorMessage","Error","PlaygroundServer","express","_res","context","uuid","tmpFile","writeFileSync","error","contextFile","existsSync","readFileSync","requestId","progressMessages","lastMessage","undefined","tip","actionSpace","processedActionSpace","action","typedAction","processedSchema","e","actionName","type","prompt","params","deepThink","screenshotIncluded","domIncluded","deviceOptions","_dump","executionDump","task","index","typeStr","description","paramStr","taskStatus","status","Date","response","startTime","value","executeAction","formatErrorMessage","JSON","timeCost","_req","base64Screenshot","aiConfig","Object","overrideAIConfig","htmlPath","html","scrcpyPort","global","configScript","port","Promise","resolve","serverPort","reject","agent","staticPath","id","getTmpDir"],"mappings":"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"}
|
|
@@ -32,7 +32,7 @@ class BasePlaygroundAdapter {
|
|
|
32
32
|
return [];
|
|
33
33
|
}
|
|
34
34
|
validateParams(value, action) {
|
|
35
|
-
if (!
|
|
35
|
+
if (!action?.paramSchema) return {
|
|
36
36
|
valid: true
|
|
37
37
|
};
|
|
38
38
|
const needsStructuredParams = this.actionNeedsStructuredParams(action);
|
|
@@ -54,15 +54,15 @@ class BasePlaygroundAdapter {
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
createDisplayContent(value, needsStructuredParams, action) {
|
|
57
|
-
if (!needsStructuredParams || !value.params || !
|
|
57
|
+
if (!needsStructuredParams || !value.params || !action?.paramSchema) return value.prompt || '';
|
|
58
58
|
const paramsList = this.buildParamsDisplayList(value.params, action);
|
|
59
59
|
return paramsList.join('\n') || value.prompt || '';
|
|
60
60
|
}
|
|
61
61
|
formatBasicErrorMessage(error) {
|
|
62
|
-
return
|
|
62
|
+
return error?.message || 'Unknown error';
|
|
63
63
|
}
|
|
64
64
|
getSchemaKeys(action) {
|
|
65
|
-
if (!
|
|
65
|
+
if (!action?.paramSchema || !('shape' in action.paramSchema)) return [];
|
|
66
66
|
const schema = action.paramSchema;
|
|
67
67
|
return schema && 'shape' in schema ? Object.keys(schema.shape) : [];
|
|
68
68
|
}
|
|
@@ -155,9 +155,9 @@ class BasePlaygroundAdapter {
|
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
157
|
exports.BasePlaygroundAdapter = __webpack_exports__.BasePlaygroundAdapter;
|
|
158
|
-
for(var
|
|
158
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
159
159
|
"BasePlaygroundAdapter"
|
|
160
|
-
].indexOf(
|
|
160
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
161
161
|
Object.defineProperty(exports, '__esModule', {
|
|
162
162
|
value: true
|
|
163
163
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapters/base.js","sources":["webpack://@midscene/playground/webpack/runtime/define_property_getters","webpack://@midscene/playground/webpack/runtime/has_own_property","webpack://@midscene/playground/webpack/runtime/make_namespace_object","webpack://@midscene/playground/./src/adapters/base.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import type { DeviceAction } from '@midscene/core';\nimport { findAllMidsceneLocatorField } from '@midscene/core/ai-model';\nimport type { ExecutionOptions, FormValue, ValidationResult } from '../types';\n\nexport abstract class BasePlaygroundAdapter {\n abstract parseStructuredParams(\n action: DeviceAction<unknown>,\n params: Record<string, unknown>,\n options: ExecutionOptions,\n ): Promise<unknown[]>;\n\n abstract formatErrorMessage(error: any): string;\n\n // Abstract method for execution - must be implemented by concrete adapters\n abstract executeAction(\n actionType: string,\n value: FormValue,\n options: ExecutionOptions,\n ): Promise<unknown>;\n\n // Optional method for getting action space - default implementation returns empty array\n async getActionSpace(_context: any): Promise<DeviceAction<unknown>[]> {\n return [];\n }\n\n // Common validation logic - can be overridden if needed\n validateParams(\n value: FormValue,\n action: DeviceAction<unknown> | undefined,\n ): ValidationResult {\n if (!action?.paramSchema) {\n return { valid: true };\n }\n\n const needsStructuredParams = this.actionNeedsStructuredParams(action);\n\n if (!needsStructuredParams) {\n return { valid: true };\n }\n\n if (!value.params) {\n return { valid: false, errorMessage: 'Parameters are required' };\n }\n\n try {\n const paramsForValidation = this.prepareParamsForValidation(\n value.params,\n action,\n );\n action.paramSchema.parse(paramsForValidation);\n return { valid: true };\n } catch (error: unknown) {\n return this.handleValidationError(error);\n }\n }\n\n // Common display content creation logic - can be overridden if needed\n createDisplayContent(\n value: FormValue,\n needsStructuredParams: boolean,\n action: DeviceAction<unknown> | undefined,\n ): string {\n if (!needsStructuredParams || !value.params || !action?.paramSchema) {\n return value.prompt || '';\n }\n\n const paramsList = this.buildParamsDisplayList(value.params, action);\n return paramsList.join('\\n') || value.prompt || '';\n }\n\n // Helper method for basic error message formatting\n protected formatBasicErrorMessage(error: any): string {\n return error?.message || 'Unknown error';\n }\n\n // Helper method for parsing structured params base logic\n protected getSchemaKeys(action: DeviceAction<unknown>): string[] {\n if (!action?.paramSchema || !('shape' in action.paramSchema)) {\n return [];\n }\n\n const schema = action.paramSchema;\n return schema && 'shape' in schema\n ? Object.keys((schema as { shape: Record<string, unknown> }).shape)\n : [];\n }\n\n // Helper method for filtering valid params\n protected filterValidParams(\n params: Record<string, unknown>,\n excludeKeys: string[] = [],\n ): Record<string, unknown> {\n const filtered: Record<string, unknown> = {};\n\n Object.keys(params).forEach((key) => {\n if (\n !excludeKeys.includes(key) &&\n params[key] !== undefined &&\n params[key] !== null &&\n params[key] !== ''\n ) {\n filtered[key] = params[key];\n }\n });\n\n return filtered;\n }\n\n // Check if action needs structured parameters\n protected actionNeedsStructuredParams(\n action: DeviceAction<unknown>,\n ): boolean {\n if (\n typeof action.paramSchema === 'object' &&\n 'shape' in action.paramSchema\n ) {\n const shape =\n (action.paramSchema as { shape: Record<string, unknown> }).shape || {};\n return Object.keys(shape).length > 0;\n }\n return true; // If paramSchema exists but not in expected format, assume it needs params\n }\n\n // Prepare parameters for validation by converting string locate fields\n protected prepareParamsForValidation(\n params: Record<string, unknown>,\n action: DeviceAction<unknown>,\n ): Record<string, unknown> {\n const paramsForValidation = { ...params };\n\n if (action.paramSchema) {\n const locatorFieldKeys = findAllMidsceneLocatorField(action.paramSchema);\n locatorFieldKeys.forEach((key: string) => {\n if (typeof paramsForValidation[key] === 'string') {\n paramsForValidation[key] = {\n midscene_location_field_flag: true,\n prompt: paramsForValidation[key],\n center: [0, 0], // dummy values for validation\n rect: { left: 0, top: 0, width: 0, height: 0 },\n };\n }\n });\n }\n\n return paramsForValidation;\n }\n\n // Handle validation errors with proper error message extraction\n protected handleValidationError(error: unknown): ValidationResult {\n const zodError = error as {\n errors?: Array<{ path: string[]; message: string }>;\n };\n\n if (zodError.errors && zodError.errors.length > 0) {\n const errorMessages = zodError.errors\n .filter((err) => {\n const path = err.path.join('.');\n return (\n !path.includes('center') &&\n !path.includes('rect') &&\n !path.includes('midscene_location_field_flag')\n );\n })\n .map((err) => {\n const field = err.path.join('.');\n return `${field}: ${err.message}`;\n });\n\n if (errorMessages.length > 0) {\n return {\n valid: false,\n errorMessage: `Validation error: ${errorMessages.join(', ')}`,\n };\n }\n }\n\n const errorMsg =\n error instanceof Error ? error.message : 'Unknown validation error';\n\n return {\n valid: false,\n errorMessage: `Parameter validation failed: ${errorMsg}`,\n };\n }\n\n // Build display list for parameters\n protected buildParamsDisplayList(\n params: Record<string, unknown>,\n action: DeviceAction<unknown>,\n ): string[] {\n const paramsList: string[] = [];\n const schema = action.paramSchema;\n\n if (!(schema && 'shape' in schema)) {\n return paramsList;\n }\n\n const locatorFieldKeys = findAllMidsceneLocatorField(schema);\n const shapeKeys = Object.keys(\n (schema as { shape: Record<string, unknown> }).shape,\n );\n\n shapeKeys.forEach((key) => {\n const paramValue = params[key];\n if (this.isValidParamValue(paramValue)) {\n const displayKey = this.capitalizeFirstLetter(key);\n const formattedValue = this.formatParamValue(\n key,\n paramValue,\n locatorFieldKeys.includes(key),\n );\n paramsList.push(`${displayKey}: ${formattedValue}`);\n }\n });\n\n return paramsList;\n }\n\n // Check if parameter value is valid for display\n protected isValidParamValue(value: unknown): boolean {\n return value !== undefined && value !== null && value !== '';\n }\n\n // Capitalize first letter of a string\n protected capitalizeFirstLetter(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n }\n\n // Format parameter value for display\n protected formatParamValue(\n key: string,\n value: unknown,\n isLocateField: boolean,\n ): string {\n if (isLocateField || typeof value === 'string') {\n return `\"${value}\"`;\n }\n\n if (typeof value === 'number') {\n // Special handling for distance in scroll\n return key === 'distance' ? `${value}px` : `${value}`;\n }\n\n return `${value}`;\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","BasePlaygroundAdapter","_context","value","action","needsStructuredParams","paramsForValidation","error","paramsList","schema","params","excludeKeys","filtered","undefined","shape","locatorFieldKeys","findAllMidsceneLocatorField","zodError","errorMessages","err","path","field","errorMsg","Error","shapeKeys","paramValue","displayKey","formattedValue","str","isLocateField"],"mappings":";;;IAAAA,oBAAoB,CAAC,GAAG,CAAC,UAASC;QACjC,IAAI,IAAIC,OAAOD,WACR,IAAGD,oBAAoB,CAAC,CAACC,YAAYC,QAAQ,CAACF,oBAAoB,CAAC,CAAC,UAASE,MACzEC,OAAO,cAAc,CAAC,UAASD,KAAK;YAAE,YAAY;YAAM,KAAKD,UAAU,CAACC,IAAI;QAAC;IAGzF;;;ICNAF,oBAAoB,CAAC,GAAG,CAACI,KAAKC,OAAUF,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,CAACC,KAAKC;;;ICClFL,oBAAoB,CAAC,GAAG,CAAC;QACxB,IAAG,AAAkB,eAAlB,OAAOM,UAA0BA,OAAO,WAAW,EACrDH,OAAO,cAAc,CAAC,UAASG,OAAO,WAAW,EAAE;YAAE,OAAO;QAAS;QAEtEH,OAAO,cAAc,CAAC,UAAS,cAAc;YAAE,OAAO;QAAK;IAC5D;;;;;;;;ACFO,MAAeI;IAiBpB,MAAM,eAAeC,QAAa,EAAoC;QACpE,OAAO,EAAE;IACX;IAGA,eACEC,KAAgB,EAChBC,MAAyC,EACvB;QAClB,IAAI,CAACA,CAAAA,QAAAA,SAAAA,KAAAA,IAAAA,OAAQ,WAAW,AAAD,GACrB,OAAO;YAAE,OAAO;QAAK;QAGvB,MAAMC,wBAAwB,IAAI,CAAC,2BAA2B,CAACD;QAE/D,IAAI,CAACC,uBACH,OAAO;YAAE,OAAO;QAAK;QAGvB,IAAI,CAACF,MAAM,MAAM,EACf,OAAO;YAAE,OAAO;YAAO,cAAc;QAA0B;QAGjE,IAAI;YACF,MAAMG,sBAAsB,IAAI,CAAC,0BAA0B,CACzDH,MAAM,MAAM,EACZC;YAEFA,OAAO,WAAW,CAAC,KAAK,CAACE;YACzB,OAAO;gBAAE,OAAO;YAAK;QACvB,EAAE,OAAOC,OAAgB;YACvB,OAAO,IAAI,CAAC,qBAAqB,CAACA;QACpC;IACF;IAGA,qBACEJ,KAAgB,EAChBE,qBAA8B,EAC9BD,MAAyC,EACjC;QACR,IAAI,CAACC,yBAAyB,CAACF,MAAM,MAAM,IAAI,CAACC,CAAAA,QAAAA,SAAAA,KAAAA,IAAAA,OAAQ,WAAW,AAAD,GAChE,OAAOD,MAAM,MAAM,IAAI;QAGzB,MAAMK,aAAa,IAAI,CAAC,sBAAsB,CAACL,MAAM,MAAM,EAAEC;QAC7D,OAAOI,WAAW,IAAI,CAAC,SAASL,MAAM,MAAM,IAAI;IAClD;IAGU,wBAAwBI,KAAU,EAAU;QACpD,OAAOA,AAAAA,CAAAA,QAAAA,QAAAA,KAAAA,IAAAA,MAAO,OAAO,AAAD,KAAK;IAC3B;IAGU,cAAcH,MAA6B,EAAY;QAC/D,IAAI,CAACA,CAAAA,QAAAA,SAAAA,KAAAA,IAAAA,OAAQ,WAAW,AAAD,KAAK,CAAE,YAAWA,OAAO,WAAU,GACxD,OAAO,EAAE;QAGX,MAAMK,SAASL,OAAO,WAAW;QACjC,OAAOK,UAAU,WAAWA,SACxBZ,OAAO,IAAI,CAAEY,OAA8C,KAAK,IAChE,EAAE;IACR;IAGU,kBACRC,MAA+B,EAC/BC,cAAwB,EAAE,EACD;QACzB,MAAMC,WAAoC,CAAC;QAE3Cf,OAAO,IAAI,CAACa,QAAQ,OAAO,CAAC,CAACd;YAC3B,IACE,CAACe,YAAY,QAAQ,CAACf,QACtBc,AAAgBG,WAAhBH,MAAM,CAACd,IAAI,IACXc,AAAgB,SAAhBA,MAAM,CAACd,IAAI,IACXc,AAAgB,OAAhBA,MAAM,CAACd,IAAI,EAEXgB,QAAQ,CAAChB,IAAI,GAAGc,MAAM,CAACd,IAAI;QAE/B;QAEA,OAAOgB;IACT;IAGU,4BACRR,MAA6B,EACpB;QACT,IACE,AAA8B,YAA9B,OAAOA,OAAO,WAAW,IACzB,WAAWA,OAAO,WAAW,EAC7B;YACA,MAAMU,QACHV,OAAO,WAAW,CAAwC,KAAK,IAAI,CAAC;YACvE,OAAOP,OAAO,IAAI,CAACiB,OAAO,MAAM,GAAG;QACrC;QACA,OAAO;IACT;IAGU,2BACRJ,MAA+B,EAC/BN,MAA6B,EACJ;QACzB,MAAME,sBAAsB;YAAE,GAAGI,MAAM;QAAC;QAExC,IAAIN,OAAO,WAAW,EAAE;YACtB,MAAMW,mBAAmBC,AAAAA,IAAAA,yBAAAA,2BAAAA,AAAAA,EAA4BZ,OAAO,WAAW;YACvEW,iBAAiB,OAAO,CAAC,CAACnB;gBACxB,IAAI,AAAoC,YAApC,OAAOU,mBAAmB,CAACV,IAAI,EACjCU,mBAAmB,CAACV,IAAI,GAAG;oBACzB,8BAA8B;oBAC9B,QAAQU,mBAAmB,CAACV,IAAI;oBAChC,QAAQ;wBAAC;wBAAG;qBAAE;oBACd,MAAM;wBAAE,MAAM;wBAAG,KAAK;wBAAG,OAAO;wBAAG,QAAQ;oBAAE;gBAC/C;YAEJ;QACF;QAEA,OAAOU;IACT;IAGU,sBAAsBC,KAAc,EAAoB;QAChE,MAAMU,WAAWV;QAIjB,IAAIU,SAAS,MAAM,IAAIA,SAAS,MAAM,CAAC,MAAM,GAAG,GAAG;YACjD,MAAMC,gBAAgBD,SAAS,MAAM,CAClC,MAAM,CAAC,CAACE;gBACP,MAAMC,OAAOD,IAAI,IAAI,CAAC,IAAI,CAAC;gBAC3B,OACE,CAACC,KAAK,QAAQ,CAAC,aACf,CAACA,KAAK,QAAQ,CAAC,WACf,CAACA,KAAK,QAAQ,CAAC;YAEnB,GACC,GAAG,CAAC,CAACD;gBACJ,MAAME,QAAQF,IAAI,IAAI,CAAC,IAAI,CAAC;gBAC5B,OAAO,GAAGE,MAAM,EAAE,EAAEF,IAAI,OAAO,EAAE;YACnC;YAEF,IAAID,cAAc,MAAM,GAAG,GACzB,OAAO;gBACL,OAAO;gBACP,cAAc,CAAC,kBAAkB,EAAEA,cAAc,IAAI,CAAC,OAAO;YAC/D;QAEJ;QAEA,MAAMI,WACJf,iBAAiBgB,QAAQhB,MAAM,OAAO,GAAG;QAE3C,OAAO;YACL,OAAO;YACP,cAAc,CAAC,6BAA6B,EAAEe,UAAU;QAC1D;IACF;IAGU,uBACRZ,MAA+B,EAC/BN,MAA6B,EACnB;QACV,MAAMI,aAAuB,EAAE;QAC/B,MAAMC,SAASL,OAAO,WAAW;QAEjC,IAAI,CAAEK,CAAAA,UAAU,WAAWA,MAAK,GAC9B,OAAOD;QAGT,MAAMO,mBAAmBC,AAAAA,IAAAA,yBAAAA,2BAAAA,AAAAA,EAA4BP;QACrD,MAAMe,YAAY3B,OAAO,IAAI,CAC1BY,OAA8C,KAAK;QAGtDe,UAAU,OAAO,CAAC,CAAC5B;YACjB,MAAM6B,aAAaf,MAAM,CAACd,IAAI;YAC9B,IAAI,IAAI,CAAC,iBAAiB,CAAC6B,aAAa;gBACtC,MAAMC,aAAa,IAAI,CAAC,qBAAqB,CAAC9B;gBAC9C,MAAM+B,iBAAiB,IAAI,CAAC,gBAAgB,CAC1C/B,KACA6B,YACAV,iBAAiB,QAAQ,CAACnB;gBAE5BY,WAAW,IAAI,CAAC,GAAGkB,WAAW,EAAE,EAAEC,gBAAgB;YACpD;QACF;QAEA,OAAOnB;IACT;IAGU,kBAAkBL,KAAc,EAAW;QACnD,OAAOA,QAAAA,SAAyCA,AAAU,OAAVA;IAClD;IAGU,sBAAsByB,GAAW,EAAU;QACnD,OAAOA,IAAI,MAAM,CAAC,GAAG,WAAW,KAAKA,IAAI,KAAK,CAAC;IACjD;IAGU,iBACRhC,GAAW,EACXO,KAAc,EACd0B,aAAsB,EACd;QACR,IAAIA,iBAAiB,AAAiB,YAAjB,OAAO1B,OAC1B,OAAO,CAAC,CAAC,EAAEA,MAAM,CAAC,CAAC;QAGrB,IAAI,AAAiB,YAAjB,OAAOA,OAET,OAAOP,AAAQ,eAARA,MAAqB,GAAGO,MAAM,EAAE,CAAC,GAAG,GAAGA,OAAO;QAGvD,OAAO,GAAGA,OAAO;IACnB;AACF"}
|
|
1
|
+
{"version":3,"file":"adapters/base.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/adapters/base.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import type { DeviceAction } from '@midscene/core';\nimport { findAllMidsceneLocatorField } from '@midscene/core/ai-model';\nimport type { ExecutionOptions, FormValue, ValidationResult } from '../types';\n\nexport abstract class BasePlaygroundAdapter {\n abstract parseStructuredParams(\n action: DeviceAction<unknown>,\n params: Record<string, unknown>,\n options: ExecutionOptions,\n ): Promise<unknown[]>;\n\n abstract formatErrorMessage(error: any): string;\n\n // Abstract method for execution - must be implemented by concrete adapters\n abstract executeAction(\n actionType: string,\n value: FormValue,\n options: ExecutionOptions,\n ): Promise<unknown>;\n\n // Optional method for getting action space - default implementation returns empty array\n async getActionSpace(_context: any): Promise<DeviceAction<unknown>[]> {\n return [];\n }\n\n // Common validation logic - can be overridden if needed\n validateParams(\n value: FormValue,\n action: DeviceAction<unknown> | undefined,\n ): ValidationResult {\n if (!action?.paramSchema) {\n return { valid: true };\n }\n\n const needsStructuredParams = this.actionNeedsStructuredParams(action);\n\n if (!needsStructuredParams) {\n return { valid: true };\n }\n\n if (!value.params) {\n return { valid: false, errorMessage: 'Parameters are required' };\n }\n\n try {\n const paramsForValidation = this.prepareParamsForValidation(\n value.params,\n action,\n );\n action.paramSchema.parse(paramsForValidation);\n return { valid: true };\n } catch (error: unknown) {\n return this.handleValidationError(error);\n }\n }\n\n // Common display content creation logic - can be overridden if needed\n createDisplayContent(\n value: FormValue,\n needsStructuredParams: boolean,\n action: DeviceAction<unknown> | undefined,\n ): string {\n if (!needsStructuredParams || !value.params || !action?.paramSchema) {\n return value.prompt || '';\n }\n\n const paramsList = this.buildParamsDisplayList(value.params, action);\n return paramsList.join('\\n') || value.prompt || '';\n }\n\n // Helper method for basic error message formatting\n protected formatBasicErrorMessage(error: any): string {\n return error?.message || 'Unknown error';\n }\n\n // Helper method for parsing structured params base logic\n protected getSchemaKeys(action: DeviceAction<unknown>): string[] {\n if (!action?.paramSchema || !('shape' in action.paramSchema)) {\n return [];\n }\n\n const schema = action.paramSchema;\n return schema && 'shape' in schema\n ? Object.keys((schema as { shape: Record<string, unknown> }).shape)\n : [];\n }\n\n // Helper method for filtering valid params\n protected filterValidParams(\n params: Record<string, unknown>,\n excludeKeys: string[] = [],\n ): Record<string, unknown> {\n const filtered: Record<string, unknown> = {};\n\n Object.keys(params).forEach((key) => {\n if (\n !excludeKeys.includes(key) &&\n params[key] !== undefined &&\n params[key] !== null &&\n params[key] !== ''\n ) {\n filtered[key] = params[key];\n }\n });\n\n return filtered;\n }\n\n // Check if action needs structured parameters\n protected actionNeedsStructuredParams(\n action: DeviceAction<unknown>,\n ): boolean {\n if (\n typeof action.paramSchema === 'object' &&\n 'shape' in action.paramSchema\n ) {\n const shape =\n (action.paramSchema as { shape: Record<string, unknown> }).shape || {};\n return Object.keys(shape).length > 0;\n }\n return true; // If paramSchema exists but not in expected format, assume it needs params\n }\n\n // Prepare parameters for validation by converting string locate fields\n protected prepareParamsForValidation(\n params: Record<string, unknown>,\n action: DeviceAction<unknown>,\n ): Record<string, unknown> {\n const paramsForValidation = { ...params };\n\n if (action.paramSchema) {\n const locatorFieldKeys = findAllMidsceneLocatorField(action.paramSchema);\n locatorFieldKeys.forEach((key: string) => {\n if (typeof paramsForValidation[key] === 'string') {\n paramsForValidation[key] = {\n midscene_location_field_flag: true,\n prompt: paramsForValidation[key],\n center: [0, 0], // dummy values for validation\n rect: { left: 0, top: 0, width: 0, height: 0 },\n };\n }\n });\n }\n\n return paramsForValidation;\n }\n\n // Handle validation errors with proper error message extraction\n protected handleValidationError(error: unknown): ValidationResult {\n const zodError = error as {\n errors?: Array<{ path: string[]; message: string }>;\n };\n\n if (zodError.errors && zodError.errors.length > 0) {\n const errorMessages = zodError.errors\n .filter((err) => {\n const path = err.path.join('.');\n return (\n !path.includes('center') &&\n !path.includes('rect') &&\n !path.includes('midscene_location_field_flag')\n );\n })\n .map((err) => {\n const field = err.path.join('.');\n return `${field}: ${err.message}`;\n });\n\n if (errorMessages.length > 0) {\n return {\n valid: false,\n errorMessage: `Validation error: ${errorMessages.join(', ')}`,\n };\n }\n }\n\n const errorMsg =\n error instanceof Error ? error.message : 'Unknown validation error';\n\n return {\n valid: false,\n errorMessage: `Parameter validation failed: ${errorMsg}`,\n };\n }\n\n // Build display list for parameters\n protected buildParamsDisplayList(\n params: Record<string, unknown>,\n action: DeviceAction<unknown>,\n ): string[] {\n const paramsList: string[] = [];\n const schema = action.paramSchema;\n\n if (!(schema && 'shape' in schema)) {\n return paramsList;\n }\n\n const locatorFieldKeys = findAllMidsceneLocatorField(schema);\n const shapeKeys = Object.keys(\n (schema as { shape: Record<string, unknown> }).shape,\n );\n\n shapeKeys.forEach((key) => {\n const paramValue = params[key];\n if (this.isValidParamValue(paramValue)) {\n const displayKey = this.capitalizeFirstLetter(key);\n const formattedValue = this.formatParamValue(\n key,\n paramValue,\n locatorFieldKeys.includes(key),\n );\n paramsList.push(`${displayKey}: ${formattedValue}`);\n }\n });\n\n return paramsList;\n }\n\n // Check if parameter value is valid for display\n protected isValidParamValue(value: unknown): boolean {\n return value !== undefined && value !== null && value !== '';\n }\n\n // Capitalize first letter of a string\n protected capitalizeFirstLetter(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n }\n\n // Format parameter value for display\n protected formatParamValue(\n key: string,\n value: unknown,\n isLocateField: boolean,\n ): string {\n if (isLocateField || typeof value === 'string') {\n return `\"${value}\"`;\n }\n\n if (typeof value === 'number') {\n // Special handling for distance in scroll\n return key === 'distance' ? `${value}px` : `${value}`;\n }\n\n return `${value}`;\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","BasePlaygroundAdapter","_context","value","action","needsStructuredParams","paramsForValidation","error","paramsList","schema","params","excludeKeys","filtered","undefined","shape","locatorFieldKeys","findAllMidsceneLocatorField","zodError","errorMessages","err","path","field","errorMsg","Error","shapeKeys","paramValue","displayKey","formattedValue","str","isLocateField"],"mappings":"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"}
|
|
@@ -44,31 +44,31 @@ class LocalExecutionAdapter extends external_base_js_namespaceObject.BasePlaygro
|
|
|
44
44
|
get id() {
|
|
45
45
|
return this._id;
|
|
46
46
|
}
|
|
47
|
+
onDumpUpdate(callback) {
|
|
48
|
+
this.dumpUpdateCallback = void 0;
|
|
49
|
+
this.dumpUpdateCallback = callback;
|
|
50
|
+
}
|
|
47
51
|
setProgressCallback(callback) {
|
|
48
52
|
this.progressCallback = void 0;
|
|
49
53
|
this.progressCallback = callback;
|
|
50
54
|
}
|
|
51
|
-
cleanup(requestId) {
|
|
52
|
-
delete this.taskProgressTips[requestId];
|
|
53
|
-
}
|
|
54
55
|
async parseStructuredParams(action, params, options) {
|
|
55
56
|
return await (0, external_common_js_namespaceObject.parseStructuredParams)(action, params, options);
|
|
56
57
|
}
|
|
57
58
|
formatErrorMessage(error) {
|
|
58
|
-
const errorMessage =
|
|
59
|
+
const errorMessage = error?.message || '';
|
|
59
60
|
if (errorMessage.includes('of different extension')) return 'Conflicting extension detected. Please disable the suspicious plugins and refresh the page. Guide: https://midscenejs.com/quick-experience.html#faq';
|
|
60
61
|
return this.formatBasicErrorMessage(error);
|
|
61
62
|
}
|
|
62
63
|
async getActionSpace(context) {
|
|
63
|
-
|
|
64
|
-
if (null == (_this_agent = this.agent) ? void 0 : _this_agent.getActionSpace) return await this.agent.getActionSpace();
|
|
64
|
+
if (this.agent?.getActionSpace) return await this.agent.getActionSpace();
|
|
65
65
|
if (this.agent && 'interface' in this.agent && 'object' == typeof this.agent.interface) {
|
|
66
66
|
const page = this.agent.interface;
|
|
67
|
-
if (
|
|
67
|
+
if (page?.actionSpace) return page.actionSpace();
|
|
68
68
|
}
|
|
69
69
|
if (context && 'object' == typeof context && 'actionSpace' in context) {
|
|
70
70
|
const contextPage = context;
|
|
71
|
-
return
|
|
71
|
+
return contextPage.actionSpace();
|
|
72
72
|
}
|
|
73
73
|
return [];
|
|
74
74
|
}
|
|
@@ -78,58 +78,67 @@ class LocalExecutionAdapter extends external_base_js_namespaceObject.BasePlaygro
|
|
|
78
78
|
async overrideConfig(aiConfig) {
|
|
79
79
|
(0, env_namespaceObject.overrideAIConfig)(aiConfig);
|
|
80
80
|
}
|
|
81
|
+
async detachDebuggerSafely() {
|
|
82
|
+
try {
|
|
83
|
+
const page = this.agent?.interface;
|
|
84
|
+
await page?.detachDebugger?.();
|
|
85
|
+
} catch (error) {
|
|
86
|
+
console.warn('Failed to detach debugger:', error);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
81
89
|
async executeAction(actionType, value, options) {
|
|
82
90
|
const actionSpace = await this.getActionSpace();
|
|
83
|
-
let
|
|
91
|
+
let removeListener;
|
|
92
|
+
try {
|
|
93
|
+
this.agent.resetDump?.();
|
|
94
|
+
} catch (error) {
|
|
95
|
+
console.warn('Failed to reset dump before execution:', error);
|
|
96
|
+
}
|
|
84
97
|
if (options.requestId && this.agent) {
|
|
85
98
|
this.currentRequestId = options.requestId;
|
|
86
|
-
|
|
87
|
-
this.agent.onTaskStartTip = (tip)=>{
|
|
99
|
+
removeListener = this.agent.addDumpUpdateListener((dump, executionDump)=>{
|
|
88
100
|
if (this.currentRequestId !== options.requestId) return;
|
|
89
|
-
this.
|
|
90
|
-
|
|
91
|
-
if ('function' == typeof originalOnTaskStartTip) originalOnTaskStartTip(tip);
|
|
92
|
-
};
|
|
101
|
+
if (this.dumpUpdateCallback) this.dumpUpdateCallback(dump, executionDump);
|
|
102
|
+
});
|
|
93
103
|
}
|
|
94
104
|
try {
|
|
95
|
-
|
|
105
|
+
let result = null;
|
|
106
|
+
let executionError = null;
|
|
107
|
+
try {
|
|
108
|
+
result = await (0, external_common_js_namespaceObject.executeAction)(this.agent, actionType, actionSpace, value, options);
|
|
109
|
+
} catch (error) {
|
|
110
|
+
executionError = error;
|
|
111
|
+
}
|
|
96
112
|
const response = {
|
|
97
113
|
result,
|
|
98
114
|
dump: null,
|
|
99
115
|
reportHTML: null,
|
|
100
|
-
error: null
|
|
116
|
+
error: executionError ? executionError instanceof Error ? executionError.message : String(executionError) : null
|
|
101
117
|
};
|
|
102
118
|
try {
|
|
103
119
|
if (this.agent.dumpDataString) {
|
|
104
120
|
const dumpString = this.agent.dumpDataString();
|
|
105
|
-
if (dumpString)
|
|
121
|
+
if (dumpString) {
|
|
122
|
+
const groupedDump = JSON.parse(dumpString);
|
|
123
|
+
response.dump = groupedDump.executions?.[0] || null;
|
|
124
|
+
}
|
|
106
125
|
}
|
|
107
126
|
if (this.agent.reportHTMLString) response.reportHTML = this.agent.reportHTMLString() || null;
|
|
108
127
|
if (this.agent.writeOutActionDumps) this.agent.writeOutActionDumps();
|
|
109
128
|
} catch (error) {
|
|
110
129
|
console.error('Failed to get dump/reportHTML from agent:', error);
|
|
111
130
|
}
|
|
112
|
-
this.agent.resetDump();
|
|
113
131
|
return response;
|
|
114
132
|
} finally{
|
|
115
|
-
if (
|
|
116
|
-
this.cleanup(options.requestId);
|
|
117
|
-
if (this.agent) this.agent.onTaskStartTip = originalOnTaskStartTip;
|
|
118
|
-
}
|
|
133
|
+
if (removeListener) removeListener();
|
|
119
134
|
}
|
|
120
135
|
}
|
|
121
|
-
async getTaskProgress(requestId) {
|
|
122
|
-
return {
|
|
123
|
-
tip: this.taskProgressTips[requestId] || void 0
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
136
|
async cancelTask(_requestId) {
|
|
127
137
|
if (!this.agent) return {
|
|
128
138
|
error: 'No active agent found for this requestId'
|
|
129
139
|
};
|
|
130
140
|
try {
|
|
131
|
-
|
|
132
|
-
await (null == (_this_agent_destroy = (_this_agent = this.agent).destroy) ? void 0 : _this_agent_destroy.call(_this_agent));
|
|
141
|
+
await this.agent.destroy?.();
|
|
133
142
|
return {
|
|
134
143
|
success: true
|
|
135
144
|
};
|
|
@@ -141,13 +150,30 @@ class LocalExecutionAdapter extends external_base_js_namespaceObject.BasePlaygro
|
|
|
141
150
|
};
|
|
142
151
|
}
|
|
143
152
|
}
|
|
153
|
+
async getCurrentExecutionData() {
|
|
154
|
+
const response = {
|
|
155
|
+
dump: null,
|
|
156
|
+
reportHTML: null
|
|
157
|
+
};
|
|
158
|
+
try {
|
|
159
|
+
if (this.agent.dumpDataString) {
|
|
160
|
+
const dumpString = this.agent.dumpDataString();
|
|
161
|
+
if (dumpString) {
|
|
162
|
+
const groupedDump = JSON.parse(dumpString);
|
|
163
|
+
response.dump = groupedDump.executions?.[0] || null;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (this.agent.reportHTMLString) response.reportHTML = this.agent.reportHTMLString() || null;
|
|
167
|
+
} catch (error) {
|
|
168
|
+
console.error('Failed to get current execution data:', error);
|
|
169
|
+
}
|
|
170
|
+
return response;
|
|
171
|
+
}
|
|
144
172
|
async getInterfaceInfo() {
|
|
145
|
-
|
|
146
|
-
if (!(null == (_this_agent = this.agent) ? void 0 : _this_agent.interface)) return null;
|
|
173
|
+
if (!this.agent?.interface) return null;
|
|
147
174
|
try {
|
|
148
|
-
var _this_agent_interface_describe, _this_agent_interface;
|
|
149
175
|
const type = this.agent.interface.interfaceType || 'Unknown';
|
|
150
|
-
const description =
|
|
176
|
+
const description = this.agent.interface.describe?.() || void 0;
|
|
151
177
|
return {
|
|
152
178
|
type,
|
|
153
179
|
description
|
|
@@ -158,15 +184,15 @@ class LocalExecutionAdapter extends external_base_js_namespaceObject.BasePlaygro
|
|
|
158
184
|
}
|
|
159
185
|
}
|
|
160
186
|
constructor(agent){
|
|
161
|
-
super(), _define_property(this, "agent", void 0), _define_property(this, "
|
|
187
|
+
super(), _define_property(this, "agent", void 0), _define_property(this, "dumpUpdateCallback", void 0), _define_property(this, "progressCallback", void 0), _define_property(this, "_id", void 0), _define_property(this, "currentRequestId", void 0);
|
|
162
188
|
this.agent = agent;
|
|
163
189
|
this._id = (0, utils_namespaceObject.uuid)();
|
|
164
190
|
}
|
|
165
191
|
}
|
|
166
192
|
exports.LocalExecutionAdapter = __webpack_exports__.LocalExecutionAdapter;
|
|
167
|
-
for(var
|
|
193
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
168
194
|
"LocalExecutionAdapter"
|
|
169
|
-
].indexOf(
|
|
195
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
170
196
|
Object.defineProperty(exports, '__esModule', {
|
|
171
197
|
value: true
|
|
172
198
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapters/local-execution.js","sources":["webpack://@midscene/playground/webpack/runtime/define_property_getters","webpack://@midscene/playground/webpack/runtime/has_own_property","webpack://@midscene/playground/webpack/runtime/make_namespace_object","webpack://@midscene/playground/./src/adapters/local-execution.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import type { DeviceAction } from '@midscene/core';\nimport { overrideAIConfig } from '@midscene/shared/env';\nimport { uuid } from '@midscene/shared/utils';\nimport { executeAction, parseStructuredParams } from '../common';\nimport type { ExecutionOptions, FormValue, PlaygroundAgent } from '../types';\nimport { BasePlaygroundAdapter } from './base';\n\nexport class LocalExecutionAdapter extends BasePlaygroundAdapter {\n private agent: PlaygroundAgent;\n private taskProgressTips: Record<string, string> = {};\n private progressCallback?: (tip: string) => void;\n private readonly _id: string; // Unique identifier for this local adapter instance\n private currentRequestId?: string; // Track current request to prevent stale callbacks\n\n constructor(agent: PlaygroundAgent) {\n super();\n this.agent = agent;\n this._id = uuid(); // Generate unique ID for local adapter\n }\n\n // Get adapter ID\n get id(): string {\n return this._id;\n }\n\n setProgressCallback(callback: (tip: string) => void): void {\n // Clear any existing callback before setting new one\n this.progressCallback = undefined;\n // Set the new callback\n this.progressCallback = callback;\n }\n\n private cleanup(requestId: string): void {\n delete this.taskProgressTips[requestId];\n }\n\n async parseStructuredParams(\n action: DeviceAction<unknown>,\n params: Record<string, unknown>,\n options: ExecutionOptions,\n ): Promise<unknown[]> {\n // Use shared implementation from common.ts\n return await parseStructuredParams(action, params, options);\n }\n\n formatErrorMessage(error: any): string {\n const errorMessage = error?.message || '';\n if (errorMessage.includes('of different extension')) {\n return 'Conflicting extension detected. Please disable the suspicious plugins and refresh the page. Guide: https://midscenejs.com/quick-experience.html#faq';\n }\n return this.formatBasicErrorMessage(error);\n }\n\n // Local execution - use base implementation\n // (inherits default executeAction from BasePlaygroundAdapter)\n\n // Local execution gets actionSpace from internal agent (parameter is for backward compatibility)\n async getActionSpace(context?: unknown): Promise<DeviceAction<unknown>[]> {\n // Priority 1: Use agent's getActionSpace method\n if (this.agent?.getActionSpace) {\n return await this.agent.getActionSpace();\n }\n\n // Priority 2: Use agent's interface.actionSpace method\n if (\n this.agent &&\n 'interface' in this.agent &&\n typeof this.agent.interface === 'object'\n ) {\n const page = this.agent.interface as {\n actionSpace?: () => Promise<DeviceAction<unknown>[]>;\n };\n if (page?.actionSpace) {\n return await page.actionSpace();\n }\n }\n\n // Priority 3: Fallback to context parameter (for backward compatibility with tests)\n if (context && typeof context === 'object' && 'actionSpace' in context) {\n const contextPage = context as {\n actionSpace: () => Promise<DeviceAction<unknown>[]>;\n };\n return await contextPage.actionSpace();\n }\n\n return [];\n }\n\n // Local execution doesn't use a server, so always return true\n async checkStatus(): Promise<boolean> {\n return true;\n }\n\n async overrideConfig(aiConfig: Record<string, unknown>): Promise<void> {\n // For local execution, use the shared env override function\n overrideAIConfig(aiConfig);\n }\n\n async executeAction(\n actionType: string,\n value: FormValue,\n options: ExecutionOptions,\n ): Promise<unknown> {\n // Get actionSpace using our simplified getActionSpace method\n const actionSpace = await this.getActionSpace();\n let originalOnTaskStartTip: ((tip: string) => void) | undefined;\n\n // Setup progress tracking if requestId is provided\n if (options.requestId && this.agent) {\n // Track current request ID to prevent stale callbacks\n this.currentRequestId = options.requestId;\n originalOnTaskStartTip = this.agent.onTaskStartTip;\n\n // Set up a fresh callback\n this.agent.onTaskStartTip = (tip: string) => {\n // Only process if this is still the current request\n if (this.currentRequestId !== options.requestId) {\n return;\n }\n\n // Store tip for our progress tracking\n this.taskProgressTips[options.requestId!] = tip;\n\n // Call the direct progress callback set via setProgressCallback\n if (this.progressCallback) {\n this.progressCallback(tip);\n }\n\n if (typeof originalOnTaskStartTip === 'function') {\n originalOnTaskStartTip(tip);\n }\n };\n }\n\n try {\n // Call the base implementation with the original signature\n const result = await executeAction(\n this.agent,\n actionType,\n actionSpace,\n value,\n options,\n );\n\n // For local execution, we need to package the result with dump and reportHTML\n // similar to how the server does it\n const response = {\n result,\n dump: null as unknown,\n reportHTML: null as string | null,\n error: null as string | null,\n };\n\n try {\n // Get dump and reportHTML from agent like the server does\n if (this.agent.dumpDataString) {\n const dumpString = this.agent.dumpDataString();\n if (dumpString) {\n response.dump = JSON.parse(dumpString);\n }\n }\n\n if (this.agent.reportHTMLString) {\n response.reportHTML = this.agent.reportHTMLString() || null;\n }\n\n // Write out action dumps\n if (this.agent.writeOutActionDumps) {\n this.agent.writeOutActionDumps();\n }\n } catch (error: unknown) {\n console.error('Failed to get dump/reportHTML from agent:', error);\n }\n\n this.agent.resetDump();\n\n return response;\n } finally {\n // Always clean up progress tracking to prevent memory leaks\n if (options.requestId) {\n this.cleanup(options.requestId);\n // Clear the agent callback to prevent accumulation\n if (this.agent) {\n this.agent.onTaskStartTip = originalOnTaskStartTip;\n }\n }\n }\n }\n\n async getTaskProgress(requestId: string): Promise<{ tip?: string }> {\n // Return the stored tip for this requestId\n return { tip: this.taskProgressTips[requestId] || undefined };\n }\n\n // Local execution task cancellation - minimal implementation\n async cancelTask(\n _requestId: string,\n ): Promise<{ error?: string; success?: boolean }> {\n if (!this.agent) {\n return { error: 'No active agent found for this requestId' };\n }\n\n try {\n await this.agent.destroy?.();\n return { success: true };\n } catch (error: unknown) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error';\n console.error(`Failed to cancel agent: ${errorMessage}`);\n return { error: `Failed to cancel: ${errorMessage}` };\n }\n }\n\n // Get interface information from the agent\n async getInterfaceInfo(): Promise<{\n type: string;\n description?: string;\n } | null> {\n if (!this.agent?.interface) {\n return null;\n }\n\n try {\n const type = this.agent.interface.interfaceType || 'Unknown';\n const description = this.agent.interface.describe?.() || undefined;\n\n return {\n type,\n description,\n };\n } catch (error: unknown) {\n console.error('Failed to get interface info:', error);\n return null;\n }\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","LocalExecutionAdapter","BasePlaygroundAdapter","callback","undefined","requestId","action","params","options","parseStructuredParams","error","errorMessage","context","_this_agent","page","contextPage","aiConfig","overrideAIConfig","actionType","value","actionSpace","originalOnTaskStartTip","tip","result","executeAction","response","dumpString","JSON","console","_requestId","Error","_this_agent_interface","type","description","agent","uuid"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"adapters/local-execution.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/adapters/local-execution.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import type { DeviceAction, ExecutionDump } from '@midscene/core';\nimport { overrideAIConfig } from '@midscene/shared/env';\nimport { uuid } from '@midscene/shared/utils';\nimport { executeAction, parseStructuredParams } from '../common';\nimport type { ExecutionOptions, FormValue, PlaygroundAgent } from '../types';\nimport { BasePlaygroundAdapter } from './base';\n\nexport class LocalExecutionAdapter extends BasePlaygroundAdapter {\n private agent: PlaygroundAgent;\n private dumpUpdateCallback?: (\n dump: string,\n executionDump?: ExecutionDump,\n ) => void;\n private progressCallback?: (tip: string) => void;\n private readonly _id: string; // Unique identifier for this local adapter instance\n private currentRequestId?: string; // Track current request to prevent stale callbacks\n\n constructor(agent: PlaygroundAgent) {\n super();\n this.agent = agent;\n this._id = uuid(); // Generate unique ID for local adapter\n }\n\n // Get adapter ID\n get id(): string {\n return this._id;\n }\n\n onDumpUpdate(\n callback: (dump: string, executionDump?: ExecutionDump) => void,\n ): void {\n // Clear any existing callback before setting new one\n this.dumpUpdateCallback = undefined;\n // Set the new callback\n this.dumpUpdateCallback = callback;\n }\n\n // Set progress callback for monitoring operation status\n setProgressCallback(callback: (tip: string) => void): void {\n this.progressCallback = undefined;\n this.progressCallback = callback;\n }\n\n async parseStructuredParams(\n action: DeviceAction<unknown>,\n params: Record<string, unknown>,\n options: ExecutionOptions,\n ): Promise<unknown[]> {\n // Use shared implementation from common.ts\n return await parseStructuredParams(action, params, options);\n }\n\n formatErrorMessage(error: any): string {\n const errorMessage = error?.message || '';\n if (errorMessage.includes('of different extension')) {\n return 'Conflicting extension detected. Please disable the suspicious plugins and refresh the page. Guide: https://midscenejs.com/quick-experience.html#faq';\n }\n return this.formatBasicErrorMessage(error);\n }\n\n // Local execution - use base implementation\n // (inherits default executeAction from BasePlaygroundAdapter)\n\n // Local execution gets actionSpace from internal agent (parameter is for backward compatibility)\n async getActionSpace(context?: unknown): Promise<DeviceAction<unknown>[]> {\n // Priority 1: Use agent's getActionSpace method\n if (this.agent?.getActionSpace) {\n return await this.agent.getActionSpace();\n }\n\n // Priority 2: Use agent's interface.actionSpace method\n if (\n this.agent &&\n 'interface' in this.agent &&\n typeof this.agent.interface === 'object'\n ) {\n const page = this.agent.interface as {\n actionSpace?: () => DeviceAction<unknown>[];\n };\n if (page?.actionSpace) {\n return page.actionSpace();\n }\n }\n\n // Priority 3: Fallback to context parameter (for backward compatibility with tests)\n if (context && typeof context === 'object' && 'actionSpace' in context) {\n const contextPage = context as {\n actionSpace: () => DeviceAction<unknown>[];\n };\n return contextPage.actionSpace();\n }\n\n return [];\n }\n\n // Local execution doesn't use a server, so always return true\n async checkStatus(): Promise<boolean> {\n return true;\n }\n\n async overrideConfig(aiConfig: Record<string, unknown>): Promise<void> {\n // For local execution, use the shared env override function\n overrideAIConfig(aiConfig);\n }\n\n /**\n * Safely detaches the Chrome debugger without destroying the agent.\n * This removes the \"Debugger attached\" banner from the browser window\n * while keeping the agent instance intact for potential reuse.\n * Called on errors to improve user experience by cleaning up the UI.\n */\n private async detachDebuggerSafely() {\n try {\n const page = this.agent?.interface as\n | { detachDebugger?: () => Promise<void> }\n | undefined;\n await page?.detachDebugger?.();\n } catch (error) {\n console.warn('Failed to detach debugger:', error);\n }\n }\n\n async executeAction(\n actionType: string,\n value: FormValue,\n options: ExecutionOptions,\n ): Promise<unknown> {\n // Get actionSpace using our simplified getActionSpace method\n const actionSpace = await this.getActionSpace();\n let removeListener: (() => void) | undefined;\n\n // Reset dump at the start of execution to ensure clean state\n try {\n this.agent.resetDump?.();\n } catch (error: unknown) {\n console.warn('Failed to reset dump before execution:', error);\n }\n\n // Setup dump update tracking if requestId is provided\n if (options.requestId && this.agent) {\n // Track current request ID to prevent stale callbacks\n this.currentRequestId = options.requestId;\n\n // Add listener and save remove function\n removeListener = this.agent.addDumpUpdateListener(\n (dump: string, executionDump?: ExecutionDump) => {\n // Only process if this is still the current request\n if (this.currentRequestId !== options.requestId) {\n return;\n }\n\n // Forward to external callback\n if (this.dumpUpdateCallback) {\n this.dumpUpdateCallback(dump, executionDump);\n }\n },\n );\n }\n\n try {\n let result = null;\n let executionError = null;\n\n try {\n // Call the base implementation with the original signature\n result = await executeAction(\n this.agent,\n actionType,\n actionSpace,\n value,\n options,\n );\n } catch (error: unknown) {\n // Capture error but don't throw yet - we need to get dump/reportHTML first\n executionError = error;\n }\n\n // Always construct response with dump and reportHTML, regardless of success/failure\n const response = {\n result,\n dump: null as unknown,\n reportHTML: null as string | null,\n error: executionError\n ? executionError instanceof Error\n ? executionError.message\n : String(executionError)\n : null,\n };\n\n try {\n if (this.agent.dumpDataString) {\n const dumpString = this.agent.dumpDataString();\n if (dumpString) {\n const groupedDump = JSON.parse(dumpString);\n response.dump = groupedDump.executions?.[0] || null;\n }\n }\n\n // Always generate reportHTML for all APIs (including noReplayAPIs)\n if (this.agent.reportHTMLString) {\n response.reportHTML = this.agent.reportHTMLString() || null;\n }\n\n // Write out action dumps\n if (this.agent.writeOutActionDumps) {\n this.agent.writeOutActionDumps();\n }\n } catch (error: unknown) {\n console.error('Failed to get dump/reportHTML from agent:', error);\n }\n\n // Don't throw the error - return it in response so caller can access dump/reportHTML\n // The caller (usePlaygroundExecution) will check response.error to determine success\n return response;\n } finally {\n // Remove listener to prevent accumulation\n if (removeListener) {\n removeListener();\n }\n }\n }\n\n // Local execution task cancellation - minimal implementation\n async cancelTask(\n _requestId: string,\n ): Promise<{ error?: string; success?: boolean }> {\n if (!this.agent) {\n return { error: 'No active agent found for this requestId' };\n }\n\n try {\n await this.agent.destroy?.();\n return { success: true };\n } catch (error: unknown) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error';\n console.error(`Failed to cancel agent: ${errorMessage}`);\n return { error: `Failed to cancel: ${errorMessage}` };\n }\n }\n\n /**\n * Get current execution data without resetting\n * This allows retrieving dump and report when execution is stopped\n */\n async getCurrentExecutionData(): Promise<{\n dump: ExecutionDump | null;\n reportHTML: string | null;\n }> {\n const response = {\n dump: null as ExecutionDump | null,\n reportHTML: null as string | null,\n };\n\n try {\n // Get dump data\n if (this.agent.dumpDataString) {\n const dumpString = this.agent.dumpDataString();\n if (dumpString) {\n const groupedDump = JSON.parse(dumpString);\n response.dump = groupedDump.executions?.[0] || null;\n }\n }\n\n // Get report HTML\n if (this.agent.reportHTMLString) {\n response.reportHTML = this.agent.reportHTMLString() || null;\n }\n } catch (error: unknown) {\n console.error('Failed to get current execution data:', error);\n }\n\n return response;\n }\n\n // Get interface information from the agent\n async getInterfaceInfo(): Promise<{\n type: string;\n description?: string;\n } | null> {\n if (!this.agent?.interface) {\n return null;\n }\n\n try {\n const type = this.agent.interface.interfaceType || 'Unknown';\n const description = this.agent.interface.describe?.() || undefined;\n\n return {\n type,\n description,\n };\n } catch (error: unknown) {\n console.error('Failed to get interface info:', error);\n return null;\n }\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","LocalExecutionAdapter","BasePlaygroundAdapter","callback","undefined","action","params","options","parseStructuredParams","error","errorMessage","context","page","contextPage","aiConfig","overrideAIConfig","console","actionType","value","actionSpace","removeListener","dump","executionDump","result","executionError","executeAction","response","Error","String","dumpString","groupedDump","JSON","_requestId","type","description","agent","uuid"],"mappings":"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"}
|