@midscene/core 1.0.1-beta-20251030070226.0 → 1.0.1-beta-20251104075048.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 (50) hide show
  1. package/dist/es/agent/agent.mjs +70 -45
  2. package/dist/es/agent/agent.mjs.map +1 -1
  3. package/dist/es/agent/execution-session.mjs.map +1 -1
  4. package/dist/es/agent/task-builder.mjs +8 -7
  5. package/dist/es/agent/task-builder.mjs.map +1 -1
  6. package/dist/es/agent/tasks.mjs +30 -29
  7. package/dist/es/agent/tasks.mjs.map +1 -1
  8. package/dist/es/agent/ui-utils.mjs +6 -7
  9. package/dist/es/agent/ui-utils.mjs.map +1 -1
  10. package/dist/es/agent/utils.mjs +1 -1
  11. package/dist/es/ai-model/prompt/llm-planning.mjs +84 -66
  12. package/dist/es/ai-model/prompt/llm-planning.mjs.map +1 -1
  13. package/dist/es/device/index.mjs.map +1 -1
  14. package/dist/es/service/index.mjs +1 -1
  15. package/dist/es/service/index.mjs.map +1 -1
  16. package/dist/es/task-runner.mjs +42 -7
  17. package/dist/es/task-runner.mjs.map +1 -1
  18. package/dist/es/types.mjs.map +1 -1
  19. package/dist/es/utils.mjs +2 -2
  20. package/dist/es/yaml/player.mjs +67 -16
  21. package/dist/es/yaml/player.mjs.map +1 -1
  22. package/dist/lib/agent/agent.js +69 -44
  23. package/dist/lib/agent/agent.js.map +1 -1
  24. package/dist/lib/agent/execution-session.js.map +1 -1
  25. package/dist/lib/agent/task-builder.js +8 -7
  26. package/dist/lib/agent/task-builder.js.map +1 -1
  27. package/dist/lib/agent/tasks.js +32 -28
  28. package/dist/lib/agent/tasks.js.map +1 -1
  29. package/dist/lib/agent/ui-utils.js +6 -7
  30. package/dist/lib/agent/ui-utils.js.map +1 -1
  31. package/dist/lib/agent/utils.js +1 -1
  32. package/dist/lib/ai-model/prompt/llm-planning.js +84 -66
  33. package/dist/lib/ai-model/prompt/llm-planning.js.map +1 -1
  34. package/dist/lib/device/index.js.map +1 -1
  35. package/dist/lib/service/index.js +1 -1
  36. package/dist/lib/service/index.js.map +1 -1
  37. package/dist/lib/task-runner.js +44 -6
  38. package/dist/lib/task-runner.js.map +1 -1
  39. package/dist/lib/types.js.map +1 -1
  40. package/dist/lib/utils.js +2 -2
  41. package/dist/lib/yaml/player.js +67 -16
  42. package/dist/lib/yaml/player.js.map +1 -1
  43. package/dist/types/agent/agent.d.ts +6 -3
  44. package/dist/types/agent/execution-session.d.ts +7 -4
  45. package/dist/types/agent/tasks.d.ts +7 -0
  46. package/dist/types/device/index.d.ts +3 -3
  47. package/dist/types/task-runner.d.ts +15 -3
  48. package/dist/types/types.d.ts +24 -6
  49. package/dist/types/yaml.d.ts +1 -2
  50. package/package.json +2 -2
@@ -29,6 +29,7 @@ __webpack_require__.d(__webpack_exports__, {
29
29
  const external_node_fs_namespaceObject = require("node:fs");
30
30
  const external_node_path_namespaceObject = require("node:path");
31
31
  const utils_namespaceObject = require("@midscene/shared/utils");
32
+ const external_zod_namespaceObject = require("zod");
32
33
  const common_namespaceObject = require("@midscene/shared/common");
33
34
  const logger_namespaceObject = require("@midscene/shared/logger");
34
35
  const external_utils_js_namespaceObject = require("./utils.js");
@@ -43,6 +44,34 @@ function _define_property(obj, key, value) {
43
44
  return obj;
44
45
  }
45
46
  const debug = (0, logger_namespaceObject.getDebug)('yaml-player');
47
+ const isStringParamSchema = (schema)=>{
48
+ if (!schema) return false;
49
+ const schemaDef = null == schema ? void 0 : schema._def;
50
+ if (!(null == schemaDef ? void 0 : schemaDef.typeName)) return false;
51
+ switch(schemaDef.typeName){
52
+ case external_zod_namespaceObject.z.ZodFirstPartyTypeKind.ZodString:
53
+ case external_zod_namespaceObject.z.ZodFirstPartyTypeKind.ZodEnum:
54
+ case external_zod_namespaceObject.z.ZodFirstPartyTypeKind.ZodNativeEnum:
55
+ return true;
56
+ case external_zod_namespaceObject.z.ZodFirstPartyTypeKind.ZodLiteral:
57
+ return 'string' == typeof schemaDef.value;
58
+ case external_zod_namespaceObject.z.ZodFirstPartyTypeKind.ZodOptional:
59
+ case external_zod_namespaceObject.z.ZodFirstPartyTypeKind.ZodNullable:
60
+ case external_zod_namespaceObject.z.ZodFirstPartyTypeKind.ZodDefault:
61
+ return isStringParamSchema(schemaDef.innerType);
62
+ case external_zod_namespaceObject.z.ZodFirstPartyTypeKind.ZodEffects:
63
+ return isStringParamSchema(schemaDef.schema);
64
+ case external_zod_namespaceObject.z.ZodFirstPartyTypeKind.ZodPipeline:
65
+ return isStringParamSchema(schemaDef.out);
66
+ case external_zod_namespaceObject.z.ZodFirstPartyTypeKind.ZodUnion:
67
+ {
68
+ const options = schemaDef.options;
69
+ return Array.isArray(options) ? options.every((option)=>isStringParamSchema(option)) : false;
70
+ }
71
+ default:
72
+ return false;
73
+ }
74
+ };
46
75
  class ScriptPlayer {
47
76
  setResult(key, value) {
48
77
  const keyToUse = key || this.unnamedResultIndex++;
@@ -250,34 +279,56 @@ class ScriptPlayer {
250
279
  } else {
251
280
  const actionSpace = this.actionSpace;
252
281
  let locatePromptShortcut;
282
+ let actionParamForMatchedAction;
253
283
  const matchedAction = actionSpace.find((action)=>{
254
284
  const actionInterfaceAlias = action.interfaceAlias;
255
285
  if (actionInterfaceAlias && Object.prototype.hasOwnProperty.call(flowItem, actionInterfaceAlias)) {
256
- locatePromptShortcut = flowItem[actionInterfaceAlias];
286
+ actionParamForMatchedAction = flowItem[actionInterfaceAlias];
287
+ if ('string' == typeof actionParamForMatchedAction) locatePromptShortcut = actionParamForMatchedAction;
257
288
  return true;
258
289
  }
259
290
  const keyOfActionInActionSpace = action.name;
260
291
  if (Object.prototype.hasOwnProperty.call(flowItem, keyOfActionInActionSpace)) {
261
- locatePromptShortcut = flowItem[keyOfActionInActionSpace];
292
+ actionParamForMatchedAction = flowItem[keyOfActionInActionSpace];
293
+ if ('string' == typeof actionParamForMatchedAction) locatePromptShortcut = actionParamForMatchedAction;
262
294
  return true;
263
295
  }
264
296
  return false;
265
297
  });
266
298
  (0, utils_namespaceObject.assert)(matchedAction, `unknown flowItem in yaml: ${JSON.stringify(flowItem)}`);
267
- const flowItemForProcessing = locatePromptShortcut ? {
268
- ...flowItem,
269
- prompt: locatePromptShortcut
270
- } : flowItem;
271
- const { locateParam, restParams } = (0, external_utils_js_namespaceObject.buildDetailedLocateParamAndRestParams)(locatePromptShortcut || '', flowItemForProcessing, [
272
- matchedAction.name,
273
- matchedAction.interfaceAlias || '_never_mind_'
274
- ]);
275
- const flowParams = {
276
- ...restParams,
277
- locate: locateParam
278
- };
279
- debug(`matchedAction: ${matchedAction.name}`, `flowParams: ${JSON.stringify(flowParams, null, 2)}`);
280
- await agent.callActionInActionSpace(matchedAction.name, flowParams);
299
+ const schemaIsStringParam = isStringParamSchema(matchedAction.paramSchema);
300
+ let stringParamToCall;
301
+ if ('string' == typeof actionParamForMatchedAction && schemaIsStringParam) if (matchedAction.paramSchema) {
302
+ const parseResult = matchedAction.paramSchema.safeParse(actionParamForMatchedAction);
303
+ if (parseResult.success && 'string' == typeof parseResult.data) stringParamToCall = parseResult.data;
304
+ else if (!parseResult.success) {
305
+ debug(`parse failed for action ${matchedAction.name} with string param`, parseResult.error);
306
+ stringParamToCall = actionParamForMatchedAction;
307
+ }
308
+ } else stringParamToCall = actionParamForMatchedAction;
309
+ if (void 0 !== stringParamToCall) {
310
+ debug(`matchedAction: ${matchedAction.name}`, `flowParams: ${JSON.stringify(stringParamToCall)}`);
311
+ const result = await agent.callActionInActionSpace(matchedAction.name, stringParamToCall);
312
+ const resultName = flowItem.name;
313
+ if (void 0 !== result) this.setResult(resultName, result);
314
+ } else {
315
+ const sourceForParams = locatePromptShortcut && 'string' == typeof actionParamForMatchedAction ? {
316
+ ...flowItem,
317
+ prompt: locatePromptShortcut
318
+ } : 'object' == typeof actionParamForMatchedAction && null !== actionParamForMatchedAction ? actionParamForMatchedAction : flowItem;
319
+ const { locateParam, restParams } = (0, external_utils_js_namespaceObject.buildDetailedLocateParamAndRestParams)(locatePromptShortcut || '', sourceForParams, [
320
+ matchedAction.name,
321
+ matchedAction.interfaceAlias || '_never_mind_'
322
+ ]);
323
+ const flowParams = {
324
+ ...restParams,
325
+ locate: locateParam
326
+ };
327
+ debug(`matchedAction: ${matchedAction.name}`, `flowParams: ${JSON.stringify(flowParams, null, 2)}`);
328
+ const result = await agent.callActionInActionSpace(matchedAction.name, flowParams);
329
+ const resultName = flowItem.name;
330
+ if (void 0 !== result) this.setResult(resultName, result);
331
+ }
281
332
  }
282
333
  }
283
334
  this.reportFile = agent.reportFile;
@@ -1 +1 @@
1
- {"version":3,"file":"yaml/player.js","sources":["webpack://@midscene/core/webpack/runtime/define_property_getters","webpack://@midscene/core/webpack/runtime/has_own_property","webpack://@midscene/core/webpack/runtime/make_namespace_object","webpack://@midscene/core/./src/yaml/player.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { basename, dirname, join, resolve } from 'node:path';\nimport { assert, ifInBrowser, ifInWorker } from '@midscene/shared/utils';\n\n// previous defined yaml flow, as a helper\ninterface MidsceneYamlFlowItemAIInput extends LocateOption {\n // previous version\n // aiInput: string; // value to input\n // locate: TUserPrompt; // where to input\n aiInput: TUserPrompt | undefined; // where to input\n value: string | number; // value to input\n}\n\ninterface MidsceneYamlFlowItemAIKeyboardPress extends LocateOption {\n // previous version\n // aiKeyboardPress: string;\n // locate?: TUserPrompt; // where to press, optional\n aiKeyboardPress: TUserPrompt | undefined; // where to press\n keyName: string; // key to press\n}\n\ninterface MidsceneYamlFlowItemAIScroll extends LocateOption, ScrollParam {\n // previous version\n // aiScroll: null;\n // locate?: TUserPrompt; // which area to scroll, optional\n aiScroll: TUserPrompt | undefined; // which area to scroll\n}\n\nimport type { Agent } from '@/agent/agent';\nimport type { TUserPrompt } from '@/ai-model/common';\nimport type {\n DeviceAction,\n FreeFn,\n LocateOption,\n MidsceneYamlFlowItemAIAction,\n MidsceneYamlFlowItemAIAsk,\n MidsceneYamlFlowItemAIAssert,\n MidsceneYamlFlowItemAIBoolean,\n MidsceneYamlFlowItemAILocate,\n MidsceneYamlFlowItemAINumber,\n MidsceneYamlFlowItemAIQuery,\n MidsceneYamlFlowItemAIString,\n MidsceneYamlFlowItemAIWaitFor,\n MidsceneYamlFlowItemEvaluateJavaScript,\n MidsceneYamlFlowItemLogScreenshot,\n MidsceneYamlFlowItemSleep,\n MidsceneYamlScript,\n MidsceneYamlScriptEnv,\n ScriptPlayerStatusValue,\n ScriptPlayerTaskStatus,\n ScrollParam,\n} from '@/types';\nimport { getMidsceneRunSubDir } from '@midscene/shared/common';\nimport { getDebug } from '@midscene/shared/logger';\nimport {\n buildDetailedLocateParam,\n buildDetailedLocateParamAndRestParams,\n} from './utils';\n\nconst debug = getDebug('yaml-player');\nexport class ScriptPlayer<T extends MidsceneYamlScriptEnv> {\n public currentTaskIndex?: number;\n public taskStatusList: ScriptPlayerTaskStatus[] = [];\n public status: ScriptPlayerStatusValue = 'init';\n public reportFile?: string | null;\n public result: Record<string, any>;\n private unnamedResultIndex = 0;\n public output?: string | null;\n public unstableLogContent?: string | null;\n public errorInSetup?: Error;\n private interfaceAgent: Agent | null = null;\n public agentStatusTip?: string;\n public target?: MidsceneYamlScriptEnv;\n private actionSpace: DeviceAction[] = [];\n private scriptPath?: string;\n constructor(\n private script: MidsceneYamlScript,\n private setupAgent: (platform: T) => Promise<{\n agent: Agent;\n freeFn: FreeFn[];\n }>,\n public onTaskStatusChange?: (taskStatus: ScriptPlayerTaskStatus) => void,\n scriptPath?: string,\n ) {\n this.scriptPath = scriptPath;\n this.result = {};\n this.target =\n script.target ||\n script.web ||\n script.android ||\n script.ios ||\n script.config;\n\n if (ifInBrowser || ifInWorker) {\n this.output = undefined;\n debug('output is undefined in browser or worker');\n } else if (this.target?.output) {\n this.output = resolve(process.cwd(), this.target.output);\n debug('setting output by config.output', this.output);\n } else {\n const scriptName = this.scriptPath\n ? basename(this.scriptPath, '.yaml').replace(/\\.(ya?ml)$/i, '')\n : 'script';\n this.output = join(\n getMidsceneRunSubDir('output'),\n `${scriptName}-${Date.now()}.json`,\n );\n debug('setting output by script path', this.output);\n }\n\n if (ifInBrowser || ifInWorker) {\n this.unstableLogContent = undefined;\n } else if (typeof this.target?.unstableLogContent === 'string') {\n this.unstableLogContent = resolve(\n process.cwd(),\n this.target.unstableLogContent,\n );\n } else if (this.target?.unstableLogContent === true) {\n this.unstableLogContent = join(\n getMidsceneRunSubDir('output'),\n 'unstableLogContent.json',\n );\n }\n\n this.taskStatusList = (script.tasks || []).map((task, taskIndex) => ({\n ...task,\n index: taskIndex,\n status: 'init',\n totalSteps: task.flow?.length || 0,\n }));\n }\n\n private setResult(key: string | undefined, value: any) {\n const keyToUse = key || this.unnamedResultIndex++;\n if (this.result[keyToUse]) {\n console.warn(`result key ${keyToUse} already exists, will overwrite`);\n }\n this.result[keyToUse] = value;\n\n return this.flushResult();\n }\n\n private setPlayerStatus(status: ScriptPlayerStatusValue, error?: Error) {\n this.status = status;\n this.errorInSetup = error;\n }\n\n private notifyCurrentTaskStatusChange(taskIndex?: number) {\n const taskIndexToNotify =\n typeof taskIndex === 'number' ? taskIndex : this.currentTaskIndex;\n\n if (typeof taskIndexToNotify !== 'number') {\n return;\n }\n\n const taskStatus = this.taskStatusList[taskIndexToNotify];\n if (this.onTaskStatusChange) {\n this.onTaskStatusChange(taskStatus);\n }\n }\n\n private async setTaskStatus(\n index: number,\n statusValue: ScriptPlayerStatusValue,\n error?: Error,\n ) {\n this.taskStatusList[index].status = statusValue;\n if (error) {\n this.taskStatusList[index].error = error;\n }\n\n this.notifyCurrentTaskStatusChange(index);\n }\n\n private setTaskIndex(taskIndex: number) {\n this.currentTaskIndex = taskIndex;\n }\n\n private flushResult() {\n if (this.output) {\n const output = resolve(process.cwd(), this.output);\n const outputDir = dirname(output);\n if (!existsSync(outputDir)) {\n mkdirSync(outputDir, { recursive: true });\n }\n writeFileSync(output, JSON.stringify(this.result || {}, undefined, 2));\n }\n }\n\n private flushUnstableLogContent() {\n if (this.unstableLogContent) {\n const content = this.interfaceAgent?._unstableLogContent();\n const filePath = resolve(process.cwd(), this.unstableLogContent);\n const outputDir = dirname(filePath);\n if (!existsSync(outputDir)) {\n mkdirSync(outputDir, { recursive: true });\n }\n writeFileSync(filePath, JSON.stringify(content, null, 2));\n }\n }\n\n async playTask(taskStatus: ScriptPlayerTaskStatus, agent: Agent) {\n const { flow } = taskStatus;\n assert(flow, 'missing flow in task');\n\n for (const flowItemIndex in flow) {\n const currentStep = Number.parseInt(flowItemIndex, 10);\n taskStatus.currentStep = currentStep;\n const flowItem = flow[flowItemIndex];\n debug(\n `playing step ${flowItemIndex}, flowItem=${JSON.stringify(flowItem)}`,\n );\n if (\n 'aiAct' in (flowItem as MidsceneYamlFlowItemAIAction) ||\n 'aiAction' in (flowItem as MidsceneYamlFlowItemAIAction) ||\n 'ai' in (flowItem as MidsceneYamlFlowItemAIAction)\n ) {\n const actionTask = flowItem as MidsceneYamlFlowItemAIAction;\n const prompt = actionTask.aiAct || actionTask.aiAction || actionTask.ai;\n assert(prompt, 'missing prompt for ai (aiAct)');\n await agent.aiAct(prompt, {\n cacheable: actionTask.cacheable,\n });\n } else if ('aiAssert' in (flowItem as MidsceneYamlFlowItemAIAssert)) {\n const assertTask = flowItem as MidsceneYamlFlowItemAIAssert;\n const prompt = assertTask.aiAssert;\n const msg = assertTask.errorMessage;\n assert(prompt, 'missing prompt for aiAssert');\n const { pass, thought, message } =\n (await agent.aiAssert(prompt, msg, {\n keepRawResponse: true,\n })) || {};\n\n this.setResult(assertTask.name, {\n pass,\n thought,\n message,\n });\n\n if (!pass) {\n throw new Error(message);\n }\n } else if ('aiQuery' in (flowItem as MidsceneYamlFlowItemAIQuery)) {\n const queryTask = flowItem as MidsceneYamlFlowItemAIQuery;\n const prompt = queryTask.aiQuery;\n const options = {\n domIncluded: queryTask.domIncluded,\n screenshotIncluded: queryTask.screenshotIncluded,\n };\n assert(prompt, 'missing prompt for aiQuery');\n const queryResult = await agent.aiQuery(prompt, options);\n this.setResult(queryTask.name, queryResult);\n } else if ('aiNumber' in (flowItem as MidsceneYamlFlowItemAINumber)) {\n const numberTask = flowItem as MidsceneYamlFlowItemAINumber;\n const prompt = numberTask.aiNumber;\n const options = {\n domIncluded: numberTask.domIncluded,\n screenshotIncluded: numberTask.screenshotIncluded,\n };\n assert(prompt, 'missing prompt for aiNumber');\n const numberResult = await agent.aiNumber(prompt, options);\n this.setResult(numberTask.name, numberResult);\n } else if ('aiString' in (flowItem as MidsceneYamlFlowItemAIString)) {\n const stringTask = flowItem as MidsceneYamlFlowItemAIString;\n const prompt = stringTask.aiString;\n const options = {\n domIncluded: stringTask.domIncluded,\n screenshotIncluded: stringTask.screenshotIncluded,\n };\n assert(prompt, 'missing prompt for aiString');\n const stringResult = await agent.aiString(prompt, options);\n this.setResult(stringTask.name, stringResult);\n } else if ('aiBoolean' in (flowItem as MidsceneYamlFlowItemAIBoolean)) {\n const booleanTask = flowItem as MidsceneYamlFlowItemAIBoolean;\n const prompt = booleanTask.aiBoolean;\n const options = {\n domIncluded: booleanTask.domIncluded,\n screenshotIncluded: booleanTask.screenshotIncluded,\n };\n assert(prompt, 'missing prompt for aiBoolean');\n const booleanResult = await agent.aiBoolean(prompt, options);\n this.setResult(booleanTask.name, booleanResult);\n } else if ('aiAsk' in (flowItem as MidsceneYamlFlowItemAIAsk)) {\n const askTask = flowItem as MidsceneYamlFlowItemAIAsk;\n const prompt = askTask.aiAsk;\n assert(prompt, 'missing prompt for aiAsk');\n const askResult = await agent.aiAsk(prompt);\n this.setResult(askTask.name, askResult);\n } else if ('aiLocate' in (flowItem as MidsceneYamlFlowItemAILocate)) {\n const locateTask = flowItem as MidsceneYamlFlowItemAILocate;\n const prompt = locateTask.aiLocate;\n assert(prompt, 'missing prompt for aiLocate');\n const locateResult = await agent.aiLocate(prompt, locateTask);\n this.setResult(locateTask.name, locateResult);\n } else if ('aiWaitFor' in (flowItem as MidsceneYamlFlowItemAIWaitFor)) {\n const waitForTask = flowItem as MidsceneYamlFlowItemAIWaitFor;\n const prompt = waitForTask.aiWaitFor;\n assert(prompt, 'missing prompt for aiWaitFor');\n const timeout = waitForTask.timeout;\n await agent.aiWaitFor(prompt, { timeoutMs: timeout });\n } else if ('sleep' in (flowItem as MidsceneYamlFlowItemSleep)) {\n const sleepTask = flowItem as MidsceneYamlFlowItemSleep;\n const ms = sleepTask.sleep;\n let msNumber = ms;\n if (typeof ms === 'string') {\n msNumber = Number.parseInt(ms, 10);\n }\n assert(\n msNumber && msNumber > 0,\n `ms for sleep must be greater than 0, but got ${ms}`,\n );\n await new Promise((resolve) => setTimeout(resolve, msNumber));\n } else if (\n 'javascript' in (flowItem as MidsceneYamlFlowItemEvaluateJavaScript)\n ) {\n const evaluateJavaScriptTask =\n flowItem as MidsceneYamlFlowItemEvaluateJavaScript;\n\n const result = await agent.evaluateJavaScript(\n evaluateJavaScriptTask.javascript,\n );\n this.setResult(evaluateJavaScriptTask.name, result);\n } else if (\n 'logScreenshot' in (flowItem as MidsceneYamlFlowItemLogScreenshot) ||\n 'recordToReport' in (flowItem as MidsceneYamlFlowItemLogScreenshot)\n ) {\n const recordTask = flowItem as MidsceneYamlFlowItemLogScreenshot;\n const title =\n recordTask.recordToReport ?? recordTask.logScreenshot ?? 'untitled';\n const content = recordTask.content || '';\n await agent.recordToReport(title, { content });\n } else if ('aiInput' in (flowItem as MidsceneYamlFlowItemAIInput)) {\n // may be input empty string ''\n const {\n aiInput,\n value: rawValue,\n ...inputTask\n } = flowItem as MidsceneYamlFlowItemAIInput;\n\n // Compatibility with previous version:\n // Old format: { aiInput: string (value), locate: TUserPrompt }\n // New format - 1: { aiInput: TUserPrompt, value: string | number }\n // New format - 2: { aiInput: undefined, locate: TUserPrompt, value: string | number }\n let locatePrompt: TUserPrompt | undefined;\n let value: string | number | undefined;\n if ((inputTask as any).locate) {\n // Old format - aiInput is the value, locate is the prompt\n // Keep backward compatibility: empty string is treated as no value\n value = (aiInput as string | number) || rawValue;\n locatePrompt = (inputTask as any).locate;\n } else {\n // New format - aiInput is the prompt, value is the value\n locatePrompt = aiInput || '';\n value = rawValue;\n }\n\n // Convert value to string for Input action\n await agent.callActionInActionSpace('Input', {\n ...inputTask,\n ...(value !== undefined ? { value: String(value) } : {}),\n ...(locatePrompt\n ? { locate: buildDetailedLocateParam(locatePrompt, inputTask) }\n : {}),\n });\n } else if (\n 'aiKeyboardPress' in (flowItem as MidsceneYamlFlowItemAIKeyboardPress)\n ) {\n const { aiKeyboardPress, ...keyboardPressTask } =\n flowItem as MidsceneYamlFlowItemAIKeyboardPress;\n\n // Compatibility with previous version:\n // Old format: { aiKeyboardPress: string (key), locate?: TUserPrompt }\n // New format - 1: { aiKeyboardPress: TUserPrompt, keyName: string }\n // New format - 2: { aiKeyboardPress: , locate?: TUserPrompt, keyName: string }\n let locatePrompt: TUserPrompt | undefined;\n let keyName: string | undefined;\n if ((keyboardPressTask as any).locate) {\n // Old format - aiKeyboardPress is the key, locate is the prompt\n keyName = aiKeyboardPress as string;\n locatePrompt = (keyboardPressTask as any).locate;\n } else if (keyboardPressTask.keyName) {\n // New format - aiKeyboardPress is the prompt, key is the key\n keyName = keyboardPressTask.keyName;\n locatePrompt = aiKeyboardPress;\n } else {\n keyName = aiKeyboardPress as string;\n }\n\n await agent.callActionInActionSpace('KeyboardPress', {\n ...keyboardPressTask,\n ...(keyName ? { keyName } : {}),\n ...(locatePrompt\n ? {\n locate: buildDetailedLocateParam(\n locatePrompt,\n keyboardPressTask,\n ),\n }\n : {}),\n });\n } else if ('aiScroll' in (flowItem as MidsceneYamlFlowItemAIScroll)) {\n const { aiScroll, ...scrollTask } =\n flowItem as MidsceneYamlFlowItemAIScroll;\n\n // Compatibility with previous version:\n // Old format: { aiScroll: null, locate?: TUserPrompt, direction, scrollType, distance? }\n // New format - 1: { aiScroll: TUserPrompt, direction, scrollType, distance? }\n // New format - 2: { aiScroll: undefined, locate: TUserPrompt, direction, scrollType, distance? }\n let locatePrompt: TUserPrompt | undefined;\n if ((scrollTask as any).locate) {\n // Old format - locate is the prompt, aiScroll is null/ignored\n locatePrompt = (scrollTask as any).locate;\n } else {\n // New format - aiScroll is the prompt, or no prompt for global scroll\n locatePrompt = aiScroll;\n }\n\n await agent.callActionInActionSpace('Scroll', {\n ...scrollTask,\n ...(locatePrompt\n ? { locate: buildDetailedLocateParam(locatePrompt, scrollTask) }\n : {}),\n });\n } else {\n // generic action, find the action in actionSpace\n\n /* for aiTap, aiRightClick, the parameters are a flattened data for the 'locate', these are all valid data\n\n - aiTap: 'search input box'\n - aiTap: 'search input box'\n deepThink: true\n cacheable: false\n - aiTap:\n prompt: 'search input box'\n - aiTap:\n prompt: 'search input box'\n deepThink: true\n cacheable: false\n */\n\n const actionSpace = this.actionSpace;\n let locatePromptShortcut: string | undefined;\n const matchedAction = actionSpace.find((action) => {\n const actionInterfaceAlias = action.interfaceAlias;\n if (\n actionInterfaceAlias &&\n Object.prototype.hasOwnProperty.call(flowItem, actionInterfaceAlias)\n ) {\n locatePromptShortcut = flowItem[\n actionInterfaceAlias as keyof typeof flowItem\n ] as string;\n return true;\n }\n\n const keyOfActionInActionSpace = action.name;\n if (\n Object.prototype.hasOwnProperty.call(\n flowItem,\n keyOfActionInActionSpace,\n )\n ) {\n locatePromptShortcut = flowItem[\n keyOfActionInActionSpace as keyof typeof flowItem\n ] as string;\n return true;\n }\n\n return false;\n });\n\n assert(\n matchedAction,\n `unknown flowItem in yaml: ${JSON.stringify(flowItem)}`,\n );\n\n // Create a new object instead of mutating the original flowItem\n // This prevents issues when the same YAML script is executed multiple times\n const flowItemForProcessing = locatePromptShortcut\n ? { ...flowItem, prompt: locatePromptShortcut }\n : flowItem;\n\n const { locateParam, restParams } =\n buildDetailedLocateParamAndRestParams(\n locatePromptShortcut || '',\n flowItemForProcessing as LocateOption,\n [\n matchedAction.name,\n matchedAction.interfaceAlias || '_never_mind_',\n ],\n );\n\n const flowParams = {\n ...restParams,\n locate: locateParam,\n };\n\n debug(\n `matchedAction: ${matchedAction.name}`,\n `flowParams: ${JSON.stringify(flowParams, null, 2)}`,\n );\n await agent.callActionInActionSpace(matchedAction.name, flowParams);\n }\n }\n this.reportFile = agent.reportFile;\n await this.flushUnstableLogContent();\n }\n\n async run() {\n const { target, web, android, ios, tasks } = this.script;\n const webEnv = web || target;\n const androidEnv = android;\n const iosEnv = ios;\n const platform = webEnv || androidEnv || iosEnv;\n\n this.setPlayerStatus('running');\n\n let agent: Agent | null = null;\n let freeFn: FreeFn[] = [];\n try {\n const { agent: newAgent, freeFn: newFreeFn } = await this.setupAgent(\n platform as T,\n );\n this.actionSpace = await newAgent.getActionSpace();\n agent = newAgent;\n const originalOnTaskStartTip = agent.onTaskStartTip;\n agent.onTaskStartTip = (tip) => {\n if (this.status === 'running') {\n this.agentStatusTip = tip;\n }\n originalOnTaskStartTip?.(tip);\n };\n freeFn = [\n ...(newFreeFn || []),\n {\n name: 'restore-agent-onTaskStartTip',\n fn: () => {\n if (agent) {\n agent.onTaskStartTip = originalOnTaskStartTip;\n }\n },\n },\n ];\n } catch (e) {\n this.setPlayerStatus('error', e as Error);\n return;\n }\n this.interfaceAgent = agent;\n\n let taskIndex = 0;\n this.setPlayerStatus('running');\n let errorFlag = false;\n while (taskIndex < tasks.length) {\n const taskStatus = this.taskStatusList[taskIndex];\n this.setTaskStatus(taskIndex, 'running' as any);\n this.setTaskIndex(taskIndex);\n\n try {\n await this.playTask(taskStatus, this.interfaceAgent);\n this.setTaskStatus(taskIndex, 'done' as any);\n } catch (e) {\n this.setTaskStatus(taskIndex, 'error' as any, e as Error);\n\n if (taskStatus.continueOnError) {\n // nothing more to do\n } else {\n this.reportFile = agent.reportFile;\n errorFlag = true;\n break;\n }\n }\n this.reportFile = agent?.reportFile;\n taskIndex++;\n }\n\n if (errorFlag) {\n this.setPlayerStatus('error');\n } else {\n this.setPlayerStatus('done');\n }\n this.agentStatusTip = '';\n\n // free the resources\n for (const fn of freeFn) {\n try {\n // console.log('freeing', fn.name);\n await fn.fn();\n // console.log('freed', fn.name);\n } catch (e) {\n // console.error('error freeing', fn.name, e);\n }\n }\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","debug","getDebug","ScriptPlayer","value","keyToUse","console","status","error","taskIndex","taskIndexToNotify","taskStatus","index","statusValue","output","resolve","process","outputDir","dirname","existsSync","mkdirSync","writeFileSync","JSON","undefined","_this_interfaceAgent","content","filePath","agent","flow","assert","flowItemIndex","currentStep","Number","flowItem","actionTask","prompt","assertTask","msg","pass","thought","message","Error","queryTask","options","queryResult","numberTask","numberResult","stringTask","stringResult","booleanTask","booleanResult","askTask","askResult","locateTask","locateResult","waitForTask","timeout","sleepTask","ms","msNumber","Promise","setTimeout","evaluateJavaScriptTask","result","recordTask","title","aiInput","rawValue","inputTask","locatePrompt","String","buildDetailedLocateParam","aiKeyboardPress","keyboardPressTask","keyName","aiScroll","scrollTask","actionSpace","locatePromptShortcut","matchedAction","action","actionInterfaceAlias","keyOfActionInActionSpace","flowItemForProcessing","locateParam","restParams","buildDetailedLocateParamAndRestParams","flowParams","target","web","android","ios","tasks","webEnv","androidEnv","iosEnv","platform","freeFn","newAgent","newFreeFn","originalOnTaskStartTip","tip","e","errorFlag","fn","script","setupAgent","onTaskStatusChange","scriptPath","_this_target","_this_target1","_this_target2","ifInBrowser","ifInWorker","scriptName","basename","join","getMidsceneRunSubDir","Date","task","_task_flow"],"mappings":"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"}
1
+ {"version":3,"file":"yaml/player.js","sources":["webpack://@midscene/core/webpack/runtime/define_property_getters","webpack://@midscene/core/webpack/runtime/has_own_property","webpack://@midscene/core/webpack/runtime/make_namespace_object","webpack://@midscene/core/./src/yaml/player.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { basename, dirname, join, resolve } from 'node:path';\nimport { assert, ifInBrowser, ifInWorker } from '@midscene/shared/utils';\nimport { type ZodTypeAny, z } from 'zod';\n\n// previous defined yaml flow, as a helper\ninterface MidsceneYamlFlowItemAIInput extends LocateOption {\n // previous version\n // aiInput: string; // value to input\n // locate: TUserPrompt; // where to input\n aiInput: TUserPrompt | undefined; // where to input\n value: string | number; // value to input\n}\n\ninterface MidsceneYamlFlowItemAIKeyboardPress extends LocateOption {\n // previous version\n // aiKeyboardPress: string;\n // locate?: TUserPrompt; // where to press, optional\n aiKeyboardPress: TUserPrompt | undefined; // where to press\n keyName: string; // key to press\n}\n\ninterface MidsceneYamlFlowItemAIScroll extends LocateOption, ScrollParam {\n // previous version\n // aiScroll: null;\n // locate?: TUserPrompt; // which area to scroll, optional\n aiScroll: TUserPrompt | undefined; // which area to scroll\n}\n\nimport type { Agent } from '@/agent/agent';\nimport type { TUserPrompt } from '@/ai-model/common';\nimport type {\n DeviceAction,\n FreeFn,\n LocateOption,\n MidsceneYamlFlowItemAIAction,\n MidsceneYamlFlowItemAIAsk,\n MidsceneYamlFlowItemAIAssert,\n MidsceneYamlFlowItemAIBoolean,\n MidsceneYamlFlowItemAILocate,\n MidsceneYamlFlowItemAINumber,\n MidsceneYamlFlowItemAIQuery,\n MidsceneYamlFlowItemAIString,\n MidsceneYamlFlowItemAIWaitFor,\n MidsceneYamlFlowItemEvaluateJavaScript,\n MidsceneYamlFlowItemLogScreenshot,\n MidsceneYamlFlowItemSleep,\n MidsceneYamlScript,\n MidsceneYamlScriptEnv,\n ScriptPlayerStatusValue,\n ScriptPlayerTaskStatus,\n ScrollParam,\n} from '@/types';\nimport { getMidsceneRunSubDir } from '@midscene/shared/common';\nimport { getDebug } from '@midscene/shared/logger';\nimport {\n buildDetailedLocateParam,\n buildDetailedLocateParamAndRestParams,\n} from './utils';\n\nconst debug = getDebug('yaml-player');\n\nconst isStringParamSchema = (schema?: ZodTypeAny): boolean => {\n if (!schema) {\n return false;\n }\n\n const schemaDef = (schema as any)?._def;\n if (!schemaDef?.typeName) {\n return false;\n }\n\n switch (schemaDef.typeName) {\n case z.ZodFirstPartyTypeKind.ZodString:\n case z.ZodFirstPartyTypeKind.ZodEnum:\n case z.ZodFirstPartyTypeKind.ZodNativeEnum:\n return true;\n case z.ZodFirstPartyTypeKind.ZodLiteral:\n return typeof schemaDef.value === 'string';\n case z.ZodFirstPartyTypeKind.ZodOptional:\n case z.ZodFirstPartyTypeKind.ZodNullable:\n case z.ZodFirstPartyTypeKind.ZodDefault:\n return isStringParamSchema(schemaDef.innerType);\n case z.ZodFirstPartyTypeKind.ZodEffects:\n return isStringParamSchema(schemaDef.schema);\n case z.ZodFirstPartyTypeKind.ZodPipeline:\n return isStringParamSchema(schemaDef.out);\n case z.ZodFirstPartyTypeKind.ZodUnion: {\n const options = schemaDef.options as ZodTypeAny[] | undefined;\n return Array.isArray(options)\n ? options.every((option) => isStringParamSchema(option))\n : false;\n }\n default:\n return false;\n }\n};\nexport class ScriptPlayer<T extends MidsceneYamlScriptEnv> {\n public currentTaskIndex?: number;\n public taskStatusList: ScriptPlayerTaskStatus[] = [];\n public status: ScriptPlayerStatusValue = 'init';\n public reportFile?: string | null;\n public result: Record<string, any>;\n private unnamedResultIndex = 0;\n public output?: string | null;\n public unstableLogContent?: string | null;\n public errorInSetup?: Error;\n private interfaceAgent: Agent | null = null;\n public agentStatusTip?: string;\n public target?: MidsceneYamlScriptEnv;\n private actionSpace: DeviceAction[] = [];\n private scriptPath?: string;\n constructor(\n private script: MidsceneYamlScript,\n private setupAgent: (platform: T) => Promise<{\n agent: Agent;\n freeFn: FreeFn[];\n }>,\n public onTaskStatusChange?: (taskStatus: ScriptPlayerTaskStatus) => void,\n scriptPath?: string,\n ) {\n this.scriptPath = scriptPath;\n this.result = {};\n this.target =\n script.target ||\n script.web ||\n script.android ||\n script.ios ||\n script.config;\n\n if (ifInBrowser || ifInWorker) {\n this.output = undefined;\n debug('output is undefined in browser or worker');\n } else if (this.target?.output) {\n this.output = resolve(process.cwd(), this.target.output);\n debug('setting output by config.output', this.output);\n } else {\n const scriptName = this.scriptPath\n ? basename(this.scriptPath, '.yaml').replace(/\\.(ya?ml)$/i, '')\n : 'script';\n this.output = join(\n getMidsceneRunSubDir('output'),\n `${scriptName}-${Date.now()}.json`,\n );\n debug('setting output by script path', this.output);\n }\n\n if (ifInBrowser || ifInWorker) {\n this.unstableLogContent = undefined;\n } else if (typeof this.target?.unstableLogContent === 'string') {\n this.unstableLogContent = resolve(\n process.cwd(),\n this.target.unstableLogContent,\n );\n } else if (this.target?.unstableLogContent === true) {\n this.unstableLogContent = join(\n getMidsceneRunSubDir('output'),\n 'unstableLogContent.json',\n );\n }\n\n this.taskStatusList = (script.tasks || []).map((task, taskIndex) => ({\n ...task,\n index: taskIndex,\n status: 'init',\n totalSteps: task.flow?.length || 0,\n }));\n }\n\n private setResult(key: string | undefined, value: any) {\n const keyToUse = key || this.unnamedResultIndex++;\n if (this.result[keyToUse]) {\n console.warn(`result key ${keyToUse} already exists, will overwrite`);\n }\n this.result[keyToUse] = value;\n\n return this.flushResult();\n }\n\n private setPlayerStatus(status: ScriptPlayerStatusValue, error?: Error) {\n this.status = status;\n this.errorInSetup = error;\n }\n\n private notifyCurrentTaskStatusChange(taskIndex?: number) {\n const taskIndexToNotify =\n typeof taskIndex === 'number' ? taskIndex : this.currentTaskIndex;\n\n if (typeof taskIndexToNotify !== 'number') {\n return;\n }\n\n const taskStatus = this.taskStatusList[taskIndexToNotify];\n if (this.onTaskStatusChange) {\n this.onTaskStatusChange(taskStatus);\n }\n }\n\n private async setTaskStatus(\n index: number,\n statusValue: ScriptPlayerStatusValue,\n error?: Error,\n ) {\n this.taskStatusList[index].status = statusValue;\n if (error) {\n this.taskStatusList[index].error = error;\n }\n\n this.notifyCurrentTaskStatusChange(index);\n }\n\n private setTaskIndex(taskIndex: number) {\n this.currentTaskIndex = taskIndex;\n }\n\n private flushResult() {\n if (this.output) {\n const output = resolve(process.cwd(), this.output);\n const outputDir = dirname(output);\n if (!existsSync(outputDir)) {\n mkdirSync(outputDir, { recursive: true });\n }\n writeFileSync(output, JSON.stringify(this.result || {}, undefined, 2));\n }\n }\n\n private flushUnstableLogContent() {\n if (this.unstableLogContent) {\n const content = this.interfaceAgent?._unstableLogContent();\n const filePath = resolve(process.cwd(), this.unstableLogContent);\n const outputDir = dirname(filePath);\n if (!existsSync(outputDir)) {\n mkdirSync(outputDir, { recursive: true });\n }\n writeFileSync(filePath, JSON.stringify(content, null, 2));\n }\n }\n\n async playTask(taskStatus: ScriptPlayerTaskStatus, agent: Agent) {\n const { flow } = taskStatus;\n assert(flow, 'missing flow in task');\n\n for (const flowItemIndex in flow) {\n const currentStep = Number.parseInt(flowItemIndex, 10);\n taskStatus.currentStep = currentStep;\n const flowItem = flow[flowItemIndex];\n debug(\n `playing step ${flowItemIndex}, flowItem=${JSON.stringify(flowItem)}`,\n );\n if (\n 'aiAct' in (flowItem as MidsceneYamlFlowItemAIAction) ||\n 'aiAction' in (flowItem as MidsceneYamlFlowItemAIAction) ||\n 'ai' in (flowItem as MidsceneYamlFlowItemAIAction)\n ) {\n const actionTask = flowItem as MidsceneYamlFlowItemAIAction;\n const prompt = actionTask.aiAct || actionTask.aiAction || actionTask.ai;\n assert(prompt, 'missing prompt for ai (aiAct)');\n await agent.aiAct(prompt, {\n cacheable: actionTask.cacheable,\n });\n } else if ('aiAssert' in (flowItem as MidsceneYamlFlowItemAIAssert)) {\n const assertTask = flowItem as MidsceneYamlFlowItemAIAssert;\n const prompt = assertTask.aiAssert;\n const msg = assertTask.errorMessage;\n assert(prompt, 'missing prompt for aiAssert');\n const { pass, thought, message } =\n (await agent.aiAssert(prompt, msg, {\n keepRawResponse: true,\n })) || {};\n\n this.setResult(assertTask.name, {\n pass,\n thought,\n message,\n });\n\n if (!pass) {\n throw new Error(message);\n }\n } else if ('aiQuery' in (flowItem as MidsceneYamlFlowItemAIQuery)) {\n const queryTask = flowItem as MidsceneYamlFlowItemAIQuery;\n const prompt = queryTask.aiQuery;\n const options = {\n domIncluded: queryTask.domIncluded,\n screenshotIncluded: queryTask.screenshotIncluded,\n };\n assert(prompt, 'missing prompt for aiQuery');\n const queryResult = await agent.aiQuery(prompt, options);\n this.setResult(queryTask.name, queryResult);\n } else if ('aiNumber' in (flowItem as MidsceneYamlFlowItemAINumber)) {\n const numberTask = flowItem as MidsceneYamlFlowItemAINumber;\n const prompt = numberTask.aiNumber;\n const options = {\n domIncluded: numberTask.domIncluded,\n screenshotIncluded: numberTask.screenshotIncluded,\n };\n assert(prompt, 'missing prompt for aiNumber');\n const numberResult = await agent.aiNumber(prompt, options);\n this.setResult(numberTask.name, numberResult);\n } else if ('aiString' in (flowItem as MidsceneYamlFlowItemAIString)) {\n const stringTask = flowItem as MidsceneYamlFlowItemAIString;\n const prompt = stringTask.aiString;\n const options = {\n domIncluded: stringTask.domIncluded,\n screenshotIncluded: stringTask.screenshotIncluded,\n };\n assert(prompt, 'missing prompt for aiString');\n const stringResult = await agent.aiString(prompt, options);\n this.setResult(stringTask.name, stringResult);\n } else if ('aiBoolean' in (flowItem as MidsceneYamlFlowItemAIBoolean)) {\n const booleanTask = flowItem as MidsceneYamlFlowItemAIBoolean;\n const prompt = booleanTask.aiBoolean;\n const options = {\n domIncluded: booleanTask.domIncluded,\n screenshotIncluded: booleanTask.screenshotIncluded,\n };\n assert(prompt, 'missing prompt for aiBoolean');\n const booleanResult = await agent.aiBoolean(prompt, options);\n this.setResult(booleanTask.name, booleanResult);\n } else if ('aiAsk' in (flowItem as MidsceneYamlFlowItemAIAsk)) {\n const askTask = flowItem as MidsceneYamlFlowItemAIAsk;\n const prompt = askTask.aiAsk;\n assert(prompt, 'missing prompt for aiAsk');\n const askResult = await agent.aiAsk(prompt);\n this.setResult(askTask.name, askResult);\n } else if ('aiLocate' in (flowItem as MidsceneYamlFlowItemAILocate)) {\n const locateTask = flowItem as MidsceneYamlFlowItemAILocate;\n const prompt = locateTask.aiLocate;\n assert(prompt, 'missing prompt for aiLocate');\n const locateResult = await agent.aiLocate(prompt, locateTask);\n this.setResult(locateTask.name, locateResult);\n } else if ('aiWaitFor' in (flowItem as MidsceneYamlFlowItemAIWaitFor)) {\n const waitForTask = flowItem as MidsceneYamlFlowItemAIWaitFor;\n const prompt = waitForTask.aiWaitFor;\n assert(prompt, 'missing prompt for aiWaitFor');\n const timeout = waitForTask.timeout;\n await agent.aiWaitFor(prompt, { timeoutMs: timeout });\n } else if ('sleep' in (flowItem as MidsceneYamlFlowItemSleep)) {\n const sleepTask = flowItem as MidsceneYamlFlowItemSleep;\n const ms = sleepTask.sleep;\n let msNumber = ms;\n if (typeof ms === 'string') {\n msNumber = Number.parseInt(ms, 10);\n }\n assert(\n msNumber && msNumber > 0,\n `ms for sleep must be greater than 0, but got ${ms}`,\n );\n await new Promise((resolve) => setTimeout(resolve, msNumber));\n } else if (\n 'javascript' in (flowItem as MidsceneYamlFlowItemEvaluateJavaScript)\n ) {\n const evaluateJavaScriptTask =\n flowItem as MidsceneYamlFlowItemEvaluateJavaScript;\n\n const result = await agent.evaluateJavaScript(\n evaluateJavaScriptTask.javascript,\n );\n this.setResult(evaluateJavaScriptTask.name, result);\n } else if (\n 'logScreenshot' in (flowItem as MidsceneYamlFlowItemLogScreenshot) ||\n 'recordToReport' in (flowItem as MidsceneYamlFlowItemLogScreenshot)\n ) {\n const recordTask = flowItem as MidsceneYamlFlowItemLogScreenshot;\n const title =\n recordTask.recordToReport ?? recordTask.logScreenshot ?? 'untitled';\n const content = recordTask.content || '';\n await agent.recordToReport(title, { content });\n } else if ('aiInput' in (flowItem as MidsceneYamlFlowItemAIInput)) {\n // may be input empty string ''\n const {\n aiInput,\n value: rawValue,\n ...inputTask\n } = flowItem as MidsceneYamlFlowItemAIInput;\n\n // Compatibility with previous version:\n // Old format: { aiInput: string (value), locate: TUserPrompt }\n // New format - 1: { aiInput: TUserPrompt, value: string | number }\n // New format - 2: { aiInput: undefined, locate: TUserPrompt, value: string | number }\n let locatePrompt: TUserPrompt | undefined;\n let value: string | number | undefined;\n if ((inputTask as any).locate) {\n // Old format - aiInput is the value, locate is the prompt\n // Keep backward compatibility: empty string is treated as no value\n value = (aiInput as string | number) || rawValue;\n locatePrompt = (inputTask as any).locate;\n } else {\n // New format - aiInput is the prompt, value is the value\n locatePrompt = aiInput || '';\n value = rawValue;\n }\n\n // Convert value to string for Input action\n await agent.callActionInActionSpace('Input', {\n ...inputTask,\n ...(value !== undefined ? { value: String(value) } : {}),\n ...(locatePrompt\n ? { locate: buildDetailedLocateParam(locatePrompt, inputTask) }\n : {}),\n });\n } else if (\n 'aiKeyboardPress' in (flowItem as MidsceneYamlFlowItemAIKeyboardPress)\n ) {\n const { aiKeyboardPress, ...keyboardPressTask } =\n flowItem as MidsceneYamlFlowItemAIKeyboardPress;\n\n // Compatibility with previous version:\n // Old format: { aiKeyboardPress: string (key), locate?: TUserPrompt }\n // New format - 1: { aiKeyboardPress: TUserPrompt, keyName: string }\n // New format - 2: { aiKeyboardPress: , locate?: TUserPrompt, keyName: string }\n let locatePrompt: TUserPrompt | undefined;\n let keyName: string | undefined;\n if ((keyboardPressTask as any).locate) {\n // Old format - aiKeyboardPress is the key, locate is the prompt\n keyName = aiKeyboardPress as string;\n locatePrompt = (keyboardPressTask as any).locate;\n } else if (keyboardPressTask.keyName) {\n // New format - aiKeyboardPress is the prompt, key is the key\n keyName = keyboardPressTask.keyName;\n locatePrompt = aiKeyboardPress;\n } else {\n keyName = aiKeyboardPress as string;\n }\n\n await agent.callActionInActionSpace('KeyboardPress', {\n ...keyboardPressTask,\n ...(keyName ? { keyName } : {}),\n ...(locatePrompt\n ? {\n locate: buildDetailedLocateParam(\n locatePrompt,\n keyboardPressTask,\n ),\n }\n : {}),\n });\n } else if ('aiScroll' in (flowItem as MidsceneYamlFlowItemAIScroll)) {\n const { aiScroll, ...scrollTask } =\n flowItem as MidsceneYamlFlowItemAIScroll;\n\n // Compatibility with previous version:\n // Old format: { aiScroll: null, locate?: TUserPrompt, direction, scrollType, distance? }\n // New format - 1: { aiScroll: TUserPrompt, direction, scrollType, distance? }\n // New format - 2: { aiScroll: undefined, locate: TUserPrompt, direction, scrollType, distance? }\n let locatePrompt: TUserPrompt | undefined;\n if ((scrollTask as any).locate) {\n // Old format - locate is the prompt, aiScroll is null/ignored\n locatePrompt = (scrollTask as any).locate;\n } else {\n // New format - aiScroll is the prompt, or no prompt for global scroll\n locatePrompt = aiScroll;\n }\n\n await agent.callActionInActionSpace('Scroll', {\n ...scrollTask,\n ...(locatePrompt\n ? { locate: buildDetailedLocateParam(locatePrompt, scrollTask) }\n : {}),\n });\n } else {\n // generic action, find the action in actionSpace\n\n /* for aiTap, aiRightClick, the parameters are a flattened data for the 'locate', these are all valid data\n\n - aiTap: 'search input box'\n - aiTap: 'search input box'\n deepThink: true\n cacheable: false\n - aiTap:\n prompt: 'search input box'\n - aiTap:\n prompt: 'search input box'\n deepThink: true\n cacheable: false\n */\n\n const actionSpace = this.actionSpace;\n let locatePromptShortcut: string | undefined;\n let actionParamForMatchedAction: unknown;\n const matchedAction = actionSpace.find((action) => {\n const actionInterfaceAlias = action.interfaceAlias;\n if (\n actionInterfaceAlias &&\n Object.prototype.hasOwnProperty.call(flowItem, actionInterfaceAlias)\n ) {\n actionParamForMatchedAction =\n flowItem[actionInterfaceAlias as keyof typeof flowItem];\n if (typeof actionParamForMatchedAction === 'string') {\n locatePromptShortcut = actionParamForMatchedAction;\n }\n return true;\n }\n\n const keyOfActionInActionSpace = action.name;\n if (\n Object.prototype.hasOwnProperty.call(\n flowItem,\n keyOfActionInActionSpace,\n )\n ) {\n actionParamForMatchedAction =\n flowItem[keyOfActionInActionSpace as keyof typeof flowItem];\n if (typeof actionParamForMatchedAction === 'string') {\n locatePromptShortcut = actionParamForMatchedAction;\n }\n return true;\n }\n\n return false;\n });\n\n assert(\n matchedAction,\n `unknown flowItem in yaml: ${JSON.stringify(flowItem)}`,\n );\n\n const schemaIsStringParam = isStringParamSchema(\n matchedAction.paramSchema,\n );\n let stringParamToCall: string | undefined;\n if (\n typeof actionParamForMatchedAction === 'string' &&\n schemaIsStringParam\n ) {\n if (matchedAction.paramSchema) {\n const parseResult = matchedAction.paramSchema.safeParse(\n actionParamForMatchedAction,\n );\n if (parseResult.success && typeof parseResult.data === 'string') {\n stringParamToCall = parseResult.data;\n } else if (!parseResult.success) {\n debug(\n `parse failed for action ${matchedAction.name} with string param`,\n parseResult.error,\n );\n stringParamToCall = actionParamForMatchedAction;\n }\n } else {\n stringParamToCall = actionParamForMatchedAction;\n }\n }\n\n if (stringParamToCall !== undefined) {\n debug(\n `matchedAction: ${matchedAction.name}`,\n `flowParams: ${JSON.stringify(stringParamToCall)}`,\n );\n const result = await agent.callActionInActionSpace(\n matchedAction.name,\n stringParamToCall,\n );\n\n // Store result if there's a name property in flowItem\n const resultName = (flowItem as any).name;\n if (result !== undefined) {\n this.setResult(resultName, result);\n }\n } else {\n // Determine the source for parameter extraction:\n // - If we have a locatePromptShortcut, use the flowItem (for actions like aiTap with prompt)\n // - Otherwise, use actionParamForMatchedAction (for actions like runWdaRequest with structured params)\n const sourceForParams =\n locatePromptShortcut &&\n typeof actionParamForMatchedAction === 'string'\n ? { ...flowItem, prompt: locatePromptShortcut }\n : typeof actionParamForMatchedAction === 'object' &&\n actionParamForMatchedAction !== null\n ? actionParamForMatchedAction\n : flowItem;\n\n const { locateParam, restParams } =\n buildDetailedLocateParamAndRestParams(\n locatePromptShortcut || '',\n sourceForParams as LocateOption,\n [\n matchedAction.name,\n matchedAction.interfaceAlias || '_never_mind_',\n ],\n );\n\n const flowParams = {\n ...restParams,\n locate: locateParam,\n };\n\n debug(\n `matchedAction: ${matchedAction.name}`,\n `flowParams: ${JSON.stringify(flowParams, null, 2)}`,\n );\n const result = await agent.callActionInActionSpace(\n matchedAction.name,\n flowParams,\n );\n\n // Store result if there's a name property in flowItem\n const resultName = (flowItem as any).name;\n if (result !== undefined) {\n this.setResult(resultName, result);\n }\n }\n }\n }\n this.reportFile = agent.reportFile;\n await this.flushUnstableLogContent();\n }\n\n async run() {\n const { target, web, android, ios, tasks } = this.script;\n const webEnv = web || target;\n const androidEnv = android;\n const iosEnv = ios;\n const platform = webEnv || androidEnv || iosEnv;\n\n this.setPlayerStatus('running');\n\n let agent: Agent | null = null;\n let freeFn: FreeFn[] = [];\n try {\n const { agent: newAgent, freeFn: newFreeFn } = await this.setupAgent(\n platform as T,\n );\n this.actionSpace = await newAgent.getActionSpace();\n agent = newAgent;\n const originalOnTaskStartTip = agent.onTaskStartTip;\n agent.onTaskStartTip = (tip) => {\n if (this.status === 'running') {\n this.agentStatusTip = tip;\n }\n originalOnTaskStartTip?.(tip);\n };\n freeFn = [\n ...(newFreeFn || []),\n {\n name: 'restore-agent-onTaskStartTip',\n fn: () => {\n if (agent) {\n agent.onTaskStartTip = originalOnTaskStartTip;\n }\n },\n },\n ];\n } catch (e) {\n this.setPlayerStatus('error', e as Error);\n return;\n }\n this.interfaceAgent = agent;\n\n let taskIndex = 0;\n this.setPlayerStatus('running');\n let errorFlag = false;\n while (taskIndex < tasks.length) {\n const taskStatus = this.taskStatusList[taskIndex];\n this.setTaskStatus(taskIndex, 'running' as any);\n this.setTaskIndex(taskIndex);\n\n try {\n await this.playTask(taskStatus, this.interfaceAgent);\n this.setTaskStatus(taskIndex, 'done' as any);\n } catch (e) {\n this.setTaskStatus(taskIndex, 'error' as any, e as Error);\n\n if (taskStatus.continueOnError) {\n // nothing more to do\n } else {\n this.reportFile = agent.reportFile;\n errorFlag = true;\n break;\n }\n }\n this.reportFile = agent?.reportFile;\n taskIndex++;\n }\n\n if (errorFlag) {\n this.setPlayerStatus('error');\n } else {\n this.setPlayerStatus('done');\n }\n this.agentStatusTip = '';\n\n // free the resources\n for (const fn of freeFn) {\n try {\n // console.log('freeing', fn.name);\n await fn.fn();\n // console.log('freed', fn.name);\n } catch (e) {\n // console.error('error freeing', fn.name, e);\n }\n }\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","debug","getDebug","isStringParamSchema","schema","schemaDef","z","options","Array","option","ScriptPlayer","value","keyToUse","console","status","error","taskIndex","taskIndexToNotify","taskStatus","index","statusValue","output","resolve","process","outputDir","dirname","existsSync","mkdirSync","writeFileSync","JSON","undefined","_this_interfaceAgent","content","filePath","agent","flow","assert","flowItemIndex","currentStep","Number","flowItem","actionTask","prompt","assertTask","msg","pass","thought","message","Error","queryTask","queryResult","numberTask","numberResult","stringTask","stringResult","booleanTask","booleanResult","askTask","askResult","locateTask","locateResult","waitForTask","timeout","sleepTask","ms","msNumber","Promise","setTimeout","evaluateJavaScriptTask","result","recordTask","title","aiInput","rawValue","inputTask","locatePrompt","String","buildDetailedLocateParam","aiKeyboardPress","keyboardPressTask","keyName","aiScroll","scrollTask","actionSpace","locatePromptShortcut","actionParamForMatchedAction","matchedAction","action","actionInterfaceAlias","keyOfActionInActionSpace","schemaIsStringParam","stringParamToCall","parseResult","resultName","sourceForParams","locateParam","restParams","buildDetailedLocateParamAndRestParams","flowParams","target","web","android","ios","tasks","webEnv","androidEnv","iosEnv","platform","freeFn","newAgent","newFreeFn","originalOnTaskStartTip","tip","e","errorFlag","fn","script","setupAgent","onTaskStatusChange","scriptPath","_this_target","_this_target1","_this_target2","ifInBrowser","ifInWorker","scriptName","basename","join","getMidsceneRunSubDir","Date","task","_task_flow"],"mappings":"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"}
@@ -1,6 +1,7 @@
1
- import { type AgentAssertOpt, type AgentDescribeElementAtPointResult, type AgentOpt, type AgentWaitForOpt, type DeviceAction, type ExecutionDump, type GroupedActionDump, type LocateOption, type LocateResultElement, type LocateValidatorResult, type LocatorValidatorOption, type OnTaskStartTip, type ScrollParam, Service, type ServiceAction, type ServiceExtractOption, type ServiceExtractParam, type TUserPrompt, type UIContext } from '../index';
1
+ import { type ActionParam, type ActionReturn, type AgentAssertOpt, type AgentDescribeElementAtPointResult, type AgentOpt, type AgentWaitForOpt, type DeviceAction, type ExecutionDump, type GroupedActionDump, type LocateOption, type LocateResultElement, type LocateValidatorResult, type LocatorValidatorOption, type OnTaskStartTip, type ScrollParam, Service, type ServiceAction, type ServiceExtractOption, type ServiceExtractParam, type TUserPrompt, type UIContext } from '../index';
2
2
  export type TestStatus = 'passed' | 'failed' | 'timedOut' | 'skipped' | 'interrupted';
3
3
  import type { AbstractInterface } from '../device';
4
+ import type { TaskRunner } from '../task-runner';
4
5
  import { ModelConfigManager } from '@midscene/shared/env';
5
6
  import { TaskCache } from './task-cache';
6
7
  import { TaskExecutor } from './tasks';
@@ -37,6 +38,7 @@ export declare class Agent<InterfaceType extends AbstractInterface = AbstractInt
37
38
  * Internal promise to deduplicate screenshot scale computation
38
39
  */
39
40
  private screenshotScalePromise?;
41
+ private executionDumpIndexByRunner;
40
42
  get page(): InterfaceType;
41
43
  /**
42
44
  * Ensures VL model warning is shown once when needed
@@ -52,12 +54,13 @@ export declare class Agent<InterfaceType extends AbstractInterface = AbstractInt
52
54
  _snapshotContext(): Promise<UIContext>;
53
55
  setAIActionContext(prompt: string): Promise<void>;
54
56
  resetDump(): GroupedActionDump;
55
- appendExecutionDump(execution: ExecutionDump): void;
57
+ appendExecutionDump(execution: ExecutionDump, runner?: TaskRunner): void;
56
58
  dumpDataString(): string;
57
59
  reportHTMLString(): string;
58
60
  writeOutActionDumps(): void;
59
61
  private callbackOnTaskStartTip;
60
- private afterTaskRunning;
62
+ private handleRunnerAfterFlush;
63
+ wrapActionInActionSpace<T extends DeviceAction>(name: string): (param: ActionParam<T>) => Promise<ActionReturn<T>>;
61
64
  callActionInActionSpace<T = any>(type: string, opt?: T): Promise<any>;
62
65
  aiTap(locatePrompt: TUserPrompt, opt?: LocateOption): Promise<any>;
63
66
  aiRightClick(locatePrompt: TUserPrompt, opt?: LocateOption): Promise<any>;
@@ -1,13 +1,15 @@
1
- import { TaskRunner } from '../task-runner';
1
+ import { type TaskExecutionError, TaskRunner } from '../task-runner';
2
2
  import type { ExecutionTaskApply, ExecutionTaskProgressOptions, UIContext } from '../types';
3
+ type ExecutionSessionOptions = ExecutionTaskProgressOptions & {
4
+ tasks?: ExecutionTaskApply[];
5
+ onTaskUpdate?: (runner: TaskRunner, error?: TaskExecutionError) => Promise<void> | void;
6
+ };
3
7
  /**
4
8
  * Thin wrapper around {@link TaskRunner} that represents a single linear execution run.
5
9
  */
6
10
  export declare class ExecutionSession {
7
11
  private readonly runner;
8
- constructor(name: string, contextProvider: () => Promise<UIContext>, options?: ExecutionTaskProgressOptions & {
9
- tasks?: ExecutionTaskApply[];
10
- });
12
+ constructor(name: string, contextProvider: () => Promise<UIContext>, options?: ExecutionSessionOptions);
11
13
  append(tasks: ExecutionTaskApply[] | ExecutionTaskApply): Promise<void>;
12
14
  appendAndRun(tasks: ExecutionTaskApply[] | ExecutionTaskApply): Promise<{
13
15
  output: any;
@@ -25,3 +27,4 @@ export declare class ExecutionSession {
25
27
  }>;
26
28
  getRunner(): TaskRunner;
27
29
  }
30
+ export {};
@@ -2,6 +2,7 @@ import type { TMultimodalPrompt, TUserPrompt } from '../ai-model/common';
2
2
  import type { AbstractInterface } from '../device';
3
3
  import type Service from '../service';
4
4
  import type { TaskRunner } from '../task-runner';
5
+ import { TaskExecutionError } from '../task-runner';
5
6
  import type { ExecutionTaskApply, ExecutionTaskProgressOptions, MidsceneYamlFlowItem, PlanningAction, PlanningActionParamSleep, PlanningActionParamWaitFor, ServiceExtractOption, ServiceExtractParam } from '../types';
6
7
  import { type IModelConfig } from '@midscene/shared/env';
7
8
  import type { TaskCache } from './task-cache';
@@ -11,6 +12,10 @@ interface ExecutionResult<OutputType = any> {
11
12
  thought?: string;
12
13
  runner: TaskRunner;
13
14
  }
15
+ interface TaskExecutorHooks {
16
+ onTaskUpdate?: (runner: TaskRunner, error?: TaskExecutionError) => Promise<void> | void;
17
+ }
18
+ export { TaskExecutionError };
14
19
  export declare class TaskExecutor {
15
20
  interface: AbstractInterface;
16
21
  service: Service;
@@ -18,12 +23,14 @@ export declare class TaskExecutor {
18
23
  private readonly taskBuilder;
19
24
  private conversationHistory;
20
25
  onTaskStartCallback?: ExecutionTaskProgressOptions['onTaskStart'];
26
+ private readonly hooks?;
21
27
  replanningCycleLimit?: number;
22
28
  get page(): AbstractInterface;
23
29
  constructor(interfaceInstance: AbstractInterface, service: Service, opts: {
24
30
  taskCache?: TaskCache;
25
31
  onTaskStart?: ExecutionTaskProgressOptions['onTaskStart'];
26
32
  replanningCycleLimit?: number;
33
+ hooks?: TaskExecutorHooks;
27
34
  });
28
35
  private createExecutionSession;
29
36
  convertPlanToExecutable(plans: PlanningAction[], modelConfig: IModelConfig, options?: {
@@ -22,13 +22,13 @@ export declare abstract class AbstractInterface {
22
22
  abstract evaluateJavaScript?<T = any>(script: string): Promise<T>;
23
23
  abstract getContext?(): Promise<UIContext>;
24
24
  }
25
- export declare const defineAction: <TSchema extends z.ZodType, TRuntime = z.infer<TSchema>>(config: {
25
+ export declare const defineAction: <TSchema extends z.ZodType, TRuntime = z.infer<TSchema>, TReturn = any>(config: {
26
26
  name: string;
27
27
  description: string;
28
28
  interfaceAlias?: string;
29
29
  paramSchema: TSchema;
30
- call: (param: TRuntime) => Promise<void>;
31
- } & Partial<Omit<DeviceAction<TRuntime>, "name" | "description" | "interfaceAlias" | "paramSchema" | "call">>) => DeviceAction<TRuntime>;
30
+ call: (param: TRuntime) => Promise<TReturn> | TReturn;
31
+ } & Partial<Omit<DeviceAction<TRuntime, TReturn>, "name" | "description" | "interfaceAlias" | "paramSchema" | "call">>) => DeviceAction<TRuntime, TReturn>;
32
32
  export declare const actionTapParamSchema: z.ZodObject<{
33
33
  locate: z.ZodObject<{
34
34
  prompt: z.ZodUnion<[z.ZodString, z.ZodIntersection<z.ZodObject<{
@@ -1,13 +1,17 @@
1
1
  import type { ExecutionDump, ExecutionTask, ExecutionTaskApply, ExecutionTaskProgressOptions, UIContext } from './types';
2
+ type TaskRunnerInitOptions = ExecutionTaskProgressOptions & {
3
+ tasks?: ExecutionTaskApply[];
4
+ onTaskUpdate?: (runner: TaskRunner, error?: TaskExecutionError) => Promise<void> | void;
5
+ };
2
6
  export declare class TaskRunner {
3
7
  name: string;
4
8
  tasks: ExecutionTask[];
5
9
  status: 'init' | 'pending' | 'running' | 'completed' | 'error';
6
10
  onTaskStart?: ExecutionTaskProgressOptions['onTaskStart'];
7
11
  private readonly uiContextBuilder;
8
- constructor(name: string, uiContextBuilder: () => Promise<UIContext>, options?: ExecutionTaskProgressOptions & {
9
- tasks?: ExecutionTaskApply[];
10
- });
12
+ private readonly onTaskUpdate?;
13
+ constructor(name: string, uiContextBuilder: () => Promise<UIContext>, options?: TaskRunnerInitOptions);
14
+ private emitOnTaskUpdate;
11
15
  private lastUiContext?;
12
16
  private getUiContext;
13
17
  private captureScreenshot;
@@ -31,3 +35,11 @@ export declare class TaskRunner {
31
35
  runner: TaskRunner;
32
36
  }>;
33
37
  }
38
+ export declare class TaskExecutionError extends Error {
39
+ runner: TaskRunner;
40
+ errorTask: ExecutionTask | null;
41
+ constructor(message: string, runner: TaskRunner, errorTask: ExecutionTask | null, options?: {
42
+ cause?: unknown;
43
+ });
44
+ }
45
+ export {};
@@ -229,7 +229,7 @@ export interface ExecutionRecorderItem {
229
229
  screenshot?: string;
230
230
  timing?: string;
231
231
  }
232
- export type ExecutionTaskType = 'Planning' | 'Insight' | 'Action' | 'Assertion' | 'Log';
232
+ export type ExecutionTaskType = 'Planning' | 'Insight' | 'Action Space' | 'Log';
233
233
  export interface ExecutorContext {
234
234
  task: ExecutionTask;
235
235
  element?: LocateResultElement | null;
@@ -294,7 +294,7 @@ export interface ExecutionTaskInsightAssertionParam {
294
294
  }
295
295
  export type ExecutionTaskInsightAssertionApply = ExecutionTaskApply<'Insight', ExecutionTaskInsightAssertionParam, ServiceAssertionResponse, ExecutionTaskInsightDump>;
296
296
  export type ExecutionTaskInsightAssertion = ExecutionTask<ExecutionTaskInsightAssertionApply>;
297
- export type ExecutionTaskActionApply<ActionParam = any> = ExecutionTaskApply<'Action', ActionParam, void, void>;
297
+ export type ExecutionTaskActionApply<ActionParam = any> = ExecutionTaskApply<'Action Space', ActionParam, void, void>;
298
298
  export type ExecutionTaskAction = ExecutionTask<ExecutionTaskActionApply>;
299
299
  export type ExecutionTaskLogApply<LogParam = {
300
300
  content: string;
@@ -302,8 +302,16 @@ export type ExecutionTaskLogApply<LogParam = {
302
302
  export type ExecutionTaskLog = ExecutionTask<ExecutionTaskLogApply>;
303
303
  export type ExecutionTaskPlanningApply = ExecutionTaskApply<'Planning', {
304
304
  userInstruction: string;
305
+ aiActionContext?: string;
305
306
  }, PlanningAIResponse>;
306
307
  export type ExecutionTaskPlanning = ExecutionTask<ExecutionTaskPlanningApply>;
308
+ export type ExecutionTaskPlanningLocateParam = PlanningLocateParam;
309
+ export interface ExecutionTaskPlanningLocateOutput {
310
+ element: LocateResultElement | null;
311
+ }
312
+ export type ExecutionTaskPlanningDump = ServiceDump;
313
+ export type ExecutionTaskPlanningLocateApply = ExecutionTaskApply<'Planning', ExecutionTaskPlanningLocateParam, ExecutionTaskPlanningLocateOutput, ExecutionTaskPlanningDump>;
314
+ export type ExecutionTaskPlanningLocate = ExecutionTask<ExecutionTaskPlanningLocateApply>;
307
315
  export interface GroupedActionDump {
308
316
  sdkVersion: string;
309
317
  groupName: string;
@@ -343,15 +351,25 @@ export interface StreamingAIResponse {
343
351
  /** Whether the response was streamed */
344
352
  isStreamed: boolean;
345
353
  }
346
- export interface DeviceAction<T = any> {
354
+ export interface DeviceAction<TParam = any, TReturn = any> {
347
355
  name: string;
348
356
  description?: string;
349
357
  interfaceAlias?: string;
350
- paramSchema?: z.ZodType<T>;
351
- /** Optional delay (ms) after runner execution. This is useful to wait for the UI to update. Defaults to 300ms. Set to 0 to skip. */
358
+ paramSchema?: z.ZodType<TParam>;
359
+ call: (param: TParam, context: ExecutorContext) => Promise<TReturn> | TReturn;
352
360
  delayAfterRunner?: number;
353
- call: (param: T, context: ExecutorContext) => Promise<void> | void;
354
361
  }
362
+ /**
363
+ * Type utilities for extracting types from DeviceAction definitions
364
+ */
365
+ /**
366
+ * Extract parameter type from a DeviceAction
367
+ */
368
+ export type ActionParam<Action extends DeviceAction<any, any>> = Action extends DeviceAction<infer P, any> ? P : never;
369
+ /**
370
+ * Extract return type from a DeviceAction
371
+ */
372
+ export type ActionReturn<Action extends DeviceAction<any, any>> = Action extends DeviceAction<any, infer R> ? R : never;
355
373
  /**
356
374
  * Web-specific types
357
375
  */
@@ -12,7 +12,6 @@ export interface LocateOption {
12
12
  export interface ServiceExtractOption {
13
13
  domIncluded?: boolean | 'visible-only';
14
14
  screenshotIncluded?: boolean;
15
- doNotThrowError?: boolean;
16
15
  }
17
16
  export interface ReferenceImage {
18
17
  base64: string;
@@ -129,7 +128,7 @@ export interface MidsceneYamlFlowItemLogScreenshot {
129
128
  recordToReport?: string;
130
129
  content?: string;
131
130
  }
132
- export type MidsceneYamlFlowItem = MidsceneYamlFlowItemAIAction | MidsceneYamlFlowItemAIAssert | MidsceneYamlFlowItemAIQuery | MidsceneYamlFlowItemAIWaitFor | MidsceneYamlFlowItemSleep | MidsceneYamlFlowItemLogScreenshot;
131
+ export type MidsceneYamlFlowItem = MidsceneYamlFlowItemAIAction | MidsceneYamlFlowItemAIAssert | MidsceneYamlFlowItemAIQuery | MidsceneYamlFlowItemAINumber | MidsceneYamlFlowItemAIString | MidsceneYamlFlowItemAIAsk | MidsceneYamlFlowItemAIBoolean | MidsceneYamlFlowItemAILocate | MidsceneYamlFlowItemAIWaitFor | MidsceneYamlFlowItemEvaluateJavaScript | MidsceneYamlFlowItemSleep | MidsceneYamlFlowItemLogScreenshot;
133
132
  export interface FreeFn {
134
133
  name: string;
135
134
  fn: () => void;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@midscene/core",
3
3
  "description": "Automate browser actions, extract data, and perform assertions using AI. It offers JavaScript SDK, Chrome extension, and support for scripting in YAML. See https://midscenejs.com/ for details.",
4
- "version": "1.0.1-beta-20251030070226.0",
4
+ "version": "1.0.1-beta-20251104075048.0",
5
5
  "repository": "https://github.com/web-infra-dev/midscene",
6
6
  "homepage": "https://midscenejs.com/",
7
7
  "main": "./dist/lib/index.js",
@@ -89,7 +89,7 @@
89
89
  "zod": "3.24.3",
90
90
  "semver": "7.5.2",
91
91
  "js-yaml": "4.1.0",
92
- "@midscene/shared": "1.0.1-beta-20251030070226.0"
92
+ "@midscene/shared": "1.0.1-beta-20251104075048.0"
93
93
  },
94
94
  "devDependencies": {
95
95
  "@rslib/core": "^0.11.2",