@midscene/playground 0.30.10 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/dist/es/adapters/base.mjs +4 -4
  2. package/dist/es/adapters/base.mjs.map +1 -1
  3. package/dist/es/adapters/local-execution.mjs +61 -35
  4. package/dist/es/adapters/local-execution.mjs.map +1 -1
  5. package/dist/es/adapters/remote-execution.mjs +13 -38
  6. package/dist/es/adapters/remote-execution.mjs.map +1 -1
  7. package/dist/es/common.mjs +16 -13
  8. package/dist/es/common.mjs.map +1 -1
  9. package/dist/es/index.browser.mjs.map +1 -1
  10. package/dist/es/launcher.mjs +12 -12
  11. package/dist/es/launcher.mjs.map +1 -1
  12. package/dist/es/sdk/index.mjs +14 -10
  13. package/dist/es/sdk/index.mjs.map +1 -1
  14. package/dist/es/server.mjs +37 -15
  15. package/dist/es/server.mjs.map +1 -1
  16. package/dist/lib/adapters/base.js +6 -6
  17. package/dist/lib/adapters/base.js.map +1 -1
  18. package/dist/lib/adapters/local-execution.js +63 -37
  19. package/dist/lib/adapters/local-execution.js.map +1 -1
  20. package/dist/lib/adapters/remote-execution.js +15 -40
  21. package/dist/lib/adapters/remote-execution.js.map +1 -1
  22. package/dist/lib/common.js +20 -17
  23. package/dist/lib/common.js.map +1 -1
  24. package/dist/lib/index.browser.js +10 -10
  25. package/dist/lib/index.browser.js.map +1 -1
  26. package/dist/lib/index.js +10 -10
  27. package/dist/lib/index.js.map +1 -1
  28. package/dist/lib/launcher.js +14 -14
  29. package/dist/lib/launcher.js.map +1 -1
  30. package/dist/lib/sdk/index.js +16 -12
  31. package/dist/lib/sdk/index.js.map +1 -1
  32. package/dist/lib/server.js +41 -19
  33. package/dist/lib/server.js.map +1 -1
  34. package/dist/lib/types.js +1 -1
  35. package/dist/lib/types.js.map +1 -1
  36. package/dist/types/adapters/local-execution.d.ts +18 -6
  37. package/dist/types/adapters/remote-execution.d.ts +2 -5
  38. package/dist/types/sdk/index.d.ts +6 -2
  39. package/dist/types/server.d.ts +2 -1
  40. package/dist/types/types.d.ts +26 -0
  41. package/package.json +6 -6
  42. package/static/index.html +1 -1
  43. package/static/static/css/index.d32b7df9.css +2 -0
  44. package/static/static/css/index.d32b7df9.css.map +1 -0
  45. package/static/static/js/79.25af61dc.js +611 -0
  46. package/static/static/js/{931.dc961e99.js.LICENSE.txt → 79.25af61dc.js.LICENSE.txt} +0 -4
  47. package/static/static/js/79.25af61dc.js.map +1 -0
  48. package/static/static/js/async/195.0366f6e8.js +3 -0
  49. package/static/static/js/async/195.0366f6e8.js.map +1 -0
  50. package/static/static/js/async/{702.60261735.js → 199.f31e52e7.js} +20 -20
  51. package/static/static/js/async/199.f31e52e7.js.map +1 -0
  52. package/static/static/js/async/221.591b048e.js +21 -0
  53. package/static/static/js/async/221.591b048e.js.map +1 -0
  54. package/static/static/js/async/271.15d46ff8.js +30 -0
  55. package/static/static/js/async/271.15d46ff8.js.map +1 -0
  56. package/static/static/js/async/35.2b64fb0f.js +1 -0
  57. package/static/static/js/async/{644.6bdc4065.js → 467.710fa05a.js} +1 -1
  58. package/static/static/js/async/652.b5a7c7b4.js +3 -0
  59. package/static/static/js/async/652.b5a7c7b4.js.map +1 -0
  60. package/static/static/js/async/856.be9fd814.js +158 -0
  61. package/static/static/js/async/{212.e243c338.js.map → 856.be9fd814.js.map} +1 -1
  62. package/static/static/js/async/860.b56301d9.js +2 -0
  63. package/static/static/js/async/860.b56301d9.js.map +1 -0
  64. package/static/static/js/async/990.82a78a53.js +26 -0
  65. package/static/static/js/async/990.82a78a53.js.map +1 -0
  66. package/static/static/js/index.0930f837.js +10 -0
  67. package/static/static/js/index.0930f837.js.map +1 -0
  68. package/static/static/js/lib-react.7b1abe58.js +3 -0
  69. package/static/static/js/lib-react.7b1abe58.js.map +1 -0
  70. package/static/static/css/index.44466eb4.css +0 -2
  71. package/static/static/css/index.44466eb4.css.map +0 -1
  72. package/static/static/js/931.dc961e99.js +0 -620
  73. package/static/static/js/931.dc961e99.js.map +0 -1
  74. package/static/static/js/async/173.9cf6b074.js +0 -3
  75. package/static/static/js/async/173.9cf6b074.js.map +0 -1
  76. package/static/static/js/async/212.e243c338.js +0 -158
  77. package/static/static/js/async/329.f888b505.js +0 -26
  78. package/static/static/js/async/329.f888b505.js.map +0 -1
  79. package/static/static/js/async/364.1821e74b.js +0 -30
  80. package/static/static/js/async/364.1821e74b.js.map +0 -1
  81. package/static/static/js/async/544.b73fa603.js +0 -2
  82. package/static/static/js/async/544.b73fa603.js.map +0 -1
  83. package/static/static/js/async/582.5dccae2d.js +0 -21
  84. package/static/static/js/async/582.5dccae2d.js.map +0 -1
  85. package/static/static/js/async/624.45ee2b2c.js +0 -3
  86. package/static/static/js/async/624.45ee2b2c.js.map +0 -1
  87. package/static/static/js/async/659.9afd03db.js +0 -21
  88. package/static/static/js/async/659.9afd03db.js.map +0 -1
  89. package/static/static/js/async/702.60261735.js.map +0 -1
  90. package/static/static/js/async/920.7d9a9aa8.js +0 -2
  91. package/static/static/js/async/920.7d9a9aa8.js.map +0 -1
  92. package/static/static/js/async/983.8b91303f.js +0 -1
  93. package/static/static/js/index.2caaacaf.js +0 -10
  94. package/static/static/js/index.2caaacaf.js.map +0 -1
  95. package/static/static/js/lib-react.f566a9ed.js +0 -3
  96. package/static/static/js/lib-react.f566a9ed.js.map +0 -1
  97. /package/static/static/js/{index.2caaacaf.js.LICENSE.txt → index.0930f837.js.LICENSE.txt} +0 -0
  98. /package/static/static/js/{lib-react.f566a9ed.js.LICENSE.txt → lib-react.7b1abe58.js.LICENSE.txt} +0 -0
  99. /package/static/static/wasm/{9e906fbf55e08f98.module.wasm → 9e906fbf.module.wasm} +0 -0
@@ -4,7 +4,7 @@ class BasePlaygroundAdapter {
4
4
  return [];
5
5
  }
6
6
  validateParams(value, action) {
7
- if (!(null == action ? void 0 : action.paramSchema)) return {
7
+ if (!action?.paramSchema) return {
8
8
  valid: true
9
9
  };
10
10
  const needsStructuredParams = this.actionNeedsStructuredParams(action);
@@ -26,15 +26,15 @@ class BasePlaygroundAdapter {
26
26
  }
27
27
  }
28
28
  createDisplayContent(value, needsStructuredParams, action) {
29
- if (!needsStructuredParams || !value.params || !(null == action ? void 0 : action.paramSchema)) return value.prompt || '';
29
+ if (!needsStructuredParams || !value.params || !action?.paramSchema) return value.prompt || '';
30
30
  const paramsList = this.buildParamsDisplayList(value.params, action);
31
31
  return paramsList.join('\n') || value.prompt || '';
32
32
  }
33
33
  formatBasicErrorMessage(error) {
34
- return (null == error ? void 0 : error.message) || 'Unknown error';
34
+ return error?.message || 'Unknown error';
35
35
  }
36
36
  getSchemaKeys(action) {
37
- if (!(null == action ? void 0 : action.paramSchema) || !('shape' in action.paramSchema)) return [];
37
+ if (!action?.paramSchema || !('shape' in action.paramSchema)) return [];
38
38
  const schema = action.paramSchema;
39
39
  return schema && 'shape' in schema ? Object.keys(schema.shape) : [];
40
40
  }
@@ -1 +1 @@
1
- {"version":3,"file":"adapters/base.mjs","sources":["webpack://@midscene/playground/./src/adapters/base.ts"],"sourcesContent":["import type { DeviceAction } from '@midscene/core';\nimport { findAllMidsceneLocatorField } from '@midscene/core/ai-model';\nimport type { ExecutionOptions, FormValue, ValidationResult } from '../types';\n\nexport abstract class BasePlaygroundAdapter {\n abstract parseStructuredParams(\n action: DeviceAction<unknown>,\n params: Record<string, unknown>,\n options: ExecutionOptions,\n ): Promise<unknown[]>;\n\n abstract formatErrorMessage(error: any): string;\n\n // Abstract method for execution - must be implemented by concrete adapters\n abstract executeAction(\n actionType: string,\n value: FormValue,\n options: ExecutionOptions,\n ): Promise<unknown>;\n\n // Optional method for getting action space - default implementation returns empty array\n async getActionSpace(_context: any): Promise<DeviceAction<unknown>[]> {\n return [];\n }\n\n // Common validation logic - can be overridden if needed\n validateParams(\n value: FormValue,\n action: DeviceAction<unknown> | undefined,\n ): ValidationResult {\n if (!action?.paramSchema) {\n return { valid: true };\n }\n\n const needsStructuredParams = this.actionNeedsStructuredParams(action);\n\n if (!needsStructuredParams) {\n return { valid: true };\n }\n\n if (!value.params) {\n return { valid: false, errorMessage: 'Parameters are required' };\n }\n\n try {\n const paramsForValidation = this.prepareParamsForValidation(\n value.params,\n action,\n );\n action.paramSchema.parse(paramsForValidation);\n return { valid: true };\n } catch (error: unknown) {\n return this.handleValidationError(error);\n }\n }\n\n // Common display content creation logic - can be overridden if needed\n createDisplayContent(\n value: FormValue,\n needsStructuredParams: boolean,\n action: DeviceAction<unknown> | undefined,\n ): string {\n if (!needsStructuredParams || !value.params || !action?.paramSchema) {\n return value.prompt || '';\n }\n\n const paramsList = this.buildParamsDisplayList(value.params, action);\n return paramsList.join('\\n') || value.prompt || '';\n }\n\n // Helper method for basic error message formatting\n protected formatBasicErrorMessage(error: any): string {\n return error?.message || 'Unknown error';\n }\n\n // Helper method for parsing structured params base logic\n protected getSchemaKeys(action: DeviceAction<unknown>): string[] {\n if (!action?.paramSchema || !('shape' in action.paramSchema)) {\n return [];\n }\n\n const schema = action.paramSchema;\n return schema && 'shape' in schema\n ? Object.keys((schema as { shape: Record<string, unknown> }).shape)\n : [];\n }\n\n // Helper method for filtering valid params\n protected filterValidParams(\n params: Record<string, unknown>,\n excludeKeys: string[] = [],\n ): Record<string, unknown> {\n const filtered: Record<string, unknown> = {};\n\n Object.keys(params).forEach((key) => {\n if (\n !excludeKeys.includes(key) &&\n params[key] !== undefined &&\n params[key] !== null &&\n params[key] !== ''\n ) {\n filtered[key] = params[key];\n }\n });\n\n return filtered;\n }\n\n // Check if action needs structured parameters\n protected actionNeedsStructuredParams(\n action: DeviceAction<unknown>,\n ): boolean {\n if (\n typeof action.paramSchema === 'object' &&\n 'shape' in action.paramSchema\n ) {\n const shape =\n (action.paramSchema as { shape: Record<string, unknown> }).shape || {};\n return Object.keys(shape).length > 0;\n }\n return true; // If paramSchema exists but not in expected format, assume it needs params\n }\n\n // Prepare parameters for validation by converting string locate fields\n protected prepareParamsForValidation(\n params: Record<string, unknown>,\n action: DeviceAction<unknown>,\n ): Record<string, unknown> {\n const paramsForValidation = { ...params };\n\n if (action.paramSchema) {\n const locatorFieldKeys = findAllMidsceneLocatorField(action.paramSchema);\n locatorFieldKeys.forEach((key: string) => {\n if (typeof paramsForValidation[key] === 'string') {\n paramsForValidation[key] = {\n midscene_location_field_flag: true,\n prompt: paramsForValidation[key],\n center: [0, 0], // dummy values for validation\n rect: { left: 0, top: 0, width: 0, height: 0 },\n };\n }\n });\n }\n\n return paramsForValidation;\n }\n\n // Handle validation errors with proper error message extraction\n protected handleValidationError(error: unknown): ValidationResult {\n const zodError = error as {\n errors?: Array<{ path: string[]; message: string }>;\n };\n\n if (zodError.errors && zodError.errors.length > 0) {\n const errorMessages = zodError.errors\n .filter((err) => {\n const path = err.path.join('.');\n return (\n !path.includes('center') &&\n !path.includes('rect') &&\n !path.includes('midscene_location_field_flag')\n );\n })\n .map((err) => {\n const field = err.path.join('.');\n return `${field}: ${err.message}`;\n });\n\n if (errorMessages.length > 0) {\n return {\n valid: false,\n errorMessage: `Validation error: ${errorMessages.join(', ')}`,\n };\n }\n }\n\n const errorMsg =\n error instanceof Error ? error.message : 'Unknown validation error';\n\n return {\n valid: false,\n errorMessage: `Parameter validation failed: ${errorMsg}`,\n };\n }\n\n // Build display list for parameters\n protected buildParamsDisplayList(\n params: Record<string, unknown>,\n action: DeviceAction<unknown>,\n ): string[] {\n const paramsList: string[] = [];\n const schema = action.paramSchema;\n\n if (!(schema && 'shape' in schema)) {\n return paramsList;\n }\n\n const locatorFieldKeys = findAllMidsceneLocatorField(schema);\n const shapeKeys = Object.keys(\n (schema as { shape: Record<string, unknown> }).shape,\n );\n\n shapeKeys.forEach((key) => {\n const paramValue = params[key];\n if (this.isValidParamValue(paramValue)) {\n const displayKey = this.capitalizeFirstLetter(key);\n const formattedValue = this.formatParamValue(\n key,\n paramValue,\n locatorFieldKeys.includes(key),\n );\n paramsList.push(`${displayKey}: ${formattedValue}`);\n }\n });\n\n return paramsList;\n }\n\n // Check if parameter value is valid for display\n protected isValidParamValue(value: unknown): boolean {\n return value !== undefined && value !== null && value !== '';\n }\n\n // Capitalize first letter of a string\n protected capitalizeFirstLetter(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n }\n\n // Format parameter value for display\n protected formatParamValue(\n key: string,\n value: unknown,\n isLocateField: boolean,\n ): string {\n if (isLocateField || typeof value === 'string') {\n return `\"${value}\"`;\n }\n\n if (typeof value === 'number') {\n // Special handling for distance in scroll\n return key === 'distance' ? `${value}px` : `${value}`;\n }\n\n return `${value}`;\n }\n}\n"],"names":["BasePlaygroundAdapter","_context","value","action","needsStructuredParams","paramsForValidation","error","paramsList","schema","Object","params","excludeKeys","filtered","key","undefined","shape","locatorFieldKeys","findAllMidsceneLocatorField","zodError","errorMessages","err","path","field","errorMsg","Error","shapeKeys","paramValue","displayKey","formattedValue","str","isLocateField"],"mappings":"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"}
1
+ {"version":3,"file":"adapters/base.mjs","sources":["../../../src/adapters/base.ts"],"sourcesContent":["import type { DeviceAction } from '@midscene/core';\nimport { findAllMidsceneLocatorField } from '@midscene/core/ai-model';\nimport type { ExecutionOptions, FormValue, ValidationResult } from '../types';\n\nexport abstract class BasePlaygroundAdapter {\n abstract parseStructuredParams(\n action: DeviceAction<unknown>,\n params: Record<string, unknown>,\n options: ExecutionOptions,\n ): Promise<unknown[]>;\n\n abstract formatErrorMessage(error: any): string;\n\n // Abstract method for execution - must be implemented by concrete adapters\n abstract executeAction(\n actionType: string,\n value: FormValue,\n options: ExecutionOptions,\n ): Promise<unknown>;\n\n // Optional method for getting action space - default implementation returns empty array\n async getActionSpace(_context: any): Promise<DeviceAction<unknown>[]> {\n return [];\n }\n\n // Common validation logic - can be overridden if needed\n validateParams(\n value: FormValue,\n action: DeviceAction<unknown> | undefined,\n ): ValidationResult {\n if (!action?.paramSchema) {\n return { valid: true };\n }\n\n const needsStructuredParams = this.actionNeedsStructuredParams(action);\n\n if (!needsStructuredParams) {\n return { valid: true };\n }\n\n if (!value.params) {\n return { valid: false, errorMessage: 'Parameters are required' };\n }\n\n try {\n const paramsForValidation = this.prepareParamsForValidation(\n value.params,\n action,\n );\n action.paramSchema.parse(paramsForValidation);\n return { valid: true };\n } catch (error: unknown) {\n return this.handleValidationError(error);\n }\n }\n\n // Common display content creation logic - can be overridden if needed\n createDisplayContent(\n value: FormValue,\n needsStructuredParams: boolean,\n action: DeviceAction<unknown> | undefined,\n ): string {\n if (!needsStructuredParams || !value.params || !action?.paramSchema) {\n return value.prompt || '';\n }\n\n const paramsList = this.buildParamsDisplayList(value.params, action);\n return paramsList.join('\\n') || value.prompt || '';\n }\n\n // Helper method for basic error message formatting\n protected formatBasicErrorMessage(error: any): string {\n return error?.message || 'Unknown error';\n }\n\n // Helper method for parsing structured params base logic\n protected getSchemaKeys(action: DeviceAction<unknown>): string[] {\n if (!action?.paramSchema || !('shape' in action.paramSchema)) {\n return [];\n }\n\n const schema = action.paramSchema;\n return schema && 'shape' in schema\n ? Object.keys((schema as { shape: Record<string, unknown> }).shape)\n : [];\n }\n\n // Helper method for filtering valid params\n protected filterValidParams(\n params: Record<string, unknown>,\n excludeKeys: string[] = [],\n ): Record<string, unknown> {\n const filtered: Record<string, unknown> = {};\n\n Object.keys(params).forEach((key) => {\n if (\n !excludeKeys.includes(key) &&\n params[key] !== undefined &&\n params[key] !== null &&\n params[key] !== ''\n ) {\n filtered[key] = params[key];\n }\n });\n\n return filtered;\n }\n\n // Check if action needs structured parameters\n protected actionNeedsStructuredParams(\n action: DeviceAction<unknown>,\n ): boolean {\n if (\n typeof action.paramSchema === 'object' &&\n 'shape' in action.paramSchema\n ) {\n const shape =\n (action.paramSchema as { shape: Record<string, unknown> }).shape || {};\n return Object.keys(shape).length > 0;\n }\n return true; // If paramSchema exists but not in expected format, assume it needs params\n }\n\n // Prepare parameters for validation by converting string locate fields\n protected prepareParamsForValidation(\n params: Record<string, unknown>,\n action: DeviceAction<unknown>,\n ): Record<string, unknown> {\n const paramsForValidation = { ...params };\n\n if (action.paramSchema) {\n const locatorFieldKeys = findAllMidsceneLocatorField(action.paramSchema);\n locatorFieldKeys.forEach((key: string) => {\n if (typeof paramsForValidation[key] === 'string') {\n paramsForValidation[key] = {\n midscene_location_field_flag: true,\n prompt: paramsForValidation[key],\n center: [0, 0], // dummy values for validation\n rect: { left: 0, top: 0, width: 0, height: 0 },\n };\n }\n });\n }\n\n return paramsForValidation;\n }\n\n // Handle validation errors with proper error message extraction\n protected handleValidationError(error: unknown): ValidationResult {\n const zodError = error as {\n errors?: Array<{ path: string[]; message: string }>;\n };\n\n if (zodError.errors && zodError.errors.length > 0) {\n const errorMessages = zodError.errors\n .filter((err) => {\n const path = err.path.join('.');\n return (\n !path.includes('center') &&\n !path.includes('rect') &&\n !path.includes('midscene_location_field_flag')\n );\n })\n .map((err) => {\n const field = err.path.join('.');\n return `${field}: ${err.message}`;\n });\n\n if (errorMessages.length > 0) {\n return {\n valid: false,\n errorMessage: `Validation error: ${errorMessages.join(', ')}`,\n };\n }\n }\n\n const errorMsg =\n error instanceof Error ? error.message : 'Unknown validation error';\n\n return {\n valid: false,\n errorMessage: `Parameter validation failed: ${errorMsg}`,\n };\n }\n\n // Build display list for parameters\n protected buildParamsDisplayList(\n params: Record<string, unknown>,\n action: DeviceAction<unknown>,\n ): string[] {\n const paramsList: string[] = [];\n const schema = action.paramSchema;\n\n if (!(schema && 'shape' in schema)) {\n return paramsList;\n }\n\n const locatorFieldKeys = findAllMidsceneLocatorField(schema);\n const shapeKeys = Object.keys(\n (schema as { shape: Record<string, unknown> }).shape,\n );\n\n shapeKeys.forEach((key) => {\n const paramValue = params[key];\n if (this.isValidParamValue(paramValue)) {\n const displayKey = this.capitalizeFirstLetter(key);\n const formattedValue = this.formatParamValue(\n key,\n paramValue,\n locatorFieldKeys.includes(key),\n );\n paramsList.push(`${displayKey}: ${formattedValue}`);\n }\n });\n\n return paramsList;\n }\n\n // Check if parameter value is valid for display\n protected isValidParamValue(value: unknown): boolean {\n return value !== undefined && value !== null && value !== '';\n }\n\n // Capitalize first letter of a string\n protected capitalizeFirstLetter(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n }\n\n // Format parameter value for display\n protected formatParamValue(\n key: string,\n value: unknown,\n isLocateField: boolean,\n ): string {\n if (isLocateField || typeof value === 'string') {\n return `\"${value}\"`;\n }\n\n if (typeof value === 'number') {\n // Special handling for distance in scroll\n return key === 'distance' ? `${value}px` : `${value}`;\n }\n\n return `${value}`;\n }\n}\n"],"names":["BasePlaygroundAdapter","_context","value","action","needsStructuredParams","paramsForValidation","error","paramsList","schema","Object","params","excludeKeys","filtered","key","undefined","shape","locatorFieldKeys","findAllMidsceneLocatorField","zodError","errorMessages","err","path","field","errorMsg","Error","shapeKeys","paramValue","displayKey","formattedValue","str","isLocateField"],"mappings":"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"}
@@ -16,31 +16,31 @@ class LocalExecutionAdapter extends BasePlaygroundAdapter {
16
16
  get id() {
17
17
  return this._id;
18
18
  }
19
+ onDumpUpdate(callback) {
20
+ this.dumpUpdateCallback = void 0;
21
+ this.dumpUpdateCallback = callback;
22
+ }
19
23
  setProgressCallback(callback) {
20
24
  this.progressCallback = void 0;
21
25
  this.progressCallback = callback;
22
26
  }
23
- cleanup(requestId) {
24
- delete this.taskProgressTips[requestId];
25
- }
26
27
  async parseStructuredParams(action, params, options) {
27
28
  return await parseStructuredParams(action, params, options);
28
29
  }
29
30
  formatErrorMessage(error) {
30
- const errorMessage = (null == error ? void 0 : error.message) || '';
31
+ const errorMessage = error?.message || '';
31
32
  if (errorMessage.includes('of different extension')) return 'Conflicting extension detected. Please disable the suspicious plugins and refresh the page. Guide: https://midscenejs.com/quick-experience.html#faq';
32
33
  return this.formatBasicErrorMessage(error);
33
34
  }
34
35
  async getActionSpace(context) {
35
- var _this_agent;
36
- if (null == (_this_agent = this.agent) ? void 0 : _this_agent.getActionSpace) return await this.agent.getActionSpace();
36
+ if (this.agent?.getActionSpace) return await this.agent.getActionSpace();
37
37
  if (this.agent && 'interface' in this.agent && 'object' == typeof this.agent.interface) {
38
38
  const page = this.agent.interface;
39
- if (null == page ? void 0 : page.actionSpace) return await page.actionSpace();
39
+ if (page?.actionSpace) return page.actionSpace();
40
40
  }
41
41
  if (context && 'object' == typeof context && 'actionSpace' in context) {
42
42
  const contextPage = context;
43
- return await contextPage.actionSpace();
43
+ return contextPage.actionSpace();
44
44
  }
45
45
  return [];
46
46
  }
@@ -50,58 +50,67 @@ class LocalExecutionAdapter extends BasePlaygroundAdapter {
50
50
  async overrideConfig(aiConfig) {
51
51
  overrideAIConfig(aiConfig);
52
52
  }
53
+ async detachDebuggerSafely() {
54
+ try {
55
+ const page = this.agent?.interface;
56
+ await page?.detachDebugger?.();
57
+ } catch (error) {
58
+ console.warn('Failed to detach debugger:', error);
59
+ }
60
+ }
53
61
  async executeAction(actionType, value, options) {
54
62
  const actionSpace = await this.getActionSpace();
55
- let originalOnTaskStartTip;
63
+ let removeListener;
64
+ try {
65
+ this.agent.resetDump?.();
66
+ } catch (error) {
67
+ console.warn('Failed to reset dump before execution:', error);
68
+ }
56
69
  if (options.requestId && this.agent) {
57
70
  this.currentRequestId = options.requestId;
58
- originalOnTaskStartTip = this.agent.onTaskStartTip;
59
- this.agent.onTaskStartTip = (tip)=>{
71
+ removeListener = this.agent.addDumpUpdateListener((dump, executionDump)=>{
60
72
  if (this.currentRequestId !== options.requestId) return;
61
- this.taskProgressTips[options.requestId] = tip;
62
- if (this.progressCallback) this.progressCallback(tip);
63
- if ('function' == typeof originalOnTaskStartTip) originalOnTaskStartTip(tip);
64
- };
73
+ if (this.dumpUpdateCallback) this.dumpUpdateCallback(dump, executionDump);
74
+ });
65
75
  }
66
76
  try {
67
- const result = await executeAction(this.agent, actionType, actionSpace, value, options);
77
+ let result = null;
78
+ let executionError = null;
79
+ try {
80
+ result = await executeAction(this.agent, actionType, actionSpace, value, options);
81
+ } catch (error) {
82
+ executionError = error;
83
+ }
68
84
  const response = {
69
85
  result,
70
86
  dump: null,
71
87
  reportHTML: null,
72
- error: null
88
+ error: executionError ? executionError instanceof Error ? executionError.message : String(executionError) : null
73
89
  };
74
90
  try {
75
91
  if (this.agent.dumpDataString) {
76
92
  const dumpString = this.agent.dumpDataString();
77
- if (dumpString) response.dump = JSON.parse(dumpString);
93
+ if (dumpString) {
94
+ const groupedDump = JSON.parse(dumpString);
95
+ response.dump = groupedDump.executions?.[0] || null;
96
+ }
78
97
  }
79
98
  if (this.agent.reportHTMLString) response.reportHTML = this.agent.reportHTMLString() || null;
80
99
  if (this.agent.writeOutActionDumps) this.agent.writeOutActionDumps();
81
100
  } catch (error) {
82
101
  console.error('Failed to get dump/reportHTML from agent:', error);
83
102
  }
84
- this.agent.resetDump();
85
103
  return response;
86
104
  } finally{
87
- if (options.requestId) {
88
- this.cleanup(options.requestId);
89
- if (this.agent) this.agent.onTaskStartTip = originalOnTaskStartTip;
90
- }
105
+ if (removeListener) removeListener();
91
106
  }
92
107
  }
93
- async getTaskProgress(requestId) {
94
- return {
95
- tip: this.taskProgressTips[requestId] || void 0
96
- };
97
- }
98
108
  async cancelTask(_requestId) {
99
109
  if (!this.agent) return {
100
110
  error: 'No active agent found for this requestId'
101
111
  };
102
112
  try {
103
- var _this_agent_destroy, _this_agent;
104
- await (null == (_this_agent_destroy = (_this_agent = this.agent).destroy) ? void 0 : _this_agent_destroy.call(_this_agent));
113
+ await this.agent.destroy?.();
105
114
  return {
106
115
  success: true
107
116
  };
@@ -113,13 +122,30 @@ class LocalExecutionAdapter extends BasePlaygroundAdapter {
113
122
  };
114
123
  }
115
124
  }
125
+ async getCurrentExecutionData() {
126
+ const response = {
127
+ dump: null,
128
+ reportHTML: null
129
+ };
130
+ try {
131
+ if (this.agent.dumpDataString) {
132
+ const dumpString = this.agent.dumpDataString();
133
+ if (dumpString) {
134
+ const groupedDump = JSON.parse(dumpString);
135
+ response.dump = groupedDump.executions?.[0] || null;
136
+ }
137
+ }
138
+ if (this.agent.reportHTMLString) response.reportHTML = this.agent.reportHTMLString() || null;
139
+ } catch (error) {
140
+ console.error('Failed to get current execution data:', error);
141
+ }
142
+ return response;
143
+ }
116
144
  async getInterfaceInfo() {
117
- var _this_agent;
118
- if (!(null == (_this_agent = this.agent) ? void 0 : _this_agent.interface)) return null;
145
+ if (!this.agent?.interface) return null;
119
146
  try {
120
- var _this_agent_interface_describe, _this_agent_interface;
121
147
  const type = this.agent.interface.interfaceType || 'Unknown';
122
- const description = (null == (_this_agent_interface_describe = (_this_agent_interface = this.agent.interface).describe) ? void 0 : _this_agent_interface_describe.call(_this_agent_interface)) || void 0;
148
+ const description = this.agent.interface.describe?.() || void 0;
123
149
  return {
124
150
  type,
125
151
  description
@@ -130,7 +156,7 @@ class LocalExecutionAdapter extends BasePlaygroundAdapter {
130
156
  }
131
157
  }
132
158
  constructor(agent){
133
- super(), _define_property(this, "agent", void 0), _define_property(this, "taskProgressTips", {}), _define_property(this, "progressCallback", void 0), _define_property(this, "_id", void 0), _define_property(this, "currentRequestId", void 0);
159
+ super(), _define_property(this, "agent", void 0), _define_property(this, "dumpUpdateCallback", void 0), _define_property(this, "progressCallback", void 0), _define_property(this, "_id", void 0), _define_property(this, "currentRequestId", void 0);
134
160
  this.agent = agent;
135
161
  this._id = uuid();
136
162
  }
@@ -1 +1 @@
1
- {"version":3,"file":"adapters/local-execution.mjs","sources":["webpack://@midscene/playground/./src/adapters/local-execution.ts"],"sourcesContent":["import type { DeviceAction } from '@midscene/core';\nimport { overrideAIConfig } from '@midscene/shared/env';\nimport { uuid } from '@midscene/shared/utils';\nimport { executeAction, parseStructuredParams } from '../common';\nimport type { ExecutionOptions, FormValue, PlaygroundAgent } from '../types';\nimport { BasePlaygroundAdapter } from './base';\n\nexport class LocalExecutionAdapter extends BasePlaygroundAdapter {\n private agent: PlaygroundAgent;\n private taskProgressTips: Record<string, string> = {};\n private progressCallback?: (tip: string) => void;\n private readonly _id: string; // Unique identifier for this local adapter instance\n private currentRequestId?: string; // Track current request to prevent stale callbacks\n\n constructor(agent: PlaygroundAgent) {\n super();\n this.agent = agent;\n this._id = uuid(); // Generate unique ID for local adapter\n }\n\n // Get adapter ID\n get id(): string {\n return this._id;\n }\n\n setProgressCallback(callback: (tip: string) => void): void {\n // Clear any existing callback before setting new one\n this.progressCallback = undefined;\n // Set the new callback\n this.progressCallback = callback;\n }\n\n private cleanup(requestId: string): void {\n delete this.taskProgressTips[requestId];\n }\n\n async parseStructuredParams(\n action: DeviceAction<unknown>,\n params: Record<string, unknown>,\n options: ExecutionOptions,\n ): Promise<unknown[]> {\n // Use shared implementation from common.ts\n return await parseStructuredParams(action, params, options);\n }\n\n formatErrorMessage(error: any): string {\n const errorMessage = error?.message || '';\n if (errorMessage.includes('of different extension')) {\n return 'Conflicting extension detected. Please disable the suspicious plugins and refresh the page. Guide: https://midscenejs.com/quick-experience.html#faq';\n }\n return this.formatBasicErrorMessage(error);\n }\n\n // Local execution - use base implementation\n // (inherits default executeAction from BasePlaygroundAdapter)\n\n // Local execution gets actionSpace from internal agent (parameter is for backward compatibility)\n async getActionSpace(context?: unknown): Promise<DeviceAction<unknown>[]> {\n // Priority 1: Use agent's getActionSpace method\n if (this.agent?.getActionSpace) {\n return await this.agent.getActionSpace();\n }\n\n // Priority 2: Use agent's interface.actionSpace method\n if (\n this.agent &&\n 'interface' in this.agent &&\n typeof this.agent.interface === 'object'\n ) {\n const page = this.agent.interface as {\n actionSpace?: () => Promise<DeviceAction<unknown>[]>;\n };\n if (page?.actionSpace) {\n return await page.actionSpace();\n }\n }\n\n // Priority 3: Fallback to context parameter (for backward compatibility with tests)\n if (context && typeof context === 'object' && 'actionSpace' in context) {\n const contextPage = context as {\n actionSpace: () => Promise<DeviceAction<unknown>[]>;\n };\n return await contextPage.actionSpace();\n }\n\n return [];\n }\n\n // Local execution doesn't use a server, so always return true\n async checkStatus(): Promise<boolean> {\n return true;\n }\n\n async overrideConfig(aiConfig: Record<string, unknown>): Promise<void> {\n // For local execution, use the shared env override function\n overrideAIConfig(aiConfig);\n }\n\n async executeAction(\n actionType: string,\n value: FormValue,\n options: ExecutionOptions,\n ): Promise<unknown> {\n // Get actionSpace using our simplified getActionSpace method\n const actionSpace = await this.getActionSpace();\n let originalOnTaskStartTip: ((tip: string) => void) | undefined;\n\n // Setup progress tracking if requestId is provided\n if (options.requestId && this.agent) {\n // Track current request ID to prevent stale callbacks\n this.currentRequestId = options.requestId;\n originalOnTaskStartTip = this.agent.onTaskStartTip;\n\n // Set up a fresh callback\n this.agent.onTaskStartTip = (tip: string) => {\n // Only process if this is still the current request\n if (this.currentRequestId !== options.requestId) {\n return;\n }\n\n // Store tip for our progress tracking\n this.taskProgressTips[options.requestId!] = tip;\n\n // Call the direct progress callback set via setProgressCallback\n if (this.progressCallback) {\n this.progressCallback(tip);\n }\n\n if (typeof originalOnTaskStartTip === 'function') {\n originalOnTaskStartTip(tip);\n }\n };\n }\n\n try {\n // Call the base implementation with the original signature\n const result = await executeAction(\n this.agent,\n actionType,\n actionSpace,\n value,\n options,\n );\n\n // For local execution, we need to package the result with dump and reportHTML\n // similar to how the server does it\n const response = {\n result,\n dump: null as unknown,\n reportHTML: null as string | null,\n error: null as string | null,\n };\n\n try {\n // Get dump and reportHTML from agent like the server does\n if (this.agent.dumpDataString) {\n const dumpString = this.agent.dumpDataString();\n if (dumpString) {\n response.dump = JSON.parse(dumpString);\n }\n }\n\n if (this.agent.reportHTMLString) {\n response.reportHTML = this.agent.reportHTMLString() || null;\n }\n\n // Write out action dumps\n if (this.agent.writeOutActionDumps) {\n this.agent.writeOutActionDumps();\n }\n } catch (error: unknown) {\n console.error('Failed to get dump/reportHTML from agent:', error);\n }\n\n this.agent.resetDump();\n\n return response;\n } finally {\n // Always clean up progress tracking to prevent memory leaks\n if (options.requestId) {\n this.cleanup(options.requestId);\n // Clear the agent callback to prevent accumulation\n if (this.agent) {\n this.agent.onTaskStartTip = originalOnTaskStartTip;\n }\n }\n }\n }\n\n async getTaskProgress(requestId: string): Promise<{ tip?: string }> {\n // Return the stored tip for this requestId\n return { tip: this.taskProgressTips[requestId] || undefined };\n }\n\n // Local execution task cancellation - minimal implementation\n async cancelTask(\n _requestId: string,\n ): Promise<{ error?: string; success?: boolean }> {\n if (!this.agent) {\n return { error: 'No active agent found for this requestId' };\n }\n\n try {\n await this.agent.destroy?.();\n return { success: true };\n } catch (error: unknown) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error';\n console.error(`Failed to cancel agent: ${errorMessage}`);\n return { error: `Failed to cancel: ${errorMessage}` };\n }\n }\n\n // Get interface information from the agent\n async getInterfaceInfo(): Promise<{\n type: string;\n description?: string;\n } | null> {\n if (!this.agent?.interface) {\n return null;\n }\n\n try {\n const type = this.agent.interface.interfaceType || 'Unknown';\n const description = this.agent.interface.describe?.() || undefined;\n\n return {\n type,\n description,\n };\n } catch (error: unknown) {\n console.error('Failed to get interface info:', error);\n return null;\n }\n }\n}\n"],"names":["LocalExecutionAdapter","BasePlaygroundAdapter","callback","undefined","requestId","action","params","options","parseStructuredParams","error","errorMessage","context","_this_agent","page","contextPage","aiConfig","overrideAIConfig","actionType","value","actionSpace","originalOnTaskStartTip","tip","result","executeAction","response","dumpString","JSON","console","_requestId","Error","_this_agent_interface","type","description","agent","uuid"],"mappings":"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"}
1
+ {"version":3,"file":"adapters/local-execution.mjs","sources":["../../../src/adapters/local-execution.ts"],"sourcesContent":["import type { DeviceAction, ExecutionDump } from '@midscene/core';\nimport { overrideAIConfig } from '@midscene/shared/env';\nimport { uuid } from '@midscene/shared/utils';\nimport { executeAction, parseStructuredParams } from '../common';\nimport type { ExecutionOptions, FormValue, PlaygroundAgent } from '../types';\nimport { BasePlaygroundAdapter } from './base';\n\nexport class LocalExecutionAdapter extends BasePlaygroundAdapter {\n private agent: PlaygroundAgent;\n private dumpUpdateCallback?: (\n dump: string,\n executionDump?: ExecutionDump,\n ) => void;\n private progressCallback?: (tip: string) => void;\n private readonly _id: string; // Unique identifier for this local adapter instance\n private currentRequestId?: string; // Track current request to prevent stale callbacks\n\n constructor(agent: PlaygroundAgent) {\n super();\n this.agent = agent;\n this._id = uuid(); // Generate unique ID for local adapter\n }\n\n // Get adapter ID\n get id(): string {\n return this._id;\n }\n\n onDumpUpdate(\n callback: (dump: string, executionDump?: ExecutionDump) => void,\n ): void {\n // Clear any existing callback before setting new one\n this.dumpUpdateCallback = undefined;\n // Set the new callback\n this.dumpUpdateCallback = callback;\n }\n\n // Set progress callback for monitoring operation status\n setProgressCallback(callback: (tip: string) => void): void {\n this.progressCallback = undefined;\n this.progressCallback = callback;\n }\n\n async parseStructuredParams(\n action: DeviceAction<unknown>,\n params: Record<string, unknown>,\n options: ExecutionOptions,\n ): Promise<unknown[]> {\n // Use shared implementation from common.ts\n return await parseStructuredParams(action, params, options);\n }\n\n formatErrorMessage(error: any): string {\n const errorMessage = error?.message || '';\n if (errorMessage.includes('of different extension')) {\n return 'Conflicting extension detected. Please disable the suspicious plugins and refresh the page. Guide: https://midscenejs.com/quick-experience.html#faq';\n }\n return this.formatBasicErrorMessage(error);\n }\n\n // Local execution - use base implementation\n // (inherits default executeAction from BasePlaygroundAdapter)\n\n // Local execution gets actionSpace from internal agent (parameter is for backward compatibility)\n async getActionSpace(context?: unknown): Promise<DeviceAction<unknown>[]> {\n // Priority 1: Use agent's getActionSpace method\n if (this.agent?.getActionSpace) {\n return await this.agent.getActionSpace();\n }\n\n // Priority 2: Use agent's interface.actionSpace method\n if (\n this.agent &&\n 'interface' in this.agent &&\n typeof this.agent.interface === 'object'\n ) {\n const page = this.agent.interface as {\n actionSpace?: () => DeviceAction<unknown>[];\n };\n if (page?.actionSpace) {\n return page.actionSpace();\n }\n }\n\n // Priority 3: Fallback to context parameter (for backward compatibility with tests)\n if (context && typeof context === 'object' && 'actionSpace' in context) {\n const contextPage = context as {\n actionSpace: () => DeviceAction<unknown>[];\n };\n return contextPage.actionSpace();\n }\n\n return [];\n }\n\n // Local execution doesn't use a server, so always return true\n async checkStatus(): Promise<boolean> {\n return true;\n }\n\n async overrideConfig(aiConfig: Record<string, unknown>): Promise<void> {\n // For local execution, use the shared env override function\n overrideAIConfig(aiConfig);\n }\n\n /**\n * Safely detaches the Chrome debugger without destroying the agent.\n * This removes the \"Debugger attached\" banner from the browser window\n * while keeping the agent instance intact for potential reuse.\n * Called on errors to improve user experience by cleaning up the UI.\n */\n private async detachDebuggerSafely() {\n try {\n const page = this.agent?.interface as\n | { detachDebugger?: () => Promise<void> }\n | undefined;\n await page?.detachDebugger?.();\n } catch (error) {\n console.warn('Failed to detach debugger:', error);\n }\n }\n\n async executeAction(\n actionType: string,\n value: FormValue,\n options: ExecutionOptions,\n ): Promise<unknown> {\n // Get actionSpace using our simplified getActionSpace method\n const actionSpace = await this.getActionSpace();\n let removeListener: (() => void) | undefined;\n\n // Reset dump at the start of execution to ensure clean state\n try {\n this.agent.resetDump?.();\n } catch (error: unknown) {\n console.warn('Failed to reset dump before execution:', error);\n }\n\n // Setup dump update tracking if requestId is provided\n if (options.requestId && this.agent) {\n // Track current request ID to prevent stale callbacks\n this.currentRequestId = options.requestId;\n\n // Add listener and save remove function\n removeListener = this.agent.addDumpUpdateListener(\n (dump: string, executionDump?: ExecutionDump) => {\n // Only process if this is still the current request\n if (this.currentRequestId !== options.requestId) {\n return;\n }\n\n // Forward to external callback\n if (this.dumpUpdateCallback) {\n this.dumpUpdateCallback(dump, executionDump);\n }\n },\n );\n }\n\n try {\n let result = null;\n let executionError = null;\n\n try {\n // Call the base implementation with the original signature\n result = await executeAction(\n this.agent,\n actionType,\n actionSpace,\n value,\n options,\n );\n } catch (error: unknown) {\n // Capture error but don't throw yet - we need to get dump/reportHTML first\n executionError = error;\n }\n\n // Always construct response with dump and reportHTML, regardless of success/failure\n const response = {\n result,\n dump: null as unknown,\n reportHTML: null as string | null,\n error: executionError\n ? executionError instanceof Error\n ? executionError.message\n : String(executionError)\n : null,\n };\n\n try {\n if (this.agent.dumpDataString) {\n const dumpString = this.agent.dumpDataString();\n if (dumpString) {\n const groupedDump = JSON.parse(dumpString);\n response.dump = groupedDump.executions?.[0] || null;\n }\n }\n\n // Always generate reportHTML for all APIs (including noReplayAPIs)\n if (this.agent.reportHTMLString) {\n response.reportHTML = this.agent.reportHTMLString() || null;\n }\n\n // Write out action dumps\n if (this.agent.writeOutActionDumps) {\n this.agent.writeOutActionDumps();\n }\n } catch (error: unknown) {\n console.error('Failed to get dump/reportHTML from agent:', error);\n }\n\n // Don't throw the error - return it in response so caller can access dump/reportHTML\n // The caller (usePlaygroundExecution) will check response.error to determine success\n return response;\n } finally {\n // Remove listener to prevent accumulation\n if (removeListener) {\n removeListener();\n }\n }\n }\n\n // Local execution task cancellation - minimal implementation\n async cancelTask(\n _requestId: string,\n ): Promise<{ error?: string; success?: boolean }> {\n if (!this.agent) {\n return { error: 'No active agent found for this requestId' };\n }\n\n try {\n await this.agent.destroy?.();\n return { success: true };\n } catch (error: unknown) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error';\n console.error(`Failed to cancel agent: ${errorMessage}`);\n return { error: `Failed to cancel: ${errorMessage}` };\n }\n }\n\n /**\n * Get current execution data without resetting\n * This allows retrieving dump and report when execution is stopped\n */\n async getCurrentExecutionData(): Promise<{\n dump: ExecutionDump | null;\n reportHTML: string | null;\n }> {\n const response = {\n dump: null as ExecutionDump | null,\n reportHTML: null as string | null,\n };\n\n try {\n // Get dump data\n if (this.agent.dumpDataString) {\n const dumpString = this.agent.dumpDataString();\n if (dumpString) {\n const groupedDump = JSON.parse(dumpString);\n response.dump = groupedDump.executions?.[0] || null;\n }\n }\n\n // Get report HTML\n if (this.agent.reportHTMLString) {\n response.reportHTML = this.agent.reportHTMLString() || null;\n }\n } catch (error: unknown) {\n console.error('Failed to get current execution data:', error);\n }\n\n return response;\n }\n\n // Get interface information from the agent\n async getInterfaceInfo(): Promise<{\n type: string;\n description?: string;\n } | null> {\n if (!this.agent?.interface) {\n return null;\n }\n\n try {\n const type = this.agent.interface.interfaceType || 'Unknown';\n const description = this.agent.interface.describe?.() || undefined;\n\n return {\n type,\n description,\n };\n } catch (error: unknown) {\n console.error('Failed to get interface info:', error);\n return null;\n }\n }\n}\n"],"names":["LocalExecutionAdapter","BasePlaygroundAdapter","callback","undefined","action","params","options","parseStructuredParams","error","errorMessage","context","page","contextPage","aiConfig","overrideAIConfig","console","actionType","value","actionSpace","removeListener","dump","executionDump","result","executionError","executeAction","response","Error","String","dumpString","groupedDump","JSON","_requestId","type","description","agent","uuid"],"mappings":"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"}
@@ -11,11 +11,14 @@ function _define_property(obj, key, value) {
11
11
  return obj;
12
12
  }
13
13
  class RemoteExecutionAdapter extends BasePlaygroundAdapter {
14
+ setProgressCallback(callback) {
15
+ this.progressCallback = callback;
16
+ }
14
17
  get id() {
15
18
  return this._id;
16
19
  }
17
20
  validateParams(value, action) {
18
- if (!(null == action ? void 0 : action.paramSchema)) return {
21
+ if (!action?.paramSchema) return {
19
22
  valid: true
20
23
  };
21
24
  const needsStructuredParams = this.actionNeedsStructuredParams(action);
@@ -31,9 +34,8 @@ class RemoteExecutionAdapter extends BasePlaygroundAdapter {
31
34
  if (schema.shape || 'ZodObject' === schema.type) {
32
35
  const shape = schema.shape || {};
33
36
  const missingFields = Object.keys(shape).filter((key)=>{
34
- var _fieldDef__def, _fieldDef__def1;
35
37
  const fieldDef = shape[key];
36
- const isOptional = (null == fieldDef ? void 0 : fieldDef.isOptional) || (null == fieldDef ? void 0 : null == (_fieldDef__def = fieldDef._def) ? void 0 : _fieldDef__def.innerType) || (null == fieldDef ? void 0 : null == (_fieldDef__def1 = fieldDef._def) ? void 0 : _fieldDef__def1.typeName) === 'ZodOptional';
38
+ const isOptional = fieldDef?.isOptional || fieldDef?._def?.innerType || fieldDef?._def?.typeName === 'ZodOptional';
37
39
  return !isOptional && (void 0 === value.params[key] || '' === value.params[key]);
38
40
  });
39
41
  if (missingFields.length > 0) return {
@@ -50,7 +52,7 @@ class RemoteExecutionAdapter extends BasePlaygroundAdapter {
50
52
  return await parseStructuredParams(action, params, options);
51
53
  }
52
54
  formatErrorMessage(error) {
53
- const message = (null == error ? void 0 : error.message) || '';
55
+ const message = error?.message || '';
54
56
  const androidErrors = [
55
57
  {
56
58
  keyword: 'adb',
@@ -76,7 +78,6 @@ class RemoteExecutionAdapter extends BasePlaygroundAdapter {
76
78
  ...this.buildOptionalPayloadParams(options, value)
77
79
  };
78
80
  if (options.context) payload.context = options.context;
79
- if (options.requestId && this.progressCallback) this.startProgressPolling(options.requestId, this.progressCallback);
80
81
  try {
81
82
  const response = await fetch(`${this.serverUrl}/execute`, {
82
83
  method: 'POST',
@@ -90,10 +91,8 @@ class RemoteExecutionAdapter extends BasePlaygroundAdapter {
90
91
  throw new Error(`Server request failed (${response.status}): ${errorText}`);
91
92
  }
92
93
  const result = await response.json();
93
- if (options.requestId) this.stopProgressPolling(options.requestId);
94
94
  return result;
95
95
  } catch (error) {
96
- if (options.requestId) this.stopProgressPolling(options.requestId);
97
96
  console.error('Execute via server failed:', error);
98
97
  throw error;
99
98
  }
@@ -117,6 +116,10 @@ class RemoteExecutionAdapter extends BasePlaygroundAdapter {
117
116
  key: 'domIncluded',
118
117
  value: options.domIncluded
119
118
  },
119
+ {
120
+ key: 'deviceOptions',
121
+ value: options.deviceOptions
122
+ },
120
123
  {
121
124
  key: 'params',
122
125
  value: value.params
@@ -194,7 +197,7 @@ class RemoteExecutionAdapter extends BasePlaygroundAdapter {
194
197
  if (!this.serverUrl) return {
195
198
  tip: void 0
196
199
  };
197
- if (!(null == requestId ? void 0 : requestId.trim())) {
200
+ if (!requestId?.trim()) {
198
201
  console.warn('Invalid requestId provided for task progress');
199
202
  return {
200
203
  tip: void 0
@@ -217,11 +220,10 @@ class RemoteExecutionAdapter extends BasePlaygroundAdapter {
217
220
  }
218
221
  }
219
222
  async cancelTask(requestId) {
220
- this.stopProgressPolling(requestId);
221
223
  if (!this.serverUrl) return {
222
224
  error: 'No server URL configured'
223
225
  };
224
- if (!(null == requestId ? void 0 : requestId.trim())) return {
226
+ if (!requestId?.trim()) return {
225
227
  error: 'Invalid request ID'
226
228
  };
227
229
  try {
@@ -243,33 +245,6 @@ class RemoteExecutionAdapter extends BasePlaygroundAdapter {
243
245
  };
244
246
  }
245
247
  }
246
- setProgressCallback(callback) {
247
- this.progressCallback = callback;
248
- }
249
- startProgressPolling(requestId, callback) {
250
- if (this.progressPolling.has(requestId)) return;
251
- let lastTip = '';
252
- const interval = setInterval(async ()=>{
253
- try {
254
- var _progress_tip_trim, _progress_tip;
255
- const progress = await this.getTaskProgress(requestId);
256
- if ((null == progress ? void 0 : null == (_progress_tip = progress.tip) ? void 0 : null == (_progress_tip_trim = _progress_tip.trim) ? void 0 : _progress_tip_trim.call(_progress_tip)) && progress.tip !== lastTip) {
257
- lastTip = progress.tip;
258
- callback(progress.tip);
259
- }
260
- } catch (error) {
261
- console.debug('Progress polling error:', error);
262
- }
263
- }, 500);
264
- this.progressPolling.set(requestId, interval);
265
- }
266
- stopProgressPolling(requestId) {
267
- const interval = this.progressPolling.get(requestId);
268
- if (interval) {
269
- clearInterval(interval);
270
- this.progressPolling.delete(requestId);
271
- }
272
- }
273
248
  async getScreenshot() {
274
249
  if (!this.serverUrl) return null;
275
250
  try {
@@ -299,7 +274,7 @@ class RemoteExecutionAdapter extends BasePlaygroundAdapter {
299
274
  }
300
275
  }
301
276
  constructor(serverUrl){
302
- super(), _define_property(this, "serverUrl", void 0), _define_property(this, "progressPolling", new Map()), _define_property(this, "progressCallback", void 0), _define_property(this, "_id", void 0);
277
+ super(), _define_property(this, "serverUrl", void 0), _define_property(this, "_id", void 0), _define_property(this, "progressCallback", void 0);
303
278
  this.serverUrl = serverUrl;
304
279
  }
305
280
  }
@@ -1 +1 @@
1
- {"version":3,"file":"adapters/remote-execution.mjs","sources":["webpack://@midscene/playground/./src/adapters/remote-execution.ts"],"sourcesContent":["import type { DeviceAction } 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 progressPolling = new Map<string, NodeJS.Timeout>();\n private progressCallback?: (tip: string) => void;\n private _id?: string;\n\n constructor(serverUrl: string) {\n super();\n this.serverUrl = serverUrl;\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 progress polling if callback is set and requestId exists\n if (options.requestId && this.progressCallback) {\n this.startProgressPolling(options.requestId, this.progressCallback);\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 // Stop progress polling when execution completes\n if (options.requestId) {\n this.stopProgressPolling(options.requestId);\n }\n\n return result;\n } catch (error) {\n // Stop progress polling on error\n if (options.requestId) {\n this.stopProgressPolling(options.requestId);\n }\n console.error('Execute via server failed:', error);\n throw error;\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: '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 { actionSpace: () => Promise<DeviceAction<unknown>[]> }\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<{ tip?: string }> {\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 // Cancel task\n async cancelTask(\n requestId: string,\n ): Promise<{ error?: string; success?: boolean }> {\n // Stop progress polling\n this.stopProgressPolling(requestId);\n\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 // Progress callback management\n setProgressCallback(callback: (tip: string) => void): void {\n this.progressCallback = callback;\n }\n\n // Start progress polling\n private startProgressPolling(\n requestId: string,\n callback: (tip: string) => void,\n ): void {\n // Don't start multiple polling for the same request\n if (this.progressPolling.has(requestId)) {\n return;\n }\n\n let lastTip = '';\n const interval = setInterval(async () => {\n try {\n const progress = await this.getTaskProgress(requestId);\n if (progress?.tip?.trim?.() && progress.tip !== lastTip) {\n lastTip = progress.tip;\n callback(progress.tip);\n }\n } catch (error) {\n // Silently ignore progress polling errors to avoid spam\n console.debug('Progress polling error:', error);\n }\n }, 500); // Poll every 500ms\n\n this.progressPolling.set(requestId, interval);\n }\n\n // Stop progress polling\n private stopProgressPolling(requestId: string): void {\n const interval = this.progressPolling.get(requestId);\n if (interval) {\n clearInterval(interval);\n this.progressPolling.delete(requestId);\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":["RemoteExecutionAdapter","BasePlaygroundAdapter","value","action","needsStructuredParams","schema","shape","missingFields","Object","key","_fieldDef__def","_fieldDef__def1","fieldDef","isOptional","undefined","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","callback","lastTip","interval","setInterval","_progress_tip","progress","clearInterval","serverUrl","Map"],"mappings":"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"}
1
+ {"version":3,"file":"adapters/remote-execution.mjs","sources":["../../../src/adapters/remote-execution.ts"],"sourcesContent":["import type { DeviceAction } 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 progressCallback?: (tip: string) => void;\n\n constructor(serverUrl: string) {\n super();\n this.serverUrl = serverUrl;\n }\n\n // Set progress callback for monitoring operation status\n setProgressCallback(callback: (tip: string) => void): void {\n this.progressCallback = 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 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 }\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<{ tip?: string }> {\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 // 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":["RemoteExecutionAdapter","BasePlaygroundAdapter","callback","value","action","needsStructuredParams","schema","shape","missingFields","Object","key","fieldDef","isOptional","undefined","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","serverUrl"],"mappings":"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"}