@midscene/playground 1.0.3-beta-20251223004639.0 → 1.0.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"adapters/remote-execution.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/adapters/remote-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 { parseStructuredParams } from '../common';\nimport type {\n ExecutionOptions,\n FormValue,\n ProgressMessage,\n ValidationResult,\n} from '../types';\nimport { BasePlaygroundAdapter } from './base';\n\nexport class RemoteExecutionAdapter extends BasePlaygroundAdapter {\n private serverUrl?: string;\n private _id?: string;\n private dumpUpdateCallback?: (\n dump: string,\n executionDump?: ExecutionDump,\n ) => void;\n private pollingIntervalId?: ReturnType<typeof setInterval>;\n\n constructor(serverUrl: string) {\n super();\n this.serverUrl = serverUrl;\n }\n\n // Set dump update callback\n onDumpUpdate(\n callback: (dump: string, executionDump?: ExecutionDump) => void,\n ): void {\n this.dumpUpdateCallback = undefined;\n this.dumpUpdateCallback = callback;\n }\n\n // Get adapter ID (cached after first status check for remote)\n get id(): string | undefined {\n return this._id;\n }\n\n // Override validateParams for remote execution\n // Since schemas from server are JSON-serialized and lack .parse() method\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 // For remote execution, perform basic validation without .parse()\n // Check if required fields are present\n if (action.paramSchema && typeof action.paramSchema === 'object') {\n const schema = action.paramSchema as any;\n if (schema.shape || schema.type === 'ZodObject') {\n const shape = schema.shape || {};\n const missingFields = Object.keys(shape).filter((key) => {\n const fieldDef = shape[key];\n // Check if field is required (not optional)\n const isOptional =\n fieldDef?.isOptional ||\n fieldDef?._def?.innerType || // ZodOptional\n fieldDef?._def?.typeName === 'ZodOptional';\n return (\n !isOptional &&\n (value.params![key] === undefined || value.params![key] === '')\n );\n });\n\n if (missingFields.length > 0) {\n return {\n valid: false,\n errorMessage: `Missing required parameters: ${missingFields.join(', ')}`,\n };\n }\n }\n }\n\n return { valid: true };\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 message = error?.message || '';\n\n // Handle Android-specific errors\n const androidErrors = [\n {\n keyword: 'adb',\n message:\n 'ADB connection error. Please ensure device is connected and USB debugging is enabled.',\n },\n {\n keyword: 'UIAutomator',\n message:\n 'UIAutomator error. Please ensure the UIAutomator server is running on the device.',\n },\n ];\n\n const androidError = androidErrors.find(({ keyword }) =>\n message.includes(keyword),\n );\n if (androidError) {\n return androidError.message;\n }\n\n return this.formatBasicErrorMessage(error);\n }\n\n // Remote execution adapter - simplified interface\n async executeAction(\n actionType: string,\n value: FormValue,\n options: ExecutionOptions,\n ): Promise<unknown> {\n // If serverUrl is provided, use server-side execution\n if (this.serverUrl && typeof window !== 'undefined') {\n return this.executeViaServer(actionType, value, options);\n }\n\n throw new Error(\n 'Remote execution adapter requires server URL for execution',\n );\n }\n\n // Remote execution via server - uses same endpoint as requestPlaygroundServer\n private async executeViaServer(\n actionType: string,\n value: FormValue,\n options: ExecutionOptions,\n ): Promise<unknown> {\n const payload: Record<string, unknown> = {\n type: actionType,\n prompt: value.prompt,\n ...this.buildOptionalPayloadParams(options, value),\n };\n\n // Add context only if it exists (server can handle single agent case without context)\n if (options.context) {\n payload.context = options.context;\n }\n\n // Start polling if requestId is provided and dumpUpdateCallback is set\n if (options.requestId && this.dumpUpdateCallback) {\n this.startProgressPolling(options.requestId);\n }\n\n try {\n const response = await fetch(`${this.serverUrl}/execute`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'Unknown error');\n throw new Error(\n `Server request failed (${response.status}): ${errorText}`,\n );\n }\n\n const result = await response.json();\n\n return result;\n } catch (error) {\n console.error('Execute via server failed:', error);\n throw error;\n } finally {\n // Stop polling when execution completes (success or error)\n this.stopProgressPolling();\n }\n }\n\n // Helper method to build optional payload parameters\n private buildOptionalPayloadParams(\n options: ExecutionOptions,\n value: FormValue,\n ): Record<string, unknown> {\n const optionalParams: Record<string, unknown> = {};\n\n // Add optional parameters only if they have meaningful values\n const optionalFields = [\n { key: 'requestId', value: options.requestId },\n { key: 'deepThink', value: options.deepThink },\n { key: 'screenshotIncluded', value: options.screenshotIncluded },\n { key: 'domIncluded', value: options.domIncluded },\n { key: 'deviceOptions', value: options.deviceOptions },\n { key: 'params', value: value.params },\n ] as const;\n\n optionalFields.forEach(({ key, value }) => {\n if (value !== undefined && value !== null && value !== '') {\n optionalParams[key] = value;\n }\n });\n\n return optionalParams;\n }\n\n // Get action space from server with fallback\n async getActionSpace(context?: unknown): Promise<DeviceAction<unknown>[]> {\n // Try server first if available\n if (this.serverUrl && typeof window !== 'undefined') {\n try {\n const response = await fetch(`${this.serverUrl}/action-space`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ context }),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to get action space: ${response.statusText}`);\n }\n\n const result = await response.json();\n return Array.isArray(result) ? result : [];\n } catch (error) {\n console.error('Failed to get action space from server:', error);\n // Fall through to context fallback\n }\n }\n\n // Fallback: try context.actionSpace if available\n if (context && typeof context === 'object' && 'actionSpace' in context) {\n try {\n const actionSpaceMethod = (\n context as {\n actionSpace: () =>\n | DeviceAction<unknown>[]\n | Promise<DeviceAction<unknown>[]>;\n }\n ).actionSpace;\n const result = await actionSpaceMethod();\n return Array.isArray(result) ? result : [];\n } catch (error) {\n console.error('Failed to get action space from context:', error);\n }\n }\n\n return [];\n }\n\n // Uses base implementation for validateParams and createDisplayContent\n\n // Server communication methods\n async checkStatus(): Promise<boolean> {\n if (!this.serverUrl) {\n return false;\n }\n\n try {\n const res = await fetch(`${this.serverUrl}/status`);\n if (res.status === 200) {\n // Try to extract id from response\n try {\n const data = await res.json();\n if (data.id && typeof data.id === 'string') {\n this._id = data.id;\n }\n } catch (jsonError) {\n // If JSON parsing fails, id remains undefined but status is still OK\n console.debug('Failed to parse status response:', jsonError);\n }\n return true;\n }\n return false;\n } catch (error) {\n console.warn('Server status check failed:', error);\n return false;\n }\n }\n\n async overrideConfig(aiConfig: Record<string, unknown>): Promise<void> {\n if (!this.serverUrl) {\n throw new Error('Server URL not configured');\n }\n\n try {\n const response = await fetch(`${this.serverUrl}/config`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ aiConfig }),\n });\n\n if (!response.ok) {\n throw new Error(\n `Failed to override server config: ${response.statusText}`,\n );\n }\n } catch (error) {\n console.error('Failed to override server config:', error);\n throw error;\n }\n }\n\n async getTaskProgress(requestId: string): Promise<{\n tip?: string;\n progressMessages?: ProgressMessage[];\n }> {\n if (!this.serverUrl) {\n return { tip: undefined };\n }\n\n if (!requestId?.trim()) {\n console.warn('Invalid requestId provided for task progress');\n return { tip: undefined };\n }\n\n try {\n const response = await fetch(\n `${this.serverUrl}/task-progress/${encodeURIComponent(requestId)}`,\n );\n\n if (!response.ok) {\n console.warn(`Task progress request failed: ${response.statusText}`);\n return { tip: undefined };\n }\n\n return await response.json();\n } catch (error) {\n console.error('Failed to poll task progress:', error);\n return { tip: undefined };\n }\n }\n\n /**\n * Convert ProgressMessage[] to ExecutionDump format\n * This allows remote execution to provide the same dump format as local execution\n */\n private convertProgressMessagesToExecutionDump(\n progressMessages: ProgressMessage[],\n ): ExecutionDump {\n // Convert ProgressMessage[] to ExecutionTask[] format\n // We need to construct tasks in a way that typeStr() and paramStr() can extract correctly\n const tasks = progressMessages.map((msg) => {\n // For typeStr() to work: it returns task.subType || task.type\n // For paramStr() to work: we use Planning type which checks output.log or param.userInstruction\n const task: any = {\n type: 'Planning',\n subType: msg.action, // This will be returned by typeStr()\n param: {\n userInstruction: msg.description, // This will be returned by paramStr()\n },\n status: msg.status,\n timing: {\n start: msg.timestamp,\n end:\n msg.status === 'finished' || msg.status === 'failed'\n ? msg.timestamp\n : undefined,\n },\n };\n return task;\n });\n\n return {\n name: 'Remote Execution',\n tasks: tasks as any[], // Type assertion needed due to ExecutionTask complexity\n logTime: Date.now(),\n };\n }\n\n /**\n * Start polling for task progress and invoke dump update callback\n */\n private startProgressPolling(requestId: string): void {\n // Clear any existing polling\n this.stopProgressPolling();\n\n // Poll every 500ms for progress updates\n this.pollingIntervalId = setInterval(async () => {\n try {\n const progressData = await this.getTaskProgress(requestId);\n\n if (\n progressData.progressMessages &&\n progressData.progressMessages.length > 0\n ) {\n // Convert progress messages to ExecutionDump format\n const executionDump = this.convertProgressMessagesToExecutionDump(\n progressData.progressMessages,\n );\n\n // Invoke dump update callback if set\n if (this.dumpUpdateCallback) {\n this.dumpUpdateCallback('', executionDump);\n }\n }\n } catch (error) {\n console.error('Error polling task progress:', error);\n }\n }, 500); // Poll every 500ms\n }\n\n /**\n * Stop polling for task progress\n */\n private stopProgressPolling(): void {\n if (this.pollingIntervalId) {\n clearInterval(this.pollingIntervalId);\n this.pollingIntervalId = undefined;\n }\n }\n\n // Cancel task\n async cancelTask(\n requestId: string,\n ): Promise<{ error?: string; success?: boolean }> {\n if (!this.serverUrl) {\n return { error: 'No server URL configured' };\n }\n\n if (!requestId?.trim()) {\n return { error: 'Invalid request ID' };\n }\n\n try {\n const res = await fetch(\n `${this.serverUrl}/cancel/${encodeURIComponent(requestId)}`,\n {\n method: 'POST',\n },\n );\n\n if (!res.ok) {\n return { error: `Cancel request failed: ${res.statusText}` };\n }\n\n const result = await res.json();\n return { success: true, ...result };\n } catch (error) {\n console.error('Failed to cancel task:', error);\n return { error: 'Failed to cancel task' };\n }\n }\n\n // Get screenshot from server\n async getScreenshot(): Promise<{\n screenshot: string;\n timestamp: number;\n } | null> {\n if (!this.serverUrl) {\n return null;\n }\n\n try {\n const response = await fetch(`${this.serverUrl}/screenshot`);\n\n if (!response.ok) {\n console.warn(`Screenshot request failed: ${response.statusText}`);\n return null;\n }\n\n return await response.json();\n } catch (error) {\n console.error('Failed to get screenshot:', error);\n return null;\n }\n }\n\n // Get interface information from server\n async getInterfaceInfo(): Promise<{\n type: string;\n description?: string;\n } | null> {\n if (!this.serverUrl) {\n return null;\n }\n\n try {\n const response = await fetch(`${this.serverUrl}/interface-info`);\n\n if (!response.ok) {\n console.warn(`Interface info request failed: ${response.statusText}`);\n return null;\n }\n\n return await response.json();\n } catch (error) {\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","RemoteExecutionAdapter","BasePlaygroundAdapter","callback","undefined","value","action","needsStructuredParams","schema","shape","missingFields","fieldDef","isOptional","params","options","parseStructuredParams","error","message","androidErrors","androidError","keyword","actionType","window","Error","payload","response","fetch","JSON","errorText","result","console","optionalParams","optionalFields","context","Array","actionSpaceMethod","res","data","jsonError","aiConfig","requestId","encodeURIComponent","progressMessages","tasks","msg","task","Date","setInterval","progressData","executionDump","clearInterval","serverUrl"],"mappings":"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"}
1
+ {"version":3,"file":"adapters/remote-execution.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/adapters/remote-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 { parseStructuredParams } from '../common';\nimport type { ExecutionOptions, FormValue, ValidationResult } from '../types';\nimport { BasePlaygroundAdapter } from './base';\n\nexport class RemoteExecutionAdapter extends BasePlaygroundAdapter {\n private serverUrl?: string;\n private _id?: string;\n private dumpUpdateCallback?: (\n dump: string,\n executionDump?: ExecutionDump,\n ) => void;\n private pollingIntervalId?: ReturnType<typeof setInterval>;\n\n constructor(serverUrl: string) {\n super();\n this.serverUrl = serverUrl;\n }\n\n // Set dump update callback\n onDumpUpdate(\n callback: (dump: string, executionDump?: ExecutionDump) => void,\n ): void {\n this.dumpUpdateCallback = undefined;\n this.dumpUpdateCallback = callback;\n }\n\n // Get adapter ID (cached after first status check for remote)\n get id(): string | undefined {\n return this._id;\n }\n\n // Override validateParams for remote execution\n // Since schemas from server are JSON-serialized and lack .parse() method\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 // For remote execution, perform basic validation without .parse()\n // Check if required fields are present\n if (action.paramSchema && typeof action.paramSchema === 'object') {\n const schema = action.paramSchema as any;\n if (schema.shape || schema.type === 'ZodObject') {\n const shape = schema.shape || {};\n const missingFields = Object.keys(shape).filter((key) => {\n const fieldDef = shape[key];\n // Check if field is required (not optional)\n const isOptional =\n fieldDef?.isOptional ||\n fieldDef?._def?.innerType || // ZodOptional\n fieldDef?._def?.typeName === 'ZodOptional';\n return (\n !isOptional &&\n (value.params![key] === undefined || value.params![key] === '')\n );\n });\n\n if (missingFields.length > 0) {\n return {\n valid: false,\n errorMessage: `Missing required parameters: ${missingFields.join(', ')}`,\n };\n }\n }\n }\n\n return { valid: true };\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 message = error?.message || '';\n\n // Handle Android-specific errors\n const androidErrors = [\n {\n keyword: 'adb',\n message:\n 'ADB connection error. Please ensure device is connected and USB debugging is enabled.',\n },\n {\n keyword: 'UIAutomator',\n message:\n 'UIAutomator error. Please ensure the UIAutomator server is running on the device.',\n },\n ];\n\n const androidError = androidErrors.find(({ keyword }) =>\n message.includes(keyword),\n );\n if (androidError) {\n return androidError.message;\n }\n\n return this.formatBasicErrorMessage(error);\n }\n\n // Remote execution adapter - simplified interface\n async executeAction(\n actionType: string,\n value: FormValue,\n options: ExecutionOptions,\n ): Promise<unknown> {\n // If serverUrl is provided, use server-side execution\n if (this.serverUrl && typeof window !== 'undefined') {\n return this.executeViaServer(actionType, value, options);\n }\n\n throw new Error(\n 'Remote execution adapter requires server URL for execution',\n );\n }\n\n // Remote execution via server - uses same endpoint as requestPlaygroundServer\n private async executeViaServer(\n actionType: string,\n value: FormValue,\n options: ExecutionOptions,\n ): Promise<unknown> {\n const payload: Record<string, unknown> = {\n type: actionType,\n prompt: value.prompt,\n ...this.buildOptionalPayloadParams(options, value),\n };\n\n // Add context only if it exists (server can handle single agent case without context)\n if (options.context) {\n payload.context = options.context;\n }\n\n // Start polling if requestId is provided and dumpUpdateCallback is set\n if (options.requestId && this.dumpUpdateCallback) {\n this.startProgressPolling(options.requestId);\n }\n\n try {\n const response = await fetch(`${this.serverUrl}/execute`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'Unknown error');\n throw new Error(\n `Server request failed (${response.status}): ${errorText}`,\n );\n }\n\n const result = await response.json();\n\n return result;\n } catch (error) {\n console.error('Execute via server failed:', error);\n throw error;\n } finally {\n // Stop polling when execution completes (success or error)\n this.stopProgressPolling();\n }\n }\n\n // Helper method to build optional payload parameters\n private buildOptionalPayloadParams(\n options: ExecutionOptions,\n value: FormValue,\n ): Record<string, unknown> {\n const optionalParams: Record<string, unknown> = {};\n\n // Add optional parameters only if they have meaningful values\n const optionalFields = [\n { key: 'requestId', value: options.requestId },\n { key: 'deepThink', value: options.deepThink },\n { key: 'screenshotIncluded', value: options.screenshotIncluded },\n { key: 'domIncluded', value: options.domIncluded },\n { key: 'deviceOptions', value: options.deviceOptions },\n { key: 'params', value: value.params },\n ] as const;\n\n optionalFields.forEach(({ key, value }) => {\n if (value !== undefined && value !== null && value !== '') {\n optionalParams[key] = value;\n }\n });\n\n return optionalParams;\n }\n\n // Get action space from server with fallback\n async getActionSpace(context?: unknown): Promise<DeviceAction<unknown>[]> {\n // Try server first if available\n if (this.serverUrl && typeof window !== 'undefined') {\n try {\n const response = await fetch(`${this.serverUrl}/action-space`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ context }),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to get action space: ${response.statusText}`);\n }\n\n const result = await response.json();\n return Array.isArray(result) ? result : [];\n } catch (error) {\n console.error('Failed to get action space from server:', error);\n // Fall through to context fallback\n }\n }\n\n // Fallback: try context.actionSpace if available\n if (context && typeof context === 'object' && 'actionSpace' in context) {\n try {\n const actionSpaceMethod = (\n context as {\n actionSpace: () =>\n | DeviceAction<unknown>[]\n | Promise<DeviceAction<unknown>[]>;\n }\n ).actionSpace;\n const result = await actionSpaceMethod();\n return Array.isArray(result) ? result : [];\n } catch (error) {\n console.error('Failed to get action space from context:', error);\n }\n }\n\n return [];\n }\n\n // Uses base implementation for validateParams and createDisplayContent\n\n // Server communication methods\n async checkStatus(): Promise<boolean> {\n if (!this.serverUrl) {\n return false;\n }\n\n try {\n const res = await fetch(`${this.serverUrl}/status`);\n if (res.status === 200) {\n // Try to extract id from response\n try {\n const data = await res.json();\n if (data.id && typeof data.id === 'string') {\n this._id = data.id;\n }\n } catch (jsonError) {\n // If JSON parsing fails, id remains undefined but status is still OK\n console.debug('Failed to parse status response:', jsonError);\n }\n return true;\n }\n return false;\n } catch (error) {\n console.warn('Server status check failed:', error);\n return false;\n }\n }\n\n async overrideConfig(aiConfig: Record<string, unknown>): Promise<void> {\n if (!this.serverUrl) {\n throw new Error('Server URL not configured');\n }\n\n try {\n const response = await fetch(`${this.serverUrl}/config`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ aiConfig }),\n });\n\n if (!response.ok) {\n throw new Error(\n `Failed to override server config: ${response.statusText}`,\n );\n }\n } catch (error) {\n console.error('Failed to override server config:', error);\n throw error;\n }\n }\n\n async getTaskProgress(requestId: string): Promise<{\n executionDump?: ExecutionDump;\n }> {\n if (!this.serverUrl) {\n return {};\n }\n\n if (!requestId?.trim()) {\n console.warn('Invalid requestId provided for task progress');\n return {};\n }\n\n try {\n const response = await fetch(\n `${this.serverUrl}/task-progress/${encodeURIComponent(requestId)}`,\n );\n\n if (!response.ok) {\n console.warn(`Task progress request failed: ${response.statusText}`);\n return {};\n }\n\n return await response.json();\n } catch (error) {\n console.error('Failed to poll task progress:', error);\n return {};\n }\n }\n\n /**\n * Start polling for task progress and invoke dump update callback\n */\n private startProgressPolling(requestId: string): void {\n // Clear any existing polling\n this.stopProgressPolling();\n\n // Poll every 500ms for progress updates\n this.pollingIntervalId = setInterval(async () => {\n try {\n const progressData = await this.getTaskProgress(requestId);\n\n if (progressData.executionDump) {\n // Invoke dump update callback if set\n if (this.dumpUpdateCallback) {\n this.dumpUpdateCallback('', progressData.executionDump);\n }\n }\n } catch (error) {\n console.error('Error polling task progress:', error);\n }\n }, 500); // Poll every 500ms\n }\n\n /**\n * Stop polling for task progress\n */\n private stopProgressPolling(): void {\n if (this.pollingIntervalId) {\n clearInterval(this.pollingIntervalId);\n this.pollingIntervalId = undefined;\n }\n }\n\n // Cancel task\n async cancelTask(\n requestId: string,\n ): Promise<{ error?: string; success?: boolean }> {\n if (!this.serverUrl) {\n return { error: 'No server URL configured' };\n }\n\n if (!requestId?.trim()) {\n return { error: 'Invalid request ID' };\n }\n\n try {\n const res = await fetch(\n `${this.serverUrl}/cancel/${encodeURIComponent(requestId)}`,\n {\n method: 'POST',\n },\n );\n\n if (!res.ok) {\n return { error: `Cancel request failed: ${res.statusText}` };\n }\n\n const result = await res.json();\n return { success: true, ...result };\n } catch (error) {\n console.error('Failed to cancel task:', error);\n return { error: 'Failed to cancel task' };\n }\n }\n\n // Get screenshot from server\n async getScreenshot(): Promise<{\n screenshot: string;\n timestamp: number;\n } | null> {\n if (!this.serverUrl) {\n return null;\n }\n\n try {\n const response = await fetch(`${this.serverUrl}/screenshot`);\n\n if (!response.ok) {\n console.warn(`Screenshot request failed: ${response.statusText}`);\n return null;\n }\n\n return await response.json();\n } catch (error) {\n console.error('Failed to get screenshot:', error);\n return null;\n }\n }\n\n // Get interface information from server\n async getInterfaceInfo(): Promise<{\n type: string;\n description?: string;\n } | null> {\n if (!this.serverUrl) {\n return null;\n }\n\n try {\n const response = await fetch(`${this.serverUrl}/interface-info`);\n\n if (!response.ok) {\n console.warn(`Interface info request failed: ${response.statusText}`);\n return null;\n }\n\n return await response.json();\n } catch (error) {\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","RemoteExecutionAdapter","BasePlaygroundAdapter","callback","undefined","value","action","needsStructuredParams","schema","shape","missingFields","fieldDef","isOptional","params","options","parseStructuredParams","error","message","androidErrors","androidError","keyword","actionType","window","Error","payload","response","fetch","JSON","errorText","result","console","optionalParams","optionalFields","context","Array","actionSpaceMethod","res","data","jsonError","aiConfig","requestId","encodeURIComponent","setInterval","progressData","clearInterval","serverUrl"],"mappings":"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"}
@@ -83,9 +83,7 @@ class PlaygroundSDK {
83
83
  }
84
84
  async getTaskProgress(requestId) {
85
85
  if (this.adapter instanceof remote_execution_js_namespaceObject.RemoteExecutionAdapter) return this.adapter.getTaskProgress(requestId);
86
- return {
87
- tip: void 0
88
- };
86
+ return {};
89
87
  }
90
88
  async cancelTask(requestId) {
91
89
  if (this.adapter instanceof remote_execution_js_namespaceObject.RemoteExecutionAdapter) return this.adapter.cancelTask(requestId);
@@ -1 +1 @@
1
- {"version":3,"file":"sdk/index.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/sdk/index.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 { PLAYGROUND_SERVER_PORT } from '@midscene/shared/constants';\nimport type { BasePlaygroundAdapter } from '../adapters/base';\nimport { LocalExecutionAdapter } from '../adapters/local-execution';\nimport { RemoteExecutionAdapter } from '../adapters/remote-execution';\nimport type {\n ExecutionOptions,\n FormValue,\n PlaygroundAgent,\n PlaygroundConfig,\n ValidationResult,\n} from '../types';\n\nexport class PlaygroundSDK {\n private adapter: BasePlaygroundAdapter;\n\n constructor(config: PlaygroundConfig) {\n this.adapter = this.createAdapter(\n config.type,\n config.serverUrl,\n config.agent,\n );\n }\n\n private createAdapter(\n type: string,\n serverUrl?: string,\n agent?: PlaygroundAgent,\n ): BasePlaygroundAdapter {\n switch (type) {\n case 'local-execution':\n if (!agent) {\n throw new Error('Agent is required for local execution');\n }\n return new LocalExecutionAdapter(agent);\n case 'remote-execution': {\n // Use provided serverUrl first, then fallback to localhost if current page origin is file:// or default\n const finalServerUrl =\n serverUrl ||\n (typeof window !== 'undefined' &&\n window.location.protocol.includes('http')\n ? window.location.origin\n : `http://localhost:${PLAYGROUND_SERVER_PORT}`);\n\n return new RemoteExecutionAdapter(finalServerUrl);\n }\n default:\n throw new Error(`Unsupported execution type: ${type}`);\n }\n }\n\n async executeAction(\n actionType: string,\n value: FormValue,\n options: ExecutionOptions,\n ): Promise<unknown> {\n const result = await this.adapter.executeAction(actionType, value, options);\n return result;\n }\n\n async getActionSpace(context?: unknown): Promise<DeviceAction<unknown>[]> {\n // Both adapters now accept context parameter\n // Local will prioritize internal agent, Remote will use server + fallback\n return this.adapter.getActionSpace(context);\n }\n\n validateStructuredParams(\n value: FormValue,\n action: DeviceAction<unknown> | undefined,\n ): ValidationResult {\n return this.adapter.validateParams(value, action);\n }\n\n formatErrorMessage(error: any): string {\n return this.adapter.formatErrorMessage(error);\n }\n\n createDisplayContent(\n value: FormValue,\n needsStructuredParams: boolean,\n action: DeviceAction<unknown> | undefined,\n ): string {\n return this.adapter.createDisplayContent(\n value,\n needsStructuredParams,\n action,\n );\n }\n\n // Get adapter ID (works for both remote and local execution)\n get id(): string | undefined {\n if (this.adapter instanceof RemoteExecutionAdapter) {\n return this.adapter.id;\n }\n if (this.adapter instanceof LocalExecutionAdapter) {\n return this.adapter.id;\n }\n return undefined;\n }\n\n // Server communication methods (for remote execution)\n async checkStatus(): Promise<boolean> {\n if (this.adapter instanceof RemoteExecutionAdapter) {\n return this.adapter.checkStatus();\n }\n return true; // For local execution, always return true\n }\n\n async overrideConfig(aiConfig: any): Promise<void> {\n if (this.adapter instanceof RemoteExecutionAdapter) {\n return this.adapter.overrideConfig(aiConfig);\n }\n // For local execution, this is a no-op\n }\n\n // Get task progress (for remote execution)\n async getTaskProgress(requestId: string): Promise<{ tip?: string }> {\n if (this.adapter instanceof RemoteExecutionAdapter) {\n return this.adapter.getTaskProgress(requestId);\n }\n // For local execution, progress is handled via onTaskStartTip callback\n return { tip: undefined };\n }\n\n // Cancel task (for remote execution)\n async cancelTask(requestId: string): Promise<any> {\n if (this.adapter instanceof RemoteExecutionAdapter) {\n return this.adapter.cancelTask(requestId);\n }\n return { error: 'Cancel task not supported in local execution mode' };\n }\n\n // Dump update callback management\n onDumpUpdate(callback: (dump: string, executionDump?: any) => void): void {\n if (this.adapter instanceof LocalExecutionAdapter) {\n this.adapter.onDumpUpdate(callback);\n } else if (this.adapter instanceof RemoteExecutionAdapter) {\n this.adapter.onDumpUpdate(callback);\n }\n }\n\n // Progress update callback management\n onProgressUpdate(callback: (tip: string) => void): void {\n if (this.adapter instanceof LocalExecutionAdapter) {\n this.adapter.setProgressCallback(callback);\n }\n // RemoteExecutionAdapter uses polling mechanism via onDumpUpdate, no separate progress callback needed\n }\n\n // Cancel execution - supports both remote and local\n async cancelExecution(requestId: string): Promise<{\n dump: any | null;\n reportHTML: string | null;\n } | null> {\n if (this.adapter instanceof RemoteExecutionAdapter) {\n const result = await this.adapter.cancelTask(requestId);\n // Return dump and reportHTML if available from cancellation\n if (result.success) {\n return {\n dump: (result as any).dump || null,\n reportHTML: (result as any).reportHTML || null,\n };\n }\n } else if (this.adapter instanceof LocalExecutionAdapter) {\n // For local execution, we might need to implement agent cancellation\n console.warn('Local execution cancellation not fully implemented');\n }\n return null;\n }\n\n // Get current execution data (dump and report)\n async getCurrentExecutionData(): Promise<{\n dump: any | null;\n reportHTML: string | null;\n }> {\n if (\n this.adapter instanceof LocalExecutionAdapter &&\n this.adapter.getCurrentExecutionData\n ) {\n return await this.adapter.getCurrentExecutionData();\n }\n // For remote execution or if method not available, return empty data\n return { dump: null, reportHTML: null };\n }\n\n // Screenshot method for remote execution\n async getScreenshot(): Promise<{\n screenshot: string;\n timestamp: number;\n } | null> {\n if (this.adapter instanceof RemoteExecutionAdapter) {\n return this.adapter.getScreenshot();\n }\n return null; // For local execution, not supported yet\n }\n\n // Get interface information (type and description)\n async getInterfaceInfo(): Promise<{\n type: string;\n description?: string;\n } | null> {\n if (this.adapter instanceof LocalExecutionAdapter) {\n return this.adapter.getInterfaceInfo();\n }\n if (this.adapter instanceof RemoteExecutionAdapter) {\n return this.adapter.getInterfaceInfo();\n }\n return null;\n }\n\n // Get service mode based on adapter type\n getServiceMode(): 'In-Browser-Extension' | 'Server' {\n if (this.adapter instanceof LocalExecutionAdapter) {\n return 'In-Browser-Extension';\n }\n return 'Server';\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","PlaygroundSDK","type","serverUrl","agent","Error","LocalExecutionAdapter","finalServerUrl","window","PLAYGROUND_SERVER_PORT","RemoteExecutionAdapter","actionType","value","options","result","context","action","error","needsStructuredParams","aiConfig","requestId","undefined","callback","console","config"],"mappings":"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"}
1
+ {"version":3,"file":"sdk/index.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/sdk/index.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 { PLAYGROUND_SERVER_PORT } from '@midscene/shared/constants';\nimport type { BasePlaygroundAdapter } from '../adapters/base';\nimport { LocalExecutionAdapter } from '../adapters/local-execution';\nimport { RemoteExecutionAdapter } from '../adapters/remote-execution';\nimport type {\n ExecutionOptions,\n FormValue,\n PlaygroundAgent,\n PlaygroundConfig,\n ValidationResult,\n} from '../types';\n\nexport class PlaygroundSDK {\n private adapter: BasePlaygroundAdapter;\n\n constructor(config: PlaygroundConfig) {\n this.adapter = this.createAdapter(\n config.type,\n config.serverUrl,\n config.agent,\n );\n }\n\n private createAdapter(\n type: string,\n serverUrl?: string,\n agent?: PlaygroundAgent,\n ): BasePlaygroundAdapter {\n switch (type) {\n case 'local-execution':\n if (!agent) {\n throw new Error('Agent is required for local execution');\n }\n return new LocalExecutionAdapter(agent);\n case 'remote-execution': {\n // Use provided serverUrl first, then fallback to localhost if current page origin is file:// or default\n const finalServerUrl =\n serverUrl ||\n (typeof window !== 'undefined' &&\n window.location.protocol.includes('http')\n ? window.location.origin\n : `http://localhost:${PLAYGROUND_SERVER_PORT}`);\n\n return new RemoteExecutionAdapter(finalServerUrl);\n }\n default:\n throw new Error(`Unsupported execution type: ${type}`);\n }\n }\n\n async executeAction(\n actionType: string,\n value: FormValue,\n options: ExecutionOptions,\n ): Promise<unknown> {\n const result = await this.adapter.executeAction(actionType, value, options);\n return result;\n }\n\n async getActionSpace(context?: unknown): Promise<DeviceAction<unknown>[]> {\n // Both adapters now accept context parameter\n // Local will prioritize internal agent, Remote will use server + fallback\n return this.adapter.getActionSpace(context);\n }\n\n validateStructuredParams(\n value: FormValue,\n action: DeviceAction<unknown> | undefined,\n ): ValidationResult {\n return this.adapter.validateParams(value, action);\n }\n\n formatErrorMessage(error: any): string {\n return this.adapter.formatErrorMessage(error);\n }\n\n createDisplayContent(\n value: FormValue,\n needsStructuredParams: boolean,\n action: DeviceAction<unknown> | undefined,\n ): string {\n return this.adapter.createDisplayContent(\n value,\n needsStructuredParams,\n action,\n );\n }\n\n // Get adapter ID (works for both remote and local execution)\n get id(): string | undefined {\n if (this.adapter instanceof RemoteExecutionAdapter) {\n return this.adapter.id;\n }\n if (this.adapter instanceof LocalExecutionAdapter) {\n return this.adapter.id;\n }\n return undefined;\n }\n\n // Server communication methods (for remote execution)\n async checkStatus(): Promise<boolean> {\n if (this.adapter instanceof RemoteExecutionAdapter) {\n return this.adapter.checkStatus();\n }\n return true; // For local execution, always return true\n }\n\n async overrideConfig(aiConfig: any): Promise<void> {\n if (this.adapter instanceof RemoteExecutionAdapter) {\n return this.adapter.overrideConfig(aiConfig);\n }\n // For local execution, this is a no-op\n }\n\n // Get task progress (for remote execution)\n async getTaskProgress(requestId: string): Promise<{ executionDump?: any }> {\n if (this.adapter instanceof RemoteExecutionAdapter) {\n return this.adapter.getTaskProgress(requestId);\n }\n // For local execution, progress is handled via onDumpUpdate callback\n return {};\n }\n\n // Cancel task (for remote execution)\n async cancelTask(requestId: string): Promise<any> {\n if (this.adapter instanceof RemoteExecutionAdapter) {\n return this.adapter.cancelTask(requestId);\n }\n return { error: 'Cancel task not supported in local execution mode' };\n }\n\n // Dump update callback management\n onDumpUpdate(callback: (dump: string, executionDump?: any) => void): void {\n if (this.adapter instanceof LocalExecutionAdapter) {\n this.adapter.onDumpUpdate(callback);\n } else if (this.adapter instanceof RemoteExecutionAdapter) {\n this.adapter.onDumpUpdate(callback);\n }\n }\n\n // Progress update callback management\n onProgressUpdate(callback: (tip: string) => void): void {\n if (this.adapter instanceof LocalExecutionAdapter) {\n this.adapter.setProgressCallback(callback);\n }\n // RemoteExecutionAdapter uses polling mechanism via onDumpUpdate, no separate progress callback needed\n }\n\n // Cancel execution - supports both remote and local\n async cancelExecution(requestId: string): Promise<{\n dump: any | null;\n reportHTML: string | null;\n } | null> {\n if (this.adapter instanceof RemoteExecutionAdapter) {\n const result = await this.adapter.cancelTask(requestId);\n // Return dump and reportHTML if available from cancellation\n if (result.success) {\n return {\n dump: (result as any).dump || null,\n reportHTML: (result as any).reportHTML || null,\n };\n }\n } else if (this.adapter instanceof LocalExecutionAdapter) {\n // For local execution, we might need to implement agent cancellation\n console.warn('Local execution cancellation not fully implemented');\n }\n return null;\n }\n\n // Get current execution data (dump and report)\n async getCurrentExecutionData(): Promise<{\n dump: any | null;\n reportHTML: string | null;\n }> {\n if (\n this.adapter instanceof LocalExecutionAdapter &&\n this.adapter.getCurrentExecutionData\n ) {\n return await this.adapter.getCurrentExecutionData();\n }\n // For remote execution or if method not available, return empty data\n return { dump: null, reportHTML: null };\n }\n\n // Screenshot method for remote execution\n async getScreenshot(): Promise<{\n screenshot: string;\n timestamp: number;\n } | null> {\n if (this.adapter instanceof RemoteExecutionAdapter) {\n return this.adapter.getScreenshot();\n }\n return null; // For local execution, not supported yet\n }\n\n // Get interface information (type and description)\n async getInterfaceInfo(): Promise<{\n type: string;\n description?: string;\n } | null> {\n if (this.adapter instanceof LocalExecutionAdapter) {\n return this.adapter.getInterfaceInfo();\n }\n if (this.adapter instanceof RemoteExecutionAdapter) {\n return this.adapter.getInterfaceInfo();\n }\n return null;\n }\n\n // Get service mode based on adapter type\n getServiceMode(): 'In-Browser-Extension' | 'Server' {\n if (this.adapter instanceof LocalExecutionAdapter) {\n return 'In-Browser-Extension';\n }\n return 'Server';\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","PlaygroundSDK","type","serverUrl","agent","Error","LocalExecutionAdapter","finalServerUrl","window","PLAYGROUND_SERVER_PORT","RemoteExecutionAdapter","actionType","value","options","result","context","action","error","needsStructuredParams","aiConfig","requestId","callback","console","config"],"mappings":"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"}
@@ -42,7 +42,6 @@ __webpack_require__.d(__webpack_exports__, {
42
42
  const external_node_fs_namespaceObject = require("node:fs");
43
43
  const external_node_path_namespaceObject = require("node:path");
44
44
  const external_node_url_namespaceObject = require("node:url");
45
- const agent_namespaceObject = require("@midscene/core/agent");
46
45
  const utils_namespaceObject = require("@midscene/core/utils");
47
46
  const constants_namespaceObject = require("@midscene/shared/constants");
48
47
  const env_namespaceObject = require("@midscene/shared/env");
@@ -139,12 +138,9 @@ class PlaygroundServer {
139
138
  });
140
139
  this._app.get('/task-progress/:requestId', async (req, res)=>{
141
140
  const { requestId } = req.params;
142
- const progressMessages = this.taskProgressMessages[requestId] || [];
143
- const lastMessage = progressMessages.length > 0 ? progressMessages[progressMessages.length - 1] : void 0;
144
- const tip = lastMessage && 'string' == typeof lastMessage.action ? `${lastMessage.action} - ${lastMessage.description || ''}` : '';
141
+ const executionDump = this.taskExecutionDumps[requestId] || null;
145
142
  res.json({
146
- tip,
147
- progressMessages
143
+ executionDump
148
144
  });
149
145
  });
150
146
  this._app.post('/action-space', async (req, res)=>{
@@ -209,22 +205,9 @@ class PlaygroundServer {
209
205
  });
210
206
  if (requestId) {
211
207
  this.currentTaskId = requestId;
212
- this.taskProgressMessages[requestId] = [];
208
+ this.taskExecutionDumps[requestId] = null;
213
209
  this.agent.onDumpUpdate = (_dump, executionDump)=>{
214
- if (executionDump?.tasks) this.taskProgressMessages[requestId] = executionDump.tasks.map((task, index)=>{
215
- const action = (0, agent_namespaceObject.typeStr)(task);
216
- const description = (0, agent_namespaceObject.paramStr)(task) || '';
217
- const taskStatus = task.status;
218
- const status = 'cancelled' === taskStatus ? 'failed' : taskStatus;
219
- return {
220
- id: `progress-task-${index}`,
221
- taskId: `task-${index}`,
222
- action,
223
- description,
224
- status,
225
- timestamp: task.timing?.start || Date.now()
226
- };
227
- });
210
+ if (executionDump) this.taskExecutionDumps[requestId] = executionDump;
228
211
  };
229
212
  }
230
213
  const response = {
@@ -269,7 +252,7 @@ class PlaygroundServer {
269
252
  if (response.error) console.error(`handle request failed after ${timeCost}ms: requestId: ${requestId}, ${response.error}`);
270
253
  else console.log(`handle request done after ${timeCost}ms: requestId: ${requestId}`);
271
254
  if (requestId) {
272
- delete this.taskProgressMessages[requestId];
255
+ delete this.taskExecutionDumps[requestId];
273
256
  if (this.currentTaskId === requestId) this.currentTaskId = null;
274
257
  }
275
258
  });
@@ -297,7 +280,7 @@ class PlaygroundServer {
297
280
  console.warn('Failed to get execution data before cancel:', error);
298
281
  }
299
282
  await this.recreateAgent();
300
- delete this.taskProgressMessages[requestId];
283
+ delete this.taskExecutionDumps[requestId];
301
284
  this.currentTaskId = null;
302
285
  res.json({
303
286
  status: 'cancelled',
@@ -424,7 +407,7 @@ class PlaygroundServer {
424
407
  } catch (error) {
425
408
  console.warn('Failed to destroy agent:', error);
426
409
  }
427
- this.taskProgressMessages = {};
410
+ this.taskExecutionDumps = {};
428
411
  this.server.close((error)=>{
429
412
  if (error) reject(error);
430
413
  else {
@@ -442,7 +425,7 @@ class PlaygroundServer {
442
425
  _define_property(this, "port", void 0);
443
426
  _define_property(this, "agent", void 0);
444
427
  _define_property(this, "staticPath", void 0);
445
- _define_property(this, "taskProgressMessages", void 0);
428
+ _define_property(this, "taskExecutionDumps", void 0);
446
429
  _define_property(this, "id", void 0);
447
430
  _define_property(this, "_initialized", false);
448
431
  _define_property(this, "agentFactory", void 0);
@@ -450,7 +433,7 @@ class PlaygroundServer {
450
433
  this._app = external_express_default()();
451
434
  this.tmpDir = (0, utils_namespaceObject.getTmpDir)();
452
435
  this.staticPath = staticPath;
453
- this.taskProgressMessages = {};
436
+ this.taskExecutionDumps = {};
454
437
  this.id = id || (0, shared_utils_namespaceObject.uuid)();
455
438
  if ('function' == typeof agent) {
456
439
  this.agentFactory = agent;
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sources":["webpack/runtime/compat_get_default_export","webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../src/server.ts"],"sourcesContent":["// getDefaultExport function for compatibility with non-ESM modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};\n","__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 { 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 const dumpString = this.agent.dumpDataString();\n if (dumpString) {\n const groupedDump = JSON.parse(dumpString);\n // Extract first execution from grouped dump, matching local execution adapter behavior\n response.dump = groupedDump.executions?.[0] || null;\n } else {\n response.dump = null;\n }\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 // Get current execution data before cancelling (dump and reportHTML)\n let dump: any = null;\n let reportHTML: string | null = null;\n\n try {\n const dumpString = this.agent.dumpDataString?.();\n if (dumpString) {\n const groupedDump = JSON.parse(dumpString);\n // Extract first execution from grouped dump\n dump = groupedDump.executions?.[0] || null;\n }\n\n reportHTML = this.agent.reportHTMLString?.() || null;\n } catch (error: unknown) {\n console.warn('Failed to get execution data before cancel:', error);\n }\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',\n dump,\n reportHTML,\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":["__webpack_require__","module","getter","definition","key","Object","obj","prop","Symbol","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","dumpString","groupedDump","JSON","timeCost","dump","reportHTML","_req","base64Screenshot","aiConfig","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.js","sources":["webpack/runtime/compat_get_default_export","webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../src/server.ts"],"sourcesContent":["// getDefaultExport function for compatibility with non-ESM modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};\n","__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 { 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 { 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 taskExecutionDumps: Record<string, ExecutionDump | null>; // Store execution dumps directly\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.taskExecutionDumps = {}; // 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 executionDump = this.taskExecutionDumps[requestId] || null;\n\n res.json({\n executionDump,\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.taskExecutionDumps[requestId] = null;\n\n // Use onDumpUpdate to receive and store executionDump directly\n this.agent.onDumpUpdate = (\n _dump: string,\n executionDump?: ExecutionDump,\n ) => {\n if (executionDump) {\n // Store the execution dump directly without transformation\n this.taskExecutionDumps[requestId] = executionDump;\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 const dumpString = this.agent.dumpDataString();\n if (dumpString) {\n const groupedDump = JSON.parse(dumpString);\n // Extract first execution from grouped dump, matching local execution adapter behavior\n response.dump = groupedDump.executions?.[0] || null;\n } else {\n response.dump = null;\n }\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 execution dumps and unlock after execution completes\n if (requestId) {\n delete this.taskExecutionDumps[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 // Get current execution data before cancelling (dump and reportHTML)\n let dump: any = null;\n let reportHTML: string | null = null;\n\n try {\n const dumpString = this.agent.dumpDataString?.();\n if (dumpString) {\n const groupedDump = JSON.parse(dumpString);\n // Extract first execution from grouped dump\n dump = groupedDump.executions?.[0] || null;\n }\n\n reportHTML = this.agent.reportHTMLString?.() || null;\n } catch (error: unknown) {\n console.warn('Failed to get execution data before cancel:', error);\n }\n\n // Recreate agent to cancel the current task\n await this.recreateAgent();\n\n // Clean up\n delete this.taskExecutionDumps[requestId];\n this.currentTaskId = null;\n\n res.json({\n status: 'cancelled',\n message: 'Task cancelled successfully',\n dump,\n reportHTML,\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.taskExecutionDumps = {};\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":["__webpack_require__","module","getter","definition","key","Object","obj","prop","Symbol","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","executionDump","actionSpace","processedActionSpace","action","typedAction","processedSchema","e","actionName","type","prompt","params","deepThink","screenshotIncluded","domIncluded","deviceOptions","_dump","response","startTime","Date","value","executeAction","formatErrorMessage","dumpString","groupedDump","JSON","timeCost","dump","reportHTML","_req","base64Screenshot","description","undefined","aiConfig","overrideAIConfig","htmlPath","html","scrcpyPort","global","configScript","port","Promise","resolve","serverPort","reject","agent","staticPath","id","getTmpDir"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import type { DeviceAction, ExecutionDump } from '@midscene/core';
2
- import type { ExecutionOptions, FormValue, ProgressMessage, ValidationResult } from '../types';
2
+ import type { ExecutionOptions, FormValue, ValidationResult } from '../types';
3
3
  import { BasePlaygroundAdapter } from './base';
4
4
  export declare class RemoteExecutionAdapter extends BasePlaygroundAdapter {
5
5
  private serverUrl?;
@@ -19,14 +19,8 @@ export declare class RemoteExecutionAdapter extends BasePlaygroundAdapter {
19
19
  checkStatus(): Promise<boolean>;
20
20
  overrideConfig(aiConfig: Record<string, unknown>): Promise<void>;
21
21
  getTaskProgress(requestId: string): Promise<{
22
- tip?: string;
23
- progressMessages?: ProgressMessage[];
22
+ executionDump?: ExecutionDump;
24
23
  }>;
25
- /**
26
- * Convert ProgressMessage[] to ExecutionDump format
27
- * This allows remote execution to provide the same dump format as local execution
28
- */
29
- private convertProgressMessagesToExecutionDump;
30
24
  /**
31
25
  * Start polling for task progress and invoke dump update callback
32
26
  */
@@ -13,7 +13,7 @@ export declare class PlaygroundSDK {
13
13
  checkStatus(): Promise<boolean>;
14
14
  overrideConfig(aiConfig: any): Promise<void>;
15
15
  getTaskProgress(requestId: string): Promise<{
16
- tip?: string;
16
+ executionDump?: any;
17
17
  }>;
18
18
  cancelTask(requestId: string): Promise<any>;
19
19
  onDumpUpdate(callback: (dump: string, executionDump?: any) => void): void;
@@ -1,7 +1,7 @@
1
1
  import type { Server } from 'node:http';
2
+ import type { ExecutionDump } from '@midscene/core';
2
3
  import type { Agent as PageAgent } from '@midscene/core/agent';
3
4
  import express from 'express';
4
- import type { ProgressMessage } from './types';
5
5
  import 'dotenv/config';
6
6
  declare class PlaygroundServer {
7
7
  private _app;
@@ -10,7 +10,7 @@ declare class PlaygroundServer {
10
10
  port?: number | null;
11
11
  agent: PageAgent;
12
12
  staticPath: string;
13
- taskProgressMessages: Record<string, ProgressMessage[]>;
13
+ taskExecutionDumps: Record<string, ExecutionDump | null>;
14
14
  id: string;
15
15
  private _initialized;
16
16
  private agentFactory?;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@midscene/playground",
3
- "version": "1.0.3-beta-20251223004639.0",
3
+ "version": "1.0.3",
4
4
  "description": "Midscene playground utilities for web integration",
5
5
  "author": "midscene team",
6
6
  "license": "MIT",
@@ -25,8 +25,8 @@
25
25
  "express": "^4.21.2",
26
26
  "open": "10.1.0",
27
27
  "uuid": "11.1.0",
28
- "@midscene/core": "1.0.3-beta-20251223004639.0",
29
- "@midscene/shared": "1.0.3-beta-20251223004639.0"
28
+ "@midscene/shared": "1.0.3",
29
+ "@midscene/core": "1.0.3"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@rslib/core": "^0.18.3",
package/static/index.html CHANGED
@@ -1 +1 @@
1
- <!doctype html><html><head><link rel="icon" href="/favicon.ico"><title>Midscene Playground</title><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><script defer src="/static/js/lib-react.7b1abe58.js"></script><script defer src="/static/js/430.53da0b9c.js"></script><script defer src="/static/js/index.af7dda97.js"></script><link href="/static/css/index.f2964c15.css" rel="stylesheet"></head><body><div id="root"></div></body></html>
1
+ <!doctype html><html><head><link rel="icon" href="/favicon.ico"><title>Midscene Playground</title><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><script defer src="/static/js/lib-react.7b1abe58.js"></script><script defer src="/static/js/430.53da0b9c.js"></script><script defer src="/static/js/index.53e8ac1f.js"></script><link href="/static/css/index.f2964c15.css" rel="stylesheet"></head><body><div id="root"></div></body></html>