@sqaitech/playground 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/adapters/base.mjs +131 -0
- package/dist/es/adapters/base.mjs.map +1 -0
- package/dist/es/adapters/local-execution.mjs +140 -0
- package/dist/es/adapters/local-execution.mjs.map +1 -0
- package/dist/es/adapters/remote-execution.mjs +308 -0
- package/dist/es/adapters/remote-execution.mjs.map +1 -0
- package/dist/es/common.mjs +148 -0
- package/dist/es/common.mjs.map +1 -0
- package/dist/es/index.browser.mjs +9 -0
- package/dist/es/index.browser.mjs.map +1 -0
- package/dist/es/index.mjs +8 -0
- package/dist/es/launcher.mjs +95 -0
- package/dist/es/launcher.mjs.map +1 -0
- package/dist/es/sdk/index.mjs +102 -0
- package/dist/es/sdk/index.mjs.map +1 -0
- package/dist/es/server.mjs +385 -0
- package/dist/es/server.mjs.map +1 -0
- package/dist/es/types.mjs +0 -0
- package/dist/lib/adapters/base.js +165 -0
- package/dist/lib/adapters/base.js.map +1 -0
- package/dist/lib/adapters/local-execution.js +174 -0
- package/dist/lib/adapters/local-execution.js.map +1 -0
- package/dist/lib/adapters/remote-execution.js +342 -0
- package/dist/lib/adapters/remote-execution.js.map +1 -0
- package/dist/lib/common.js +200 -0
- package/dist/lib/common.js.map +1 -0
- package/dist/lib/index.browser.js +73 -0
- package/dist/lib/index.browser.js.map +1 -0
- package/dist/lib/index.js +77 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/launcher.js +140 -0
- package/dist/lib/launcher.js.map +1 -0
- package/dist/lib/sdk/index.js +136 -0
- package/dist/lib/sdk/index.js.map +1 -0
- package/dist/lib/server.js +435 -0
- package/dist/lib/server.js.map +1 -0
- package/dist/lib/types.js +20 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/types/adapters/base.d.ts +20 -0
- package/dist/types/adapters/local-execution.d.ts +31 -0
- package/dist/types/adapters/remote-execution.d.ts +38 -0
- package/dist/types/common.d.ts +9 -0
- package/dist/types/index.browser.d.ts +7 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/launcher.d.ts +97 -0
- package/dist/types/sdk/index.d.ts +31 -0
- package/dist/types/server.d.ts +75 -0
- package/dist/types/types.d.ts +49 -0
- package/package.json +51 -0
- package/static/favicon.ico +0 -0
- package/static/index.html +1 -0
- package/static/static/css/index.60c69390.css +2 -0
- package/static/static/css/index.60c69390.css.map +1 -0
- package/static/static/image/sqai-logo.b7f781cd.png +0 -0
- package/static/static/js/931.dc961e99.js +620 -0
- package/static/static/js/931.dc961e99.js.LICENSE.txt +146 -0
- package/static/static/js/931.dc961e99.js.map +1 -0
- package/static/static/js/async/173.9cf6b074.js +3 -0
- package/static/static/js/async/173.9cf6b074.js.map +1 -0
- package/static/static/js/async/212.e243c338.js +158 -0
- package/static/static/js/async/212.e243c338.js.map +1 -0
- package/static/static/js/async/329.f888b505.js +26 -0
- package/static/static/js/async/329.f888b505.js.map +1 -0
- package/static/static/js/async/364.1821e74b.js +30 -0
- package/static/static/js/async/364.1821e74b.js.map +1 -0
- package/static/static/js/async/544.b73fa603.js +2 -0
- package/static/static/js/async/544.b73fa603.js.map +1 -0
- package/static/static/js/async/582.5dccae2d.js +21 -0
- package/static/static/js/async/582.5dccae2d.js.map +1 -0
- package/static/static/js/async/624.45ee2b2c.js +3 -0
- package/static/static/js/async/624.45ee2b2c.js.map +1 -0
- package/static/static/js/async/644.6bdc4065.js +1 -0
- package/static/static/js/async/659.9afd03db.js +21 -0
- package/static/static/js/async/659.9afd03db.js.map +1 -0
- package/static/static/js/async/702.60261735.js +231 -0
- package/static/static/js/async/702.60261735.js.map +1 -0
- package/static/static/js/async/920.7d9a9aa8.js +2 -0
- package/static/static/js/async/920.7d9a9aa8.js.map +1 -0
- package/static/static/js/async/983.8b91303f.js +1 -0
- package/static/static/js/index.0c5d4f3b.js +10 -0
- package/static/static/js/index.0c5d4f3b.js.LICENSE.txt +7 -0
- package/static/static/js/index.0c5d4f3b.js.map +1 -0
- package/static/static/js/index.3890f2de.js +10 -0
- package/static/static/js/index.3890f2de.js.LICENSE.txt +7 -0
- package/static/static/js/index.3890f2de.js.map +1 -0
- package/static/static/js/index.39b0d1ea.js +10 -0
- package/static/static/js/index.39b0d1ea.js.LICENSE.txt +7 -0
- package/static/static/js/index.39b0d1ea.js.map +1 -0
- package/static/static/js/index.3f24d218.js +10 -0
- package/static/static/js/index.3f24d218.js.LICENSE.txt +7 -0
- package/static/static/js/index.3f24d218.js.map +1 -0
- package/static/static/js/index.5cccbdaf.js +10 -0
- package/static/static/js/index.5cccbdaf.js.LICENSE.txt +7 -0
- package/static/static/js/index.5cccbdaf.js.map +1 -0
- package/static/static/js/index.8a10896b.js +10 -0
- package/static/static/js/index.8a10896b.js.LICENSE.txt +7 -0
- package/static/static/js/index.8a10896b.js.map +1 -0
- package/static/static/js/index.afc8ef37.js +10 -0
- package/static/static/js/index.afc8ef37.js.LICENSE.txt +7 -0
- package/static/static/js/index.afc8ef37.js.map +1 -0
- package/static/static/js/index.b8a17a87.js +10 -0
- package/static/static/js/index.b8a17a87.js.LICENSE.txt +7 -0
- package/static/static/js/index.b8a17a87.js.map +1 -0
- package/static/static/js/index.d0dcab60.js +10 -0
- package/static/static/js/index.d0dcab60.js.LICENSE.txt +7 -0
- package/static/static/js/index.d0dcab60.js.map +1 -0
- package/static/static/js/index.f21bb1df.js +10 -0
- package/static/static/js/index.f21bb1df.js.LICENSE.txt +7 -0
- package/static/static/js/index.f21bb1df.js.map +1 -0
- package/static/static/js/lib-react.f566a9ed.js +3 -0
- package/static/static/js/lib-react.f566a9ed.js.LICENSE.txt +39 -0
- package/static/static/js/lib-react.f566a9ed.js.map +1 -0
- package/static/static/svg/server-offline-foreground.3113df3c.svg +36 -0
- package/static/static/wasm/9e906fbf55e08f98.module.wasm +0 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { findAllMidsceneLocatorField } from "@sqaitech/core/ai-model";
|
|
2
|
+
class BasePlaygroundAdapter {
|
|
3
|
+
async getActionSpace(_context) {
|
|
4
|
+
return [];
|
|
5
|
+
}
|
|
6
|
+
validateParams(value, action) {
|
|
7
|
+
if (!(null == action ? void 0 : action.paramSchema)) return {
|
|
8
|
+
valid: true
|
|
9
|
+
};
|
|
10
|
+
const needsStructuredParams = this.actionNeedsStructuredParams(action);
|
|
11
|
+
if (!needsStructuredParams) return {
|
|
12
|
+
valid: true
|
|
13
|
+
};
|
|
14
|
+
if (!value.params) return {
|
|
15
|
+
valid: false,
|
|
16
|
+
errorMessage: 'Parameters are required'
|
|
17
|
+
};
|
|
18
|
+
try {
|
|
19
|
+
const paramsForValidation = this.prepareParamsForValidation(value.params, action);
|
|
20
|
+
action.paramSchema.parse(paramsForValidation);
|
|
21
|
+
return {
|
|
22
|
+
valid: true
|
|
23
|
+
};
|
|
24
|
+
} catch (error) {
|
|
25
|
+
return this.handleValidationError(error);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
createDisplayContent(value, needsStructuredParams, action) {
|
|
29
|
+
if (!needsStructuredParams || !value.params || !(null == action ? void 0 : action.paramSchema)) return value.prompt || '';
|
|
30
|
+
const paramsList = this.buildParamsDisplayList(value.params, action);
|
|
31
|
+
return paramsList.join('\n') || value.prompt || '';
|
|
32
|
+
}
|
|
33
|
+
formatBasicErrorMessage(error) {
|
|
34
|
+
return (null == error ? void 0 : error.message) || 'Unknown error';
|
|
35
|
+
}
|
|
36
|
+
getSchemaKeys(action) {
|
|
37
|
+
if (!(null == action ? void 0 : action.paramSchema) || !('shape' in action.paramSchema)) return [];
|
|
38
|
+
const schema = action.paramSchema;
|
|
39
|
+
return schema && 'shape' in schema ? Object.keys(schema.shape) : [];
|
|
40
|
+
}
|
|
41
|
+
filterValidParams(params, excludeKeys = []) {
|
|
42
|
+
const filtered = {};
|
|
43
|
+
Object.keys(params).forEach((key)=>{
|
|
44
|
+
if (!excludeKeys.includes(key) && void 0 !== params[key] && null !== params[key] && '' !== params[key]) filtered[key] = params[key];
|
|
45
|
+
});
|
|
46
|
+
return filtered;
|
|
47
|
+
}
|
|
48
|
+
actionNeedsStructuredParams(action) {
|
|
49
|
+
if ('object' == typeof action.paramSchema && 'shape' in action.paramSchema) {
|
|
50
|
+
const shape = action.paramSchema.shape || {};
|
|
51
|
+
return Object.keys(shape).length > 0;
|
|
52
|
+
}
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
prepareParamsForValidation(params, action) {
|
|
56
|
+
const paramsForValidation = {
|
|
57
|
+
...params
|
|
58
|
+
};
|
|
59
|
+
if (action.paramSchema) {
|
|
60
|
+
const locatorFieldKeys = findAllMidsceneLocatorField(action.paramSchema);
|
|
61
|
+
locatorFieldKeys.forEach((key)=>{
|
|
62
|
+
if ('string' == typeof paramsForValidation[key]) paramsForValidation[key] = {
|
|
63
|
+
midscene_location_field_flag: true,
|
|
64
|
+
prompt: paramsForValidation[key],
|
|
65
|
+
center: [
|
|
66
|
+
0,
|
|
67
|
+
0
|
|
68
|
+
],
|
|
69
|
+
rect: {
|
|
70
|
+
left: 0,
|
|
71
|
+
top: 0,
|
|
72
|
+
width: 0,
|
|
73
|
+
height: 0
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return paramsForValidation;
|
|
79
|
+
}
|
|
80
|
+
handleValidationError(error) {
|
|
81
|
+
const zodError = error;
|
|
82
|
+
if (zodError.errors && zodError.errors.length > 0) {
|
|
83
|
+
const errorMessages = zodError.errors.filter((err)=>{
|
|
84
|
+
const path = err.path.join('.');
|
|
85
|
+
return !path.includes('center') && !path.includes('rect') && !path.includes('midscene_location_field_flag');
|
|
86
|
+
}).map((err)=>{
|
|
87
|
+
const field = err.path.join('.');
|
|
88
|
+
return `${field}: ${err.message}`;
|
|
89
|
+
});
|
|
90
|
+
if (errorMessages.length > 0) return {
|
|
91
|
+
valid: false,
|
|
92
|
+
errorMessage: `Validation error: ${errorMessages.join(', ')}`
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
const errorMsg = error instanceof Error ? error.message : 'Unknown validation error';
|
|
96
|
+
return {
|
|
97
|
+
valid: false,
|
|
98
|
+
errorMessage: `Parameter validation failed: ${errorMsg}`
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
buildParamsDisplayList(params, action) {
|
|
102
|
+
const paramsList = [];
|
|
103
|
+
const schema = action.paramSchema;
|
|
104
|
+
if (!(schema && 'shape' in schema)) return paramsList;
|
|
105
|
+
const locatorFieldKeys = findAllMidsceneLocatorField(schema);
|
|
106
|
+
const shapeKeys = Object.keys(schema.shape);
|
|
107
|
+
shapeKeys.forEach((key)=>{
|
|
108
|
+
const paramValue = params[key];
|
|
109
|
+
if (this.isValidParamValue(paramValue)) {
|
|
110
|
+
const displayKey = this.capitalizeFirstLetter(key);
|
|
111
|
+
const formattedValue = this.formatParamValue(key, paramValue, locatorFieldKeys.includes(key));
|
|
112
|
+
paramsList.push(`${displayKey}: ${formattedValue}`);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
return paramsList;
|
|
116
|
+
}
|
|
117
|
+
isValidParamValue(value) {
|
|
118
|
+
return null != value && '' !== value;
|
|
119
|
+
}
|
|
120
|
+
capitalizeFirstLetter(str) {
|
|
121
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
122
|
+
}
|
|
123
|
+
formatParamValue(key, value, isLocateField) {
|
|
124
|
+
if (isLocateField || 'string' == typeof value) return `"${value}"`;
|
|
125
|
+
if ('number' == typeof value) return 'distance' === key ? `${value}px` : `${value}`;
|
|
126
|
+
return `${value}`;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
export { BasePlaygroundAdapter };
|
|
130
|
+
|
|
131
|
+
//# sourceMappingURL=base.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapters\\base.mjs","sources":["webpack://@sqaitech/playground/./src/adapters/base.ts"],"sourcesContent":["import type { DeviceAction } from '@sqaitech/core';\r\nimport { findAllMidsceneLocatorField } from '@sqaitech/core/ai-model';\r\nimport type { ExecutionOptions, FormValue, ValidationResult } from '../types';\r\n\r\nexport abstract class BasePlaygroundAdapter {\r\n abstract parseStructuredParams(\r\n action: DeviceAction<unknown>,\r\n params: Record<string, unknown>,\r\n options: ExecutionOptions,\r\n ): Promise<unknown[]>;\r\n\r\n abstract formatErrorMessage(error: any): string;\r\n\r\n // Abstract method for execution - must be implemented by concrete adapters\r\n abstract executeAction(\r\n actionType: string,\r\n value: FormValue,\r\n options: ExecutionOptions,\r\n ): Promise<unknown>;\r\n\r\n // Optional method for getting action space - default implementation returns empty array\r\n async getActionSpace(_context: any): Promise<DeviceAction<unknown>[]> {\r\n return [];\r\n }\r\n\r\n // Common validation logic - can be overridden if needed\r\n validateParams(\r\n value: FormValue,\r\n action: DeviceAction<unknown> | undefined,\r\n ): ValidationResult {\r\n if (!action?.paramSchema) {\r\n return { valid: true };\r\n }\r\n\r\n const needsStructuredParams = this.actionNeedsStructuredParams(action);\r\n\r\n if (!needsStructuredParams) {\r\n return { valid: true };\r\n }\r\n\r\n if (!value.params) {\r\n return { valid: false, errorMessage: 'Parameters are required' };\r\n }\r\n\r\n try {\r\n const paramsForValidation = this.prepareParamsForValidation(\r\n value.params,\r\n action,\r\n );\r\n action.paramSchema.parse(paramsForValidation);\r\n return { valid: true };\r\n } catch (error: unknown) {\r\n return this.handleValidationError(error);\r\n }\r\n }\r\n\r\n // Common display content creation logic - can be overridden if needed\r\n createDisplayContent(\r\n value: FormValue,\r\n needsStructuredParams: boolean,\r\n action: DeviceAction<unknown> | undefined,\r\n ): string {\r\n if (!needsStructuredParams || !value.params || !action?.paramSchema) {\r\n return value.prompt || '';\r\n }\r\n\r\n const paramsList = this.buildParamsDisplayList(value.params, action);\r\n return paramsList.join('\\n') || value.prompt || '';\r\n }\r\n\r\n // Helper method for basic error message formatting\r\n protected formatBasicErrorMessage(error: any): string {\r\n return error?.message || 'Unknown error';\r\n }\r\n\r\n // Helper method for parsing structured params base logic\r\n protected getSchemaKeys(action: DeviceAction<unknown>): string[] {\r\n if (!action?.paramSchema || !('shape' in action.paramSchema)) {\r\n return [];\r\n }\r\n\r\n const schema = action.paramSchema;\r\n return schema && 'shape' in schema\r\n ? Object.keys((schema as { shape: Record<string, unknown> }).shape)\r\n : [];\r\n }\r\n\r\n // Helper method for filtering valid params\r\n protected filterValidParams(\r\n params: Record<string, unknown>,\r\n excludeKeys: string[] = [],\r\n ): Record<string, unknown> {\r\n const filtered: Record<string, unknown> = {};\r\n\r\n Object.keys(params).forEach((key) => {\r\n if (\r\n !excludeKeys.includes(key) &&\r\n params[key] !== undefined &&\r\n params[key] !== null &&\r\n params[key] !== ''\r\n ) {\r\n filtered[key] = params[key];\r\n }\r\n });\r\n\r\n return filtered;\r\n }\r\n\r\n // Check if action needs structured parameters\r\n protected actionNeedsStructuredParams(\r\n action: DeviceAction<unknown>,\r\n ): boolean {\r\n if (\r\n typeof action.paramSchema === 'object' &&\r\n 'shape' in action.paramSchema\r\n ) {\r\n const shape =\r\n (action.paramSchema as { shape: Record<string, unknown> }).shape || {};\r\n return Object.keys(shape).length > 0;\r\n }\r\n return true; // If paramSchema exists but not in expected format, assume it needs params\r\n }\r\n\r\n // Prepare parameters for validation by converting string locate fields\r\n protected prepareParamsForValidation(\r\n params: Record<string, unknown>,\r\n action: DeviceAction<unknown>,\r\n ): Record<string, unknown> {\r\n const paramsForValidation = { ...params };\r\n\r\n if (action.paramSchema) {\r\n const locatorFieldKeys = findAllMidsceneLocatorField(action.paramSchema);\r\n locatorFieldKeys.forEach((key: string) => {\r\n if (typeof paramsForValidation[key] === 'string') {\r\n paramsForValidation[key] = {\r\n midscene_location_field_flag: true,\r\n prompt: paramsForValidation[key],\r\n center: [0, 0], // dummy values for validation\r\n rect: { left: 0, top: 0, width: 0, height: 0 },\r\n };\r\n }\r\n });\r\n }\r\n\r\n return paramsForValidation;\r\n }\r\n\r\n // Handle validation errors with proper error message extraction\r\n protected handleValidationError(error: unknown): ValidationResult {\r\n const zodError = error as {\r\n errors?: Array<{ path: string[]; message: string }>;\r\n };\r\n\r\n if (zodError.errors && zodError.errors.length > 0) {\r\n const errorMessages = zodError.errors\r\n .filter((err) => {\r\n const path = err.path.join('.');\r\n return (\r\n !path.includes('center') &&\r\n !path.includes('rect') &&\r\n !path.includes('midscene_location_field_flag')\r\n );\r\n })\r\n .map((err) => {\r\n const field = err.path.join('.');\r\n return `${field}: ${err.message}`;\r\n });\r\n\r\n if (errorMessages.length > 0) {\r\n return {\r\n valid: false,\r\n errorMessage: `Validation error: ${errorMessages.join(', ')}`,\r\n };\r\n }\r\n }\r\n\r\n const errorMsg =\r\n error instanceof Error ? error.message : 'Unknown validation error';\r\n\r\n return {\r\n valid: false,\r\n errorMessage: `Parameter validation failed: ${errorMsg}`,\r\n };\r\n }\r\n\r\n // Build display list for parameters\r\n protected buildParamsDisplayList(\r\n params: Record<string, unknown>,\r\n action: DeviceAction<unknown>,\r\n ): string[] {\r\n const paramsList: string[] = [];\r\n const schema = action.paramSchema;\r\n\r\n if (!(schema && 'shape' in schema)) {\r\n return paramsList;\r\n }\r\n\r\n const locatorFieldKeys = findAllMidsceneLocatorField(schema);\r\n const shapeKeys = Object.keys(\r\n (schema as { shape: Record<string, unknown> }).shape,\r\n );\r\n\r\n shapeKeys.forEach((key) => {\r\n const paramValue = params[key];\r\n if (this.isValidParamValue(paramValue)) {\r\n const displayKey = this.capitalizeFirstLetter(key);\r\n const formattedValue = this.formatParamValue(\r\n key,\r\n paramValue,\r\n locatorFieldKeys.includes(key),\r\n );\r\n paramsList.push(`${displayKey}: ${formattedValue}`);\r\n }\r\n });\r\n\r\n return paramsList;\r\n }\r\n\r\n // Check if parameter value is valid for display\r\n protected isValidParamValue(value: unknown): boolean {\r\n return value !== undefined && value !== null && value !== '';\r\n }\r\n\r\n // Capitalize first letter of a string\r\n protected capitalizeFirstLetter(str: string): string {\r\n return str.charAt(0).toUpperCase() + str.slice(1);\r\n }\r\n\r\n // Format parameter value for display\r\n protected formatParamValue(\r\n key: string,\r\n value: unknown,\r\n isLocateField: boolean,\r\n ): string {\r\n if (isLocateField || typeof value === 'string') {\r\n return `\"${value}\"`;\r\n }\r\n\r\n if (typeof value === 'number') {\r\n // Special handling for distance in scroll\r\n return key === 'distance' ? `${value}px` : `${value}`;\r\n }\r\n\r\n return `${value}`;\r\n }\r\n}\r\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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"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { overrideAIConfig } from "@sqaitech/shared/env";
|
|
2
|
+
import { uuid } from "@sqaitech/shared/utils";
|
|
3
|
+
import { executeAction, parseStructuredParams } from "../common.mjs";
|
|
4
|
+
import { BasePlaygroundAdapter } from "./base.mjs";
|
|
5
|
+
function _define_property(obj, key, value) {
|
|
6
|
+
if (key in obj) Object.defineProperty(obj, key, {
|
|
7
|
+
value: value,
|
|
8
|
+
enumerable: true,
|
|
9
|
+
configurable: true,
|
|
10
|
+
writable: true
|
|
11
|
+
});
|
|
12
|
+
else obj[key] = value;
|
|
13
|
+
return obj;
|
|
14
|
+
}
|
|
15
|
+
class LocalExecutionAdapter extends BasePlaygroundAdapter {
|
|
16
|
+
get id() {
|
|
17
|
+
return this._id;
|
|
18
|
+
}
|
|
19
|
+
setProgressCallback(callback) {
|
|
20
|
+
this.progressCallback = void 0;
|
|
21
|
+
this.progressCallback = callback;
|
|
22
|
+
}
|
|
23
|
+
cleanup(requestId) {
|
|
24
|
+
delete this.taskProgressTips[requestId];
|
|
25
|
+
}
|
|
26
|
+
async parseStructuredParams(action, params, options) {
|
|
27
|
+
return await parseStructuredParams(action, params, options);
|
|
28
|
+
}
|
|
29
|
+
formatErrorMessage(error) {
|
|
30
|
+
const errorMessage = (null == error ? void 0 : error.message) || '';
|
|
31
|
+
if (errorMessage.includes('of different extension')) return 'Conflicting extension detected. Please disable the suspicious plugins and refresh the page. Guide: https://sqai.tech/quick-experience.html#faq';
|
|
32
|
+
return this.formatBasicErrorMessage(error);
|
|
33
|
+
}
|
|
34
|
+
async getActionSpace(context) {
|
|
35
|
+
var _this_agent;
|
|
36
|
+
if (null == (_this_agent = this.agent) ? void 0 : _this_agent.getActionSpace) return await this.agent.getActionSpace();
|
|
37
|
+
if (this.agent && 'interface' in this.agent && 'object' == typeof this.agent.interface) {
|
|
38
|
+
const page = this.agent.interface;
|
|
39
|
+
if (null == page ? void 0 : page.actionSpace) return await page.actionSpace();
|
|
40
|
+
}
|
|
41
|
+
if (context && 'object' == typeof context && 'actionSpace' in context) {
|
|
42
|
+
const contextPage = context;
|
|
43
|
+
return await contextPage.actionSpace();
|
|
44
|
+
}
|
|
45
|
+
return [];
|
|
46
|
+
}
|
|
47
|
+
async checkStatus() {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
async overrideConfig(aiConfig) {
|
|
51
|
+
overrideAIConfig(aiConfig);
|
|
52
|
+
}
|
|
53
|
+
async executeAction(actionType, value, options) {
|
|
54
|
+
const actionSpace = await this.getActionSpace();
|
|
55
|
+
let originalOnTaskStartTip;
|
|
56
|
+
if (options.requestId && this.agent) {
|
|
57
|
+
this.currentRequestId = options.requestId;
|
|
58
|
+
originalOnTaskStartTip = this.agent.onTaskStartTip;
|
|
59
|
+
this.agent.onTaskStartTip = (tip)=>{
|
|
60
|
+
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
|
+
};
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
const result = await executeAction(this.agent, actionType, actionSpace, value, options);
|
|
68
|
+
const response = {
|
|
69
|
+
result,
|
|
70
|
+
dump: null,
|
|
71
|
+
reportHTML: null,
|
|
72
|
+
error: null
|
|
73
|
+
};
|
|
74
|
+
try {
|
|
75
|
+
if (this.agent.dumpDataString) {
|
|
76
|
+
const dumpString = this.agent.dumpDataString();
|
|
77
|
+
if (dumpString) response.dump = JSON.parse(dumpString);
|
|
78
|
+
}
|
|
79
|
+
if (this.agent.reportHTMLString) response.reportHTML = this.agent.reportHTMLString() || null;
|
|
80
|
+
if (this.agent.writeOutActionDumps) this.agent.writeOutActionDumps();
|
|
81
|
+
} catch (error) {
|
|
82
|
+
console.error('Failed to get dump/reportHTML from agent:', error);
|
|
83
|
+
}
|
|
84
|
+
this.agent.resetDump();
|
|
85
|
+
return response;
|
|
86
|
+
} finally{
|
|
87
|
+
if (options.requestId) {
|
|
88
|
+
this.cleanup(options.requestId);
|
|
89
|
+
if (this.agent) this.agent.onTaskStartTip = originalOnTaskStartTip;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
async getTaskProgress(requestId) {
|
|
94
|
+
return {
|
|
95
|
+
tip: this.taskProgressTips[requestId] || void 0
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
async cancelTask(_requestId) {
|
|
99
|
+
if (!this.agent) return {
|
|
100
|
+
error: 'No active agent found for this requestId'
|
|
101
|
+
};
|
|
102
|
+
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));
|
|
105
|
+
return {
|
|
106
|
+
success: true
|
|
107
|
+
};
|
|
108
|
+
} catch (error) {
|
|
109
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
110
|
+
console.error(`Failed to cancel agent: ${errorMessage}`);
|
|
111
|
+
return {
|
|
112
|
+
error: `Failed to cancel: ${errorMessage}`
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
async getInterfaceInfo() {
|
|
117
|
+
var _this_agent;
|
|
118
|
+
if (!(null == (_this_agent = this.agent) ? void 0 : _this_agent.interface)) return null;
|
|
119
|
+
try {
|
|
120
|
+
var _this_agent_interface_describe, _this_agent_interface;
|
|
121
|
+
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;
|
|
123
|
+
return {
|
|
124
|
+
type,
|
|
125
|
+
description
|
|
126
|
+
};
|
|
127
|
+
} catch (error) {
|
|
128
|
+
console.error('Failed to get interface info:', error);
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
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);
|
|
134
|
+
this.agent = agent;
|
|
135
|
+
this._id = uuid();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
export { LocalExecutionAdapter };
|
|
139
|
+
|
|
140
|
+
//# sourceMappingURL=local-execution.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapters\\local-execution.mjs","sources":["webpack://@sqaitech/playground/./src/adapters/local-execution.ts"],"sourcesContent":["import type { DeviceAction } from '@sqaitech/core';\r\nimport { overrideAIConfig } from '@sqaitech/shared/env';\r\nimport { uuid } from '@sqaitech/shared/utils';\r\nimport { executeAction, parseStructuredParams } from '../common';\r\nimport type { ExecutionOptions, FormValue, PlaygroundAgent } from '../types';\r\nimport { BasePlaygroundAdapter } from './base';\r\n\r\nexport class LocalExecutionAdapter extends BasePlaygroundAdapter {\r\n private agent: PlaygroundAgent;\r\n private taskProgressTips: Record<string, string> = {};\r\n private progressCallback?: (tip: string) => void;\r\n private readonly _id: string; // Unique identifier for this local adapter instance\r\n private currentRequestId?: string; // Track current request to prevent stale callbacks\r\n\r\n constructor(agent: PlaygroundAgent) {\r\n super();\r\n this.agent = agent;\r\n this._id = uuid(); // Generate unique ID for local adapter\r\n }\r\n\r\n // Get adapter ID\r\n get id(): string {\r\n return this._id;\r\n }\r\n\r\n setProgressCallback(callback: (tip: string) => void): void {\r\n // Clear any existing callback before setting new one\r\n this.progressCallback = undefined;\r\n // Set the new callback\r\n this.progressCallback = callback;\r\n }\r\n\r\n private cleanup(requestId: string): void {\r\n delete this.taskProgressTips[requestId];\r\n }\r\n\r\n async parseStructuredParams(\r\n action: DeviceAction<unknown>,\r\n params: Record<string, unknown>,\r\n options: ExecutionOptions,\r\n ): Promise<unknown[]> {\r\n // Use shared implementation from common.ts\r\n return await parseStructuredParams(action, params, options);\r\n }\r\n\r\n formatErrorMessage(error: any): string {\r\n const errorMessage = error?.message || '';\r\n if (errorMessage.includes('of different extension')) {\r\n return 'Conflicting extension detected. Please disable the suspicious plugins and refresh the page. Guide: https://sqai.tech/quick-experience.html#faq';\r\n }\r\n return this.formatBasicErrorMessage(error);\r\n }\r\n\r\n // Local execution - use base implementation\r\n // (inherits default executeAction from BasePlaygroundAdapter)\r\n\r\n // Local execution gets actionSpace from internal agent (parameter is for backward compatibility)\r\n async getActionSpace(context?: unknown): Promise<DeviceAction<unknown>[]> {\r\n // Priority 1: Use agent's getActionSpace method\r\n if (this.agent?.getActionSpace) {\r\n return await this.agent.getActionSpace();\r\n }\r\n\r\n // Priority 2: Use agent's interface.actionSpace method\r\n if (\r\n this.agent &&\r\n 'interface' in this.agent &&\r\n typeof this.agent.interface === 'object'\r\n ) {\r\n const page = this.agent.interface as {\r\n actionSpace?: () => Promise<DeviceAction<unknown>[]>;\r\n };\r\n if (page?.actionSpace) {\r\n return await page.actionSpace();\r\n }\r\n }\r\n\r\n // Priority 3: Fallback to context parameter (for backward compatibility with tests)\r\n if (context && typeof context === 'object' && 'actionSpace' in context) {\r\n const contextPage = context as {\r\n actionSpace: () => Promise<DeviceAction<unknown>[]>;\r\n };\r\n return await contextPage.actionSpace();\r\n }\r\n\r\n return [];\r\n }\r\n\r\n // Local execution doesn't use a server, so always return true\r\n async checkStatus(): Promise<boolean> {\r\n return true;\r\n }\r\n\r\n async overrideConfig(aiConfig: Record<string, unknown>): Promise<void> {\r\n // For local execution, use the shared env override function\r\n overrideAIConfig(aiConfig);\r\n }\r\n\r\n async executeAction(\r\n actionType: string,\r\n value: FormValue,\r\n options: ExecutionOptions,\r\n ): Promise<unknown> {\r\n // Get actionSpace using our simplified getActionSpace method\r\n const actionSpace = await this.getActionSpace();\r\n let originalOnTaskStartTip: ((tip: string) => void) | undefined;\r\n\r\n // Setup progress tracking if requestId is provided\r\n if (options.requestId && this.agent) {\r\n // Track current request ID to prevent stale callbacks\r\n this.currentRequestId = options.requestId;\r\n originalOnTaskStartTip = this.agent.onTaskStartTip;\r\n\r\n // Set up a fresh callback\r\n this.agent.onTaskStartTip = (tip: string) => {\r\n // Only process if this is still the current request\r\n if (this.currentRequestId !== options.requestId) {\r\n return;\r\n }\r\n\r\n // Store tip for our progress tracking\r\n this.taskProgressTips[options.requestId!] = tip;\r\n\r\n // Call the direct progress callback set via setProgressCallback\r\n if (this.progressCallback) {\r\n this.progressCallback(tip);\r\n }\r\n\r\n if (typeof originalOnTaskStartTip === 'function') {\r\n originalOnTaskStartTip(tip);\r\n }\r\n };\r\n }\r\n\r\n try {\r\n // Call the base implementation with the original signature\r\n const result = await executeAction(\r\n this.agent,\r\n actionType,\r\n actionSpace,\r\n value,\r\n options,\r\n );\r\n\r\n // For local execution, we need to package the result with dump and reportHTML\r\n // similar to how the server does it\r\n const response = {\r\n result,\r\n dump: null as unknown,\r\n reportHTML: null as string | null,\r\n error: null as string | null,\r\n };\r\n\r\n try {\r\n // Get dump and reportHTML from agent like the server does\r\n if (this.agent.dumpDataString) {\r\n const dumpString = this.agent.dumpDataString();\r\n if (dumpString) {\r\n response.dump = JSON.parse(dumpString);\r\n }\r\n }\r\n\r\n if (this.agent.reportHTMLString) {\r\n response.reportHTML = this.agent.reportHTMLString() || null;\r\n }\r\n\r\n // Write out action dumps\r\n if (this.agent.writeOutActionDumps) {\r\n this.agent.writeOutActionDumps();\r\n }\r\n } catch (error: unknown) {\r\n console.error('Failed to get dump/reportHTML from agent:', error);\r\n }\r\n\r\n this.agent.resetDump();\r\n\r\n return response;\r\n } finally {\r\n // Always clean up progress tracking to prevent memory leaks\r\n if (options.requestId) {\r\n this.cleanup(options.requestId);\r\n // Clear the agent callback to prevent accumulation\r\n if (this.agent) {\r\n this.agent.onTaskStartTip = originalOnTaskStartTip;\r\n }\r\n }\r\n }\r\n }\r\n\r\n async getTaskProgress(requestId: string): Promise<{ tip?: string }> {\r\n // Return the stored tip for this requestId\r\n return { tip: this.taskProgressTips[requestId] || undefined };\r\n }\r\n\r\n // Local execution task cancellation - minimal implementation\r\n async cancelTask(\r\n _requestId: string,\r\n ): Promise<{ error?: string; success?: boolean }> {\r\n if (!this.agent) {\r\n return { error: 'No active agent found for this requestId' };\r\n }\r\n\r\n try {\r\n await this.agent.destroy?.();\r\n return { success: true };\r\n } catch (error: unknown) {\r\n const errorMessage =\r\n error instanceof Error ? error.message : 'Unknown error';\r\n console.error(`Failed to cancel agent: ${errorMessage}`);\r\n return { error: `Failed to cancel: ${errorMessage}` };\r\n }\r\n }\r\n\r\n // Get interface information from the agent\r\n async getInterfaceInfo(): Promise<{\r\n type: string;\r\n description?: string;\r\n } | null> {\r\n if (!this.agent?.interface) {\r\n return null;\r\n }\r\n\r\n try {\r\n const type = this.agent.interface.interfaceType || 'Unknown';\r\n const description = this.agent.interface.describe?.() || undefined;\r\n\r\n return {\r\n type,\r\n description,\r\n };\r\n } catch (error: unknown) {\r\n console.error('Failed to get interface info:', error);\r\n return null;\r\n }\r\n }\r\n}\r\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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"}
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
import { parseStructuredParams } from "../common.mjs";
|
|
2
|
+
import { BasePlaygroundAdapter } from "./base.mjs";
|
|
3
|
+
function _define_property(obj, key, value) {
|
|
4
|
+
if (key in obj) Object.defineProperty(obj, key, {
|
|
5
|
+
value: value,
|
|
6
|
+
enumerable: true,
|
|
7
|
+
configurable: true,
|
|
8
|
+
writable: true
|
|
9
|
+
});
|
|
10
|
+
else obj[key] = value;
|
|
11
|
+
return obj;
|
|
12
|
+
}
|
|
13
|
+
class RemoteExecutionAdapter extends BasePlaygroundAdapter {
|
|
14
|
+
get id() {
|
|
15
|
+
return this._id;
|
|
16
|
+
}
|
|
17
|
+
validateParams(value, action) {
|
|
18
|
+
if (!(null == action ? void 0 : action.paramSchema)) return {
|
|
19
|
+
valid: true
|
|
20
|
+
};
|
|
21
|
+
const needsStructuredParams = this.actionNeedsStructuredParams(action);
|
|
22
|
+
if (!needsStructuredParams) return {
|
|
23
|
+
valid: true
|
|
24
|
+
};
|
|
25
|
+
if (!value.params) return {
|
|
26
|
+
valid: false,
|
|
27
|
+
errorMessage: 'Parameters are required'
|
|
28
|
+
};
|
|
29
|
+
if (action.paramSchema && 'object' == typeof action.paramSchema) {
|
|
30
|
+
const schema = action.paramSchema;
|
|
31
|
+
if (schema.shape || 'ZodObject' === schema.type) {
|
|
32
|
+
const shape = schema.shape || {};
|
|
33
|
+
const missingFields = Object.keys(shape).filter((key)=>{
|
|
34
|
+
var _fieldDef__def, _fieldDef__def1;
|
|
35
|
+
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';
|
|
37
|
+
return !isOptional && (void 0 === value.params[key] || '' === value.params[key]);
|
|
38
|
+
});
|
|
39
|
+
if (missingFields.length > 0) return {
|
|
40
|
+
valid: false,
|
|
41
|
+
errorMessage: `Missing required parameters: ${missingFields.join(', ')}`
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
valid: true
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
async parseStructuredParams(action, params, options) {
|
|
50
|
+
return await parseStructuredParams(action, params, options);
|
|
51
|
+
}
|
|
52
|
+
formatErrorMessage(error) {
|
|
53
|
+
const message = (null == error ? void 0 : error.message) || '';
|
|
54
|
+
const androidErrors = [
|
|
55
|
+
{
|
|
56
|
+
keyword: 'adb',
|
|
57
|
+
message: 'ADB connection error. Please ensure device is connected and USB debugging is enabled.'
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
keyword: 'UIAutomator',
|
|
61
|
+
message: 'UIAutomator error. Please ensure the UIAutomator server is running on the device.'
|
|
62
|
+
}
|
|
63
|
+
];
|
|
64
|
+
const androidError = androidErrors.find(({ keyword })=>message.includes(keyword));
|
|
65
|
+
if (androidError) return androidError.message;
|
|
66
|
+
return this.formatBasicErrorMessage(error);
|
|
67
|
+
}
|
|
68
|
+
async executeAction(actionType, value, options) {
|
|
69
|
+
if (this.serverUrl && 'undefined' != typeof window) return this.executeViaServer(actionType, value, options);
|
|
70
|
+
throw new Error('Remote execution adapter requires server URL for execution');
|
|
71
|
+
}
|
|
72
|
+
async executeViaServer(actionType, value, options) {
|
|
73
|
+
const payload = {
|
|
74
|
+
type: actionType,
|
|
75
|
+
prompt: value.prompt,
|
|
76
|
+
...this.buildOptionalPayloadParams(options, value)
|
|
77
|
+
};
|
|
78
|
+
if (options.context) payload.context = options.context;
|
|
79
|
+
if (options.requestId && this.progressCallback) this.startProgressPolling(options.requestId, this.progressCallback);
|
|
80
|
+
try {
|
|
81
|
+
const response = await fetch(`${this.serverUrl}/execute`, {
|
|
82
|
+
method: 'POST',
|
|
83
|
+
headers: {
|
|
84
|
+
'Content-Type': 'application/json'
|
|
85
|
+
},
|
|
86
|
+
body: JSON.stringify(payload)
|
|
87
|
+
});
|
|
88
|
+
if (!response.ok) {
|
|
89
|
+
const errorText = await response.text().catch(()=>'Unknown error');
|
|
90
|
+
throw new Error(`Server request failed (${response.status}): ${errorText}`);
|
|
91
|
+
}
|
|
92
|
+
const result = await response.json();
|
|
93
|
+
if (options.requestId) this.stopProgressPolling(options.requestId);
|
|
94
|
+
return result;
|
|
95
|
+
} catch (error) {
|
|
96
|
+
if (options.requestId) this.stopProgressPolling(options.requestId);
|
|
97
|
+
console.error('Execute via server failed:', error);
|
|
98
|
+
throw error;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
buildOptionalPayloadParams(options, value) {
|
|
102
|
+
const optionalParams = {};
|
|
103
|
+
const optionalFields = [
|
|
104
|
+
{
|
|
105
|
+
key: 'requestId',
|
|
106
|
+
value: options.requestId
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
key: 'deepThink',
|
|
110
|
+
value: options.deepThink
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
key: 'screenshotIncluded',
|
|
114
|
+
value: options.screenshotIncluded
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
key: 'domIncluded',
|
|
118
|
+
value: options.domIncluded
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
key: 'params',
|
|
122
|
+
value: value.params
|
|
123
|
+
}
|
|
124
|
+
];
|
|
125
|
+
optionalFields.forEach(({ key, value })=>{
|
|
126
|
+
if (null != value && '' !== value) optionalParams[key] = value;
|
|
127
|
+
});
|
|
128
|
+
return optionalParams;
|
|
129
|
+
}
|
|
130
|
+
async getActionSpace(context) {
|
|
131
|
+
if (this.serverUrl && 'undefined' != typeof window) try {
|
|
132
|
+
const response = await fetch(`${this.serverUrl}/action-space`, {
|
|
133
|
+
method: 'POST',
|
|
134
|
+
headers: {
|
|
135
|
+
'Content-Type': 'application/json'
|
|
136
|
+
},
|
|
137
|
+
body: JSON.stringify({
|
|
138
|
+
context
|
|
139
|
+
})
|
|
140
|
+
});
|
|
141
|
+
if (!response.ok) throw new Error(`Failed to get action space: ${response.statusText}`);
|
|
142
|
+
const result = await response.json();
|
|
143
|
+
return Array.isArray(result) ? result : [];
|
|
144
|
+
} catch (error) {
|
|
145
|
+
console.error('Failed to get action space from server:', error);
|
|
146
|
+
}
|
|
147
|
+
if (context && 'object' == typeof context && 'actionSpace' in context) try {
|
|
148
|
+
const actionSpaceMethod = context.actionSpace;
|
|
149
|
+
const result = await actionSpaceMethod();
|
|
150
|
+
return Array.isArray(result) ? result : [];
|
|
151
|
+
} catch (error) {
|
|
152
|
+
console.error('Failed to get action space from context:', error);
|
|
153
|
+
}
|
|
154
|
+
return [];
|
|
155
|
+
}
|
|
156
|
+
async checkStatus() {
|
|
157
|
+
if (!this.serverUrl) return false;
|
|
158
|
+
try {
|
|
159
|
+
const res = await fetch(`${this.serverUrl}/status`);
|
|
160
|
+
if (200 === res.status) {
|
|
161
|
+
try {
|
|
162
|
+
const data = await res.json();
|
|
163
|
+
if (data.id && 'string' == typeof data.id) this._id = data.id;
|
|
164
|
+
} catch (jsonError) {
|
|
165
|
+
console.debug('Failed to parse status response:', jsonError);
|
|
166
|
+
}
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
return false;
|
|
170
|
+
} catch (error) {
|
|
171
|
+
console.warn('Server status check failed:', error);
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
async overrideConfig(aiConfig) {
|
|
176
|
+
if (!this.serverUrl) throw new Error('Server URL not configured');
|
|
177
|
+
try {
|
|
178
|
+
const response = await fetch(`${this.serverUrl}/config`, {
|
|
179
|
+
method: 'POST',
|
|
180
|
+
headers: {
|
|
181
|
+
'Content-Type': 'application/json'
|
|
182
|
+
},
|
|
183
|
+
body: JSON.stringify({
|
|
184
|
+
aiConfig
|
|
185
|
+
})
|
|
186
|
+
});
|
|
187
|
+
if (!response.ok) throw new Error(`Failed to override server config: ${response.statusText}`);
|
|
188
|
+
} catch (error) {
|
|
189
|
+
console.error('Failed to override server config:', error);
|
|
190
|
+
throw error;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
async getTaskProgress(requestId) {
|
|
194
|
+
if (!this.serverUrl) return {
|
|
195
|
+
tip: void 0
|
|
196
|
+
};
|
|
197
|
+
if (!(null == requestId ? void 0 : requestId.trim())) {
|
|
198
|
+
console.warn('Invalid requestId provided for task progress');
|
|
199
|
+
return {
|
|
200
|
+
tip: void 0
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
try {
|
|
204
|
+
const response = await fetch(`${this.serverUrl}/task-progress/${encodeURIComponent(requestId)}`);
|
|
205
|
+
if (!response.ok) {
|
|
206
|
+
console.warn(`Task progress request failed: ${response.statusText}`);
|
|
207
|
+
return {
|
|
208
|
+
tip: void 0
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
return await response.json();
|
|
212
|
+
} catch (error) {
|
|
213
|
+
console.error('Failed to poll task progress:', error);
|
|
214
|
+
return {
|
|
215
|
+
tip: void 0
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
async cancelTask(requestId) {
|
|
220
|
+
this.stopProgressPolling(requestId);
|
|
221
|
+
if (!this.serverUrl) return {
|
|
222
|
+
error: 'No server URL configured'
|
|
223
|
+
};
|
|
224
|
+
if (!(null == requestId ? void 0 : requestId.trim())) return {
|
|
225
|
+
error: 'Invalid request ID'
|
|
226
|
+
};
|
|
227
|
+
try {
|
|
228
|
+
const res = await fetch(`${this.serverUrl}/cancel/${encodeURIComponent(requestId)}`, {
|
|
229
|
+
method: 'POST'
|
|
230
|
+
});
|
|
231
|
+
if (!res.ok) return {
|
|
232
|
+
error: `Cancel request failed: ${res.statusText}`
|
|
233
|
+
};
|
|
234
|
+
const result = await res.json();
|
|
235
|
+
return {
|
|
236
|
+
success: true,
|
|
237
|
+
...result
|
|
238
|
+
};
|
|
239
|
+
} catch (error) {
|
|
240
|
+
console.error('Failed to cancel task:', error);
|
|
241
|
+
return {
|
|
242
|
+
error: 'Failed to cancel task'
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
}
|
|
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
|
+
async getScreenshot() {
|
|
274
|
+
if (!this.serverUrl) return null;
|
|
275
|
+
try {
|
|
276
|
+
const response = await fetch(`${this.serverUrl}/screenshot`);
|
|
277
|
+
if (!response.ok) {
|
|
278
|
+
console.warn(`Screenshot request failed: ${response.statusText}`);
|
|
279
|
+
return null;
|
|
280
|
+
}
|
|
281
|
+
return await response.json();
|
|
282
|
+
} catch (error) {
|
|
283
|
+
console.error('Failed to get screenshot:', error);
|
|
284
|
+
return null;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
async getInterfaceInfo() {
|
|
288
|
+
if (!this.serverUrl) return null;
|
|
289
|
+
try {
|
|
290
|
+
const response = await fetch(`${this.serverUrl}/interface-info`);
|
|
291
|
+
if (!response.ok) {
|
|
292
|
+
console.warn(`Interface info request failed: ${response.statusText}`);
|
|
293
|
+
return null;
|
|
294
|
+
}
|
|
295
|
+
return await response.json();
|
|
296
|
+
} catch (error) {
|
|
297
|
+
console.error('Failed to get interface info:', error);
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
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);
|
|
303
|
+
this.serverUrl = serverUrl;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
export { RemoteExecutionAdapter };
|
|
307
|
+
|
|
308
|
+
//# sourceMappingURL=remote-execution.mjs.map
|