@midscene/core 0.30.5 → 1.0.1-beta-20251021060907.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 (87) hide show
  1. package/dist/es/agent/agent.mjs +41 -33
  2. package/dist/es/agent/agent.mjs.map +1 -1
  3. package/dist/es/agent/execution-session.mjs +41 -0
  4. package/dist/es/agent/execution-session.mjs.map +1 -0
  5. package/dist/es/agent/task-builder.mjs +303 -0
  6. package/dist/es/agent/task-builder.mjs.map +1 -0
  7. package/dist/es/agent/tasks.mjs +68 -391
  8. package/dist/es/agent/tasks.mjs.map +1 -1
  9. package/dist/es/agent/ui-utils.mjs.map +1 -1
  10. package/dist/es/agent/utils.mjs +6 -6
  11. package/dist/es/agent/utils.mjs.map +1 -1
  12. package/dist/es/ai-model/common.mjs +1 -15
  13. package/dist/es/ai-model/common.mjs.map +1 -1
  14. package/dist/es/ai-model/inspect.mjs +2 -3
  15. package/dist/es/ai-model/inspect.mjs.map +1 -1
  16. package/dist/es/ai-model/llm-planning.mjs +6 -24
  17. package/dist/es/ai-model/llm-planning.mjs.map +1 -1
  18. package/dist/es/ai-model/prompt/llm-locator.mjs +3 -204
  19. package/dist/es/ai-model/prompt/llm-locator.mjs.map +1 -1
  20. package/dist/es/ai-model/service-caller/index.mjs +101 -231
  21. package/dist/es/ai-model/service-caller/index.mjs.map +1 -1
  22. package/dist/es/index.mjs +3 -2
  23. package/dist/es/index.mjs.map +1 -1
  24. package/dist/es/insight/index.mjs +18 -19
  25. package/dist/es/insight/index.mjs.map +1 -1
  26. package/dist/es/insight/utils.mjs +3 -3
  27. package/dist/es/insight/utils.mjs.map +1 -1
  28. package/dist/es/report.mjs.map +1 -1
  29. package/dist/es/{ai-model/action-executor.mjs → task-runner.mjs} +69 -10
  30. package/dist/es/task-runner.mjs.map +1 -0
  31. package/dist/es/types.mjs +18 -1
  32. package/dist/es/types.mjs.map +1 -1
  33. package/dist/es/utils.mjs +2 -2
  34. package/dist/es/yaml/player.mjs +18 -14
  35. package/dist/es/yaml/player.mjs.map +1 -1
  36. package/dist/lib/agent/agent.js +41 -33
  37. package/dist/lib/agent/agent.js.map +1 -1
  38. package/dist/lib/agent/execution-session.js +75 -0
  39. package/dist/lib/agent/execution-session.js.map +1 -0
  40. package/dist/lib/agent/task-builder.js +340 -0
  41. package/dist/lib/agent/task-builder.js.map +1 -0
  42. package/dist/lib/agent/tasks.js +68 -391
  43. package/dist/lib/agent/tasks.js.map +1 -1
  44. package/dist/lib/agent/ui-utils.js.map +1 -1
  45. package/dist/lib/agent/utils.js +6 -6
  46. package/dist/lib/agent/utils.js.map +1 -1
  47. package/dist/lib/ai-model/common.js +2 -19
  48. package/dist/lib/ai-model/common.js.map +1 -1
  49. package/dist/lib/ai-model/inspect.js +1 -2
  50. package/dist/lib/ai-model/inspect.js.map +1 -1
  51. package/dist/lib/ai-model/llm-planning.js +5 -23
  52. package/dist/lib/ai-model/llm-planning.js.map +1 -1
  53. package/dist/lib/ai-model/prompt/llm-locator.js +2 -206
  54. package/dist/lib/ai-model/prompt/llm-locator.js.map +1 -1
  55. package/dist/lib/ai-model/service-caller/index.js +236 -384
  56. package/dist/lib/ai-model/service-caller/index.js.map +1 -1
  57. package/dist/lib/index.js +9 -5
  58. package/dist/lib/index.js.map +1 -1
  59. package/dist/lib/insight/index.js +17 -18
  60. package/dist/lib/insight/index.js.map +1 -1
  61. package/dist/lib/insight/utils.js +5 -5
  62. package/dist/lib/insight/utils.js.map +1 -1
  63. package/dist/lib/report.js.map +1 -1
  64. package/dist/lib/{ai-model/action-executor.js → task-runner.js} +71 -12
  65. package/dist/lib/task-runner.js.map +1 -0
  66. package/dist/lib/types.js +22 -1
  67. package/dist/lib/types.js.map +1 -1
  68. package/dist/lib/utils.js +2 -2
  69. package/dist/lib/yaml/player.js +18 -14
  70. package/dist/lib/yaml/player.js.map +1 -1
  71. package/dist/types/agent/agent.d.ts +16 -0
  72. package/dist/types/agent/execution-session.d.ts +27 -0
  73. package/dist/types/agent/task-builder.d.ts +24 -0
  74. package/dist/types/agent/tasks.d.ts +8 -11
  75. package/dist/types/agent/ui-utils.d.ts +2 -2
  76. package/dist/types/agent/utils.d.ts +5 -2
  77. package/dist/types/ai-model/common.d.ts +0 -1
  78. package/dist/types/ai-model/prompt/llm-locator.d.ts +0 -2
  79. package/dist/types/index.d.ts +4 -3
  80. package/dist/types/insight/index.d.ts +5 -10
  81. package/dist/types/insight/utils.d.ts +2 -2
  82. package/dist/types/{ai-model/action-executor.d.ts → task-runner.d.ts} +14 -3
  83. package/dist/types/types.d.ts +47 -4
  84. package/dist/types/yaml.d.ts +3 -1
  85. package/package.json +4 -7
  86. package/dist/es/ai-model/action-executor.mjs.map +0 -1
  87. package/dist/lib/ai-model/action-executor.js.map +0 -1
@@ -70,11 +70,11 @@ class ScriptPlayer {
70
70
  taskStatus.currentStep = currentStep;
71
71
  const flowItem = flow[flowItemIndex];
72
72
  debug(`playing step ${flowItemIndex}, flowItem=${JSON.stringify(flowItem)}`);
73
- if ('aiAction' in flowItem || 'ai' in flowItem) {
73
+ if ('aiAct' in flowItem || 'aiAction' in flowItem || 'ai' in flowItem) {
74
74
  const actionTask = flowItem;
75
- const prompt = actionTask.aiAction || actionTask.ai;
76
- assert(prompt, 'missing prompt for ai (aiAction)');
77
- await agent.aiAction(prompt, {
75
+ const prompt = actionTask.aiAct || actionTask.aiAction || actionTask.ai;
76
+ assert(prompt, 'missing prompt for ai (aiAct)');
77
+ await agent.aiAct(prompt, {
78
78
  cacheable: actionTask.cacheable
79
79
  });
80
80
  } else if ('aiAssert' in flowItem) {
@@ -162,21 +162,23 @@ class ScriptPlayer {
162
162
  const evaluateJavaScriptTask = flowItem;
163
163
  const result = await agent.evaluateJavaScript(evaluateJavaScriptTask.javascript);
164
164
  this.setResult(evaluateJavaScriptTask.name, result);
165
- } else if ('logScreenshot' in flowItem) {
166
- const logScreenshotTask = flowItem;
167
- await agent.logScreenshot(logScreenshotTask.logScreenshot, {
168
- content: logScreenshotTask.content || ''
165
+ } else if ('logScreenshot' in flowItem || 'recordToReport' in flowItem) {
166
+ const recordTask = flowItem;
167
+ const title = recordTask.recordToReport ?? recordTask.logScreenshot ?? 'untitled';
168
+ const content = recordTask.content || '';
169
+ await agent.recordToReport(title, {
170
+ content
169
171
  });
170
172
  } else if ('aiInput' in flowItem) {
171
- const { aiInput, ...inputTask } = flowItem;
173
+ const { aiInput, value: rawValue, ...inputTask } = flowItem;
172
174
  let locatePrompt;
173
175
  let value;
174
176
  if (inputTask.locate) {
175
- value = aiInput || inputTask.value;
177
+ value = aiInput || rawValue;
176
178
  locatePrompt = inputTask.locate;
177
179
  } else {
178
180
  locatePrompt = aiInput || '';
179
- value = inputTask.value;
181
+ value = rawValue;
180
182
  }
181
183
  await agent.callActionInActionSpace('Input', {
182
184
  ...inputTask,
@@ -234,9 +236,11 @@ class ScriptPlayer {
234
236
  return false;
235
237
  });
236
238
  assert(matchedAction, `unknown flowItem in yaml: ${JSON.stringify(flowItem)}`);
237
- assert(!(flowItem.prompt && locatePromptShortcut), `conflict locate prompt for item: ${JSON.stringify(flowItem)}`);
238
- if (locatePromptShortcut) flowItem.prompt = locatePromptShortcut;
239
- const { locateParam, restParams } = buildDetailedLocateParamAndRestParams(locatePromptShortcut || '', flowItem, [
239
+ const flowItemForProcessing = locatePromptShortcut ? {
240
+ ...flowItem,
241
+ prompt: locatePromptShortcut
242
+ } : flowItem;
243
+ const { locateParam, restParams } = buildDetailedLocateParamAndRestParams(locatePromptShortcut || '', flowItemForProcessing, [
240
244
  matchedAction.name,
241
245
  matchedAction.interfaceAlias || '_never_mind_'
242
246
  ]);
@@ -1 +1 @@
1
- {"version":3,"file":"yaml/player.mjs","sources":["webpack://@midscene/core/./src/yaml/player.ts"],"sourcesContent":["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 'aiAction' in (flowItem as MidsceneYamlFlowItemAIAction) ||\n 'ai' in (flowItem as MidsceneYamlFlowItemAIAction)\n ) {\n const actionTask = flowItem as MidsceneYamlFlowItemAIAction;\n const prompt = actionTask.aiAction || actionTask.ai;\n assert(prompt, 'missing prompt for ai (aiAction)');\n await agent.aiAction(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 ) {\n const logScreenshotTask = flowItem as MidsceneYamlFlowItemLogScreenshot;\n await agent.logScreenshot(logScreenshotTask.logScreenshot, {\n content: logScreenshotTask.content || '',\n });\n } else if ('aiInput' in (flowItem as MidsceneYamlFlowItemAIInput)) {\n // may be input empty string ''\n const { aiInput, ...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 value = (aiInput as string) || inputTask.value;\n locatePrompt = (inputTask as any).locate;\n } else {\n // New format - aiInput is the prompt, value is the value\n locatePrompt = aiInput || '';\n value = inputTask.value;\n }\n\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 assert(\n !((flowItem as any).prompt && locatePromptShortcut),\n `conflict locate prompt for item: ${JSON.stringify(flowItem)}`,\n );\n\n if (locatePromptShortcut) {\n (flowItem as any).prompt = locatePromptShortcut;\n }\n\n const { locateParam, restParams } =\n buildDetailedLocateParamAndRestParams(\n locatePromptShortcut || '',\n flowItem 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":["debug","getDebug","ScriptPlayer","key","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","logScreenshotTask","aiInput","inputTask","locatePrompt","String","buildDetailedLocateParam","aiKeyboardPress","keyboardPressTask","keyName","aiScroll","scrollTask","actionSpace","locatePromptShortcut","matchedAction","action","actionInterfaceAlias","Object","keyOfActionInActionSpace","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.mjs","sources":["webpack://@midscene/core/./src/yaml/player.ts"],"sourcesContent":["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 { aiInput, value: rawValue, ...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":["debug","getDebug","ScriptPlayer","key","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","Object","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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"}
@@ -192,8 +192,8 @@ class Agent {
192
192
  const tip = param ? `${(0, external_ui_utils_js_namespaceObject.typeStr)(task)} - ${param}` : (0, external_ui_utils_js_namespaceObject.typeStr)(task);
193
193
  if (this.onTaskStartTip) await this.onTaskStartTip(tip);
194
194
  }
195
- async afterTaskRunning(executor, doNotThrowError = false) {
196
- const executionDump = executor.dump();
195
+ async afterTaskRunning(runner, doNotThrowError = false) {
196
+ const executionDump = runner.dump();
197
197
  if (this.opts.aiActionContext) executionDump.aiActionContext = this.opts.aiActionContext;
198
198
  this.appendExecutionDump(executionDump);
199
199
  try {
@@ -202,8 +202,8 @@ class Agent {
202
202
  console.error('Error in onDumpUpdate', error);
203
203
  }
204
204
  this.writeOutActionDumps();
205
- if (executor.isInErrorState() && !doNotThrowError) {
206
- const errorTask = executor.latestErrorTask();
205
+ if (runner.isInErrorState() && !doNotThrowError) {
206
+ const errorTask = runner.latestErrorTask();
207
207
  throw new Error(`${null == errorTask ? void 0 : errorTask.errorMessage}\n${null == errorTask ? void 0 : errorTask.errorStack}`, {
208
208
  cause: null == errorTask ? void 0 : errorTask.error
209
209
  });
@@ -222,8 +222,8 @@ class Agent {
222
222
  ].filter(Boolean);
223
223
  const title = (0, external_ui_utils_js_namespaceObject.taskTitleStr)(type, (0, external_ui_utils_js_namespaceObject.locateParamStr)((null == opt ? void 0 : opt.locate) || {}));
224
224
  const modelConfig = this.modelConfigManager.getModelConfig('grounding');
225
- const { output, executor } = await this.taskExecutor.runPlans(title, plans, modelConfig);
226
- await this.afterTaskRunning(executor);
225
+ const { output, runner } = await this.taskExecutor.runPlans(title, plans, modelConfig);
226
+ await this.afterTaskRunning(runner);
227
227
  return output;
228
228
  }
229
229
  async aiTap(locatePrompt, opt) {
@@ -274,8 +274,10 @@ class Agent {
274
274
  (0, utils_namespaceObject.assert)('string' == typeof value || 'number' == typeof value, 'input value must be a string or number, use empty string if you want to clear the input');
275
275
  (0, utils_namespaceObject.assert)(locatePrompt, 'missing locate prompt for input');
276
276
  const detailedLocateParam = (0, index_js_namespaceObject.buildDetailedLocateParam)(locatePrompt, opt);
277
+ const stringValue = 'number' == typeof value ? String(value) : value;
277
278
  return this.callActionInActionSpace('Input', {
278
279
  ...opt || {},
280
+ value: stringValue,
279
281
  locate: detailedLocateParam
280
282
  });
281
283
  }
@@ -322,7 +324,7 @@ class Agent {
322
324
  locate: detailedLocateParam
323
325
  });
324
326
  }
325
- async aiAction(taskPrompt, opt) {
327
+ async aiAct(taskPrompt, opt) {
326
328
  var _this_taskCache, _this_taskCache1;
327
329
  const modelConfig = this.modelConfigManager.getModelConfig('planning');
328
330
  const cacheable = null == opt ? void 0 : opt.cacheable;
@@ -330,13 +332,13 @@ class Agent {
330
332
  const matchedCache = isVlmUiTars || false === cacheable ? void 0 : null == (_this_taskCache = this.taskCache) ? void 0 : _this_taskCache.matchPlanCache(taskPrompt);
331
333
  if (matchedCache && (null == (_this_taskCache1 = this.taskCache) ? void 0 : _this_taskCache1.isCacheResultUsed)) {
332
334
  var _matchedCache_cacheContent, _matchedCache_cacheContent1;
333
- const { executor } = await this.taskExecutor.loadYamlFlowAsPlanning(taskPrompt, null == (_matchedCache_cacheContent = matchedCache.cacheContent) ? void 0 : _matchedCache_cacheContent.yamlWorkflow);
334
- await this.afterTaskRunning(executor);
335
+ const { runner } = await this.taskExecutor.loadYamlFlowAsPlanning(taskPrompt, null == (_matchedCache_cacheContent = matchedCache.cacheContent) ? void 0 : _matchedCache_cacheContent.yamlWorkflow);
336
+ await this.afterTaskRunning(runner);
335
337
  debug('matched cache, will call .runYaml to run the action');
336
338
  const yaml = null == (_matchedCache_cacheContent1 = matchedCache.cacheContent) ? void 0 : _matchedCache_cacheContent1.yamlWorkflow;
337
339
  return this.runYaml(yaml);
338
340
  }
339
- const { output, executor } = await this.taskExecutor.action(taskPrompt, modelConfig, this.opts.aiActionContext, cacheable);
341
+ const { output, runner } = await this.taskExecutor.action(taskPrompt, modelConfig, this.opts.aiActionContext, cacheable);
340
342
  if (this.taskCache && (null == output ? void 0 : output.yamlFlow) && false !== cacheable) {
341
343
  const yamlContent = {
342
344
  tasks: [
@@ -353,34 +355,37 @@ class Agent {
353
355
  yamlWorkflow: yamlFlowStr
354
356
  }, matchedCache);
355
357
  }
356
- await this.afterTaskRunning(executor);
358
+ await this.afterTaskRunning(runner);
357
359
  return output;
358
360
  }
361
+ async aiAction(taskPrompt, opt) {
362
+ return this.aiAct(taskPrompt, opt);
363
+ }
359
364
  async aiQuery(demand, opt = defaultInsightExtractOption) {
360
365
  const modelConfig = this.modelConfigManager.getModelConfig('VQA');
361
- const { output, executor } = await this.taskExecutor.createTypeQueryExecution('Query', demand, modelConfig, opt);
362
- await this.afterTaskRunning(executor);
366
+ const { output, runner } = await this.taskExecutor.createTypeQueryExecution('Query', demand, modelConfig, opt);
367
+ await this.afterTaskRunning(runner);
363
368
  return output;
364
369
  }
365
370
  async aiBoolean(prompt, opt = defaultInsightExtractOption) {
366
371
  const modelConfig = this.modelConfigManager.getModelConfig('VQA');
367
372
  const { textPrompt, multimodalPrompt } = (0, external_utils_js_namespaceObject_1.parsePrompt)(prompt);
368
- const { output, executor } = await this.taskExecutor.createTypeQueryExecution('Boolean', textPrompt, modelConfig, opt, multimodalPrompt);
369
- await this.afterTaskRunning(executor);
373
+ const { output, runner } = await this.taskExecutor.createTypeQueryExecution('Boolean', textPrompt, modelConfig, opt, multimodalPrompt);
374
+ await this.afterTaskRunning(runner);
370
375
  return output;
371
376
  }
372
377
  async aiNumber(prompt, opt = defaultInsightExtractOption) {
373
378
  const modelConfig = this.modelConfigManager.getModelConfig('VQA');
374
379
  const { textPrompt, multimodalPrompt } = (0, external_utils_js_namespaceObject_1.parsePrompt)(prompt);
375
- const { output, executor } = await this.taskExecutor.createTypeQueryExecution('Number', textPrompt, modelConfig, opt, multimodalPrompt);
376
- await this.afterTaskRunning(executor);
380
+ const { output, runner } = await this.taskExecutor.createTypeQueryExecution('Number', textPrompt, modelConfig, opt, multimodalPrompt);
381
+ await this.afterTaskRunning(runner);
377
382
  return output;
378
383
  }
379
384
  async aiString(prompt, opt = defaultInsightExtractOption) {
380
385
  const modelConfig = this.modelConfigManager.getModelConfig('VQA');
381
386
  const { textPrompt, multimodalPrompt } = (0, external_utils_js_namespaceObject_1.parsePrompt)(prompt);
382
- const { output, executor } = await this.taskExecutor.createTypeQueryExecution('String', textPrompt, modelConfig, opt, multimodalPrompt);
383
- await this.afterTaskRunning(executor);
387
+ const { output, runner } = await this.taskExecutor.createTypeQueryExecution('String', textPrompt, modelConfig, opt, multimodalPrompt);
388
+ await this.afterTaskRunning(runner);
384
389
  return output;
385
390
  }
386
391
  async aiAsk(prompt, opt = defaultInsightExtractOption) {
@@ -438,8 +443,8 @@ class Agent {
438
443
  locatePlan
439
444
  ];
440
445
  const modelConfig = this.modelConfigManager.getModelConfig('grounding');
441
- const { executor, output } = await this.taskExecutor.runPlans((0, external_ui_utils_js_namespaceObject.taskTitleStr)('Locate', (0, external_ui_utils_js_namespaceObject.locateParamStr)(locateParam)), plans, modelConfig);
442
- await this.afterTaskRunning(executor);
446
+ const { runner, output } = await this.taskExecutor.runPlans((0, external_ui_utils_js_namespaceObject.taskTitleStr)('Locate', (0, external_ui_utils_js_namespaceObject.locateParamStr)(locateParam)), plans, modelConfig);
447
+ await this.afterTaskRunning(runner);
443
448
  const { element } = output;
444
449
  const dprValue = await this.interface.size().dpr;
445
450
  const dprEntry = dprValue ? {
@@ -452,7 +457,7 @@ class Agent {
452
457
  };
453
458
  }
454
459
  async aiAssert(assertion, msg, opt) {
455
- var _executor_latestErrorTask;
460
+ var _runner_latestErrorTask;
456
461
  const modelConfig = this.modelConfigManager.getModelConfig('VQA');
457
462
  const insightOpt = {
458
463
  domIncluded: (null == opt ? void 0 : opt.domIncluded) ?? defaultInsightExtractOption.domIncluded,
@@ -460,9 +465,9 @@ class Agent {
460
465
  doNotThrowError: null == opt ? void 0 : opt.doNotThrowError
461
466
  };
462
467
  const { textPrompt, multimodalPrompt } = (0, external_utils_js_namespaceObject_1.parsePrompt)(assertion);
463
- const { output, executor, thought } = await this.taskExecutor.createTypeQueryExecution('Assert', textPrompt, modelConfig, insightOpt, multimodalPrompt);
464
- await this.afterTaskRunning(executor, true);
465
- const message = output ? void 0 : `Assertion failed: ${msg || ('string' == typeof assertion ? assertion : assertion.prompt)}\nReason: ${thought || (null == (_executor_latestErrorTask = executor.latestErrorTask()) ? void 0 : _executor_latestErrorTask.error) || '(no_reason)'}`;
468
+ const { output, runner, thought } = await this.taskExecutor.createTypeQueryExecution('Assert', textPrompt, modelConfig, insightOpt, multimodalPrompt);
469
+ await this.afterTaskRunning(runner, true);
470
+ const message = output ? void 0 : `Assertion failed: ${msg || ('string' == typeof assertion ? assertion : assertion.prompt)}\nReason: ${thought || (null == (_runner_latestErrorTask = runner.latestErrorTask()) ? void 0 : _runner_latestErrorTask.error) || '(no_reason)'}`;
466
471
  if (null == opt ? void 0 : opt.keepRawResponse) return {
467
472
  pass: output,
468
473
  thought,
@@ -472,18 +477,18 @@ class Agent {
472
477
  }
473
478
  async aiWaitFor(assertion, opt) {
474
479
  const modelConfig = this.modelConfigManager.getModelConfig('VQA');
475
- const { executor } = await this.taskExecutor.waitFor(assertion, {
480
+ const { runner } = await this.taskExecutor.waitFor(assertion, {
476
481
  timeoutMs: (null == opt ? void 0 : opt.timeoutMs) || 15000,
477
482
  checkIntervalMs: (null == opt ? void 0 : opt.checkIntervalMs) || 3000
478
483
  }, modelConfig);
479
- await this.afterTaskRunning(executor, true);
480
- if (executor.isInErrorState()) {
481
- const errorTask = executor.latestErrorTask();
484
+ await this.afterTaskRunning(runner, true);
485
+ if (runner.isInErrorState()) {
486
+ const errorTask = runner.latestErrorTask();
482
487
  throw new Error(`${null == errorTask ? void 0 : errorTask.error}\n${null == errorTask ? void 0 : errorTask.errorStack}`);
483
488
  }
484
489
  }
485
490
  async ai(taskPrompt, type = 'action') {
486
- if ('action' === type) return this.aiAction(taskPrompt);
491
+ if ('action' === type) return this.aiAct(taskPrompt);
487
492
  if ('query' === type) return this.aiQuery(taskPrompt);
488
493
  if ('assert' === type) return this.aiAssert(taskPrompt);
489
494
  if ('tap' === type) return this.aiTap(taskPrompt);
@@ -520,7 +525,7 @@ class Agent {
520
525
  this.resetDump();
521
526
  this.destroyed = true;
522
527
  }
523
- async logScreenshot(title, opt) {
528
+ async recordToReport(title, opt) {
524
529
  const base64 = await this.interface.screenshotBase64();
525
530
  const now = Date.now();
526
531
  const recorder = [
@@ -563,6 +568,9 @@ class Agent {
563
568
  }
564
569
  this.writeOutActionDumps();
565
570
  }
571
+ async logScreenshot(title, opt) {
572
+ await this.recordToReport(title, opt);
573
+ }
566
574
  _unstableLogContent() {
567
575
  const { groupName, groupDescription, executions } = this.dump;
568
576
  const newExecutions = Array.isArray(executions) ? executions.map((execution)=>{
@@ -651,9 +659,9 @@ class Agent {
651
659
  groupDescription: ''
652
660
  }, opts || {});
653
661
  if ((null == opts ? void 0 : opts.modelConfig) && 'function' != typeof (null == opts ? void 0 : opts.modelConfig)) throw new Error(`opts.modelConfig must be one of function or undefined, but got ${typeof (null == opts ? void 0 : opts.modelConfig)}`);
654
- this.modelConfigManager = (null == opts ? void 0 : opts.modelConfig) ? new env_namespaceObject.ModelConfigManager(opts.modelConfig) : env_namespaceObject.globalModelConfigManager;
662
+ this.modelConfigManager = (null == opts ? void 0 : opts.modelConfig) ? new env_namespaceObject.ModelConfigManager(opts.modelConfig, null == opts ? void 0 : opts.createOpenAIClient) : env_namespaceObject.globalModelConfigManager;
655
663
  this.onTaskStartTip = this.opts.onTaskStartTip;
656
- this.insight = new external_index_js_namespaceObject.Insight(async (action)=>this.getUIContext(action));
664
+ this.insight = new external_index_js_namespaceObject.Insight(async ()=>this.getUIContext());
657
665
  const cacheConfigObj = this.processCacheConfig(opts || {});
658
666
  if (cacheConfigObj) this.taskCache = new external_task_cache_js_namespaceObject.TaskCache(cacheConfigObj.id, cacheConfigObj.enabled, void 0, {
659
667
  readOnly: cacheConfigObj.readOnly,