@midscene/web 0.26.6 → 0.26.7-beta-20250815153024.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 (36) hide show
  1. package/dist/es/bridge-mode/io-client.mjs +1 -1
  2. package/dist/es/bridge-mode/io-server.mjs +2 -2
  3. package/dist/es/bridge-mode/io-server.mjs.map +1 -1
  4. package/dist/es/bridge-mode/page-browser-side.mjs +1 -1
  5. package/dist/es/bridge-mode/page-browser-side.mjs.map +1 -1
  6. package/dist/es/chrome-extension/page.mjs +1 -1
  7. package/dist/es/common/agent.mjs +95 -59
  8. package/dist/es/common/agent.mjs.map +1 -1
  9. package/dist/es/common/tasks.mjs +8 -8
  10. package/dist/es/common/tasks.mjs.map +1 -1
  11. package/dist/es/common/utils.mjs +6 -1
  12. package/dist/es/common/utils.mjs.map +1 -1
  13. package/dist/es/yaml/player.mjs +75 -13
  14. package/dist/es/yaml/player.mjs.map +1 -1
  15. package/dist/lib/bridge-mode/io-client.js +1 -1
  16. package/dist/lib/bridge-mode/io-server.js +2 -2
  17. package/dist/lib/bridge-mode/io-server.js.map +1 -1
  18. package/dist/lib/bridge-mode/page-browser-side.js +1 -1
  19. package/dist/lib/bridge-mode/page-browser-side.js.map +1 -1
  20. package/dist/lib/chrome-extension/page.js +1 -1
  21. package/dist/lib/common/agent.js +94 -58
  22. package/dist/lib/common/agent.js.map +1 -1
  23. package/dist/lib/common/tasks.js +8 -8
  24. package/dist/lib/common/tasks.js.map +1 -1
  25. package/dist/lib/common/utils.js +6 -1
  26. package/dist/lib/common/utils.js.map +1 -1
  27. package/dist/lib/yaml/player.js +75 -13
  28. package/dist/lib/yaml/player.js.map +1 -1
  29. package/dist/types/common/agent.d.ts +23 -4
  30. package/dist/types/yaml/player.d.ts +1 -0
  31. package/package.json +3 -3
  32. package/dist/es/common/plan-builder.mjs +0 -89
  33. package/dist/es/common/plan-builder.mjs.map +0 -1
  34. package/dist/lib/common/plan-builder.js +0 -123
  35. package/dist/lib/common/plan-builder.js.map +0 -1
  36. package/dist/types/common/plan-builder.d.ts +0 -2
@@ -238,7 +238,7 @@ function trimContextByViewport(execution) {
238
238
  }) : execution.tasks
239
239
  };
240
240
  }
241
- const getMidsceneVersion = ()=>"0.26.6";
241
+ const getMidsceneVersion = ()=>"0.26.7-beta-20250815153024.0";
242
242
  const parsePrompt = (prompt)=>{
243
243
  if ('string' == typeof prompt) return {
244
244
  textPrompt: prompt,
@@ -257,6 +257,7 @@ const commonWebActionsForWebPage = (page)=>[
257
257
  name: 'Tap',
258
258
  description: 'Tap the element',
259
259
  location: 'required',
260
+ interfaceAlias: 'aiTap',
260
261
  call: async (context)=>{
261
262
  const { element } = context;
262
263
  (0, shared_utils_namespaceObject.assert)(element, 'Element not found, cannot tap');
@@ -281,6 +282,7 @@ const commonWebActionsForWebPage = (page)=>[
281
282
  name: 'Hover',
282
283
  description: 'Move the mouse to the element',
283
284
  location: 'required',
285
+ interfaceAlias: 'aiHover',
284
286
  call: async (context)=>{
285
287
  const { element } = context;
286
288
  (0, shared_utils_namespaceObject.assert)(element, 'Element not found, cannot hover');
@@ -294,6 +296,7 @@ const commonWebActionsForWebPage = (page)=>[
294
296
  paramDescription: '`value` is the final that should be filled in the input box. No matter what modifications are required, just provide the final value to replace the existing input value. Giving a blank string means clear the input field.',
295
297
  location: 'required',
296
298
  whatToLocate: 'The input field to be filled',
299
+ interfaceAlias: 'aiInput',
297
300
  call: async (context, param)=>{
298
301
  const { element } = context;
299
302
  if (element) {
@@ -309,6 +312,7 @@ const commonWebActionsForWebPage = (page)=>[
309
312
  paramSchema: '{ value: string }',
310
313
  paramDescription: 'The key to be pressed',
311
314
  location: false,
315
+ interfaceAlias: 'aiKeyboardPress',
312
316
  call: async (context, param)=>{
313
317
  const keys = (0, external_ui_utils_js_namespaceObject.getKeyCommands)(param.value);
314
318
  await page.keyboard.press(keys);
@@ -321,6 +325,7 @@ const commonWebActionsForWebPage = (page)=>[
321
325
  paramDescription: 'The direction to scroll, the scroll type, and the distance to scroll. The distance is the number of pixels to scroll. If not specified, use `down` direction, `once` scroll type, and `null` distance.',
322
326
  location: 'optional',
323
327
  whatToLocate: 'The element to be scrolled',
328
+ interfaceAlias: 'aiScroll',
324
329
  call: async (context, param)=>{
325
330
  const { element } = context;
326
331
  const startingPoint = element ? {
@@ -1 +1 @@
1
- {"version":3,"file":"common/utils.js","sources":["webpack://@midscene/web/webpack/runtime/compat_get_default_export","webpack://@midscene/web/webpack/runtime/define_property_getters","webpack://@midscene/web/webpack/runtime/has_own_property","webpack://@midscene/web/webpack/runtime/make_namespace_object","webpack://@midscene/web/./src/common/utils.ts"],"sourcesContent":["// getDefaultExport function for compatibility with non-ESM modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};\n","__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import type { StaticPage } from '@/playground';\nimport type {\n BaseElement,\n DeviceAction,\n ElementTreeNode,\n ExecutionDump,\n ExecutionTask,\n ExecutorContext,\n PlanningLocateParam,\n PlaywrightParserOpt,\n ScrollParam,\n TMultimodalPrompt,\n TUserPrompt,\n UIContext,\n} from '@midscene/core';\nimport { elementByPositionWithElementInfo } from '@midscene/core/ai-model';\nimport { sleep, uploadTestInfoToServer } from '@midscene/core/utils';\nimport { MIDSCENE_REPORT_TAG_NAME, getAIConfig } from '@midscene/shared/env';\nimport type { ElementInfo } from '@midscene/shared/extractor';\nimport {\n generateElementByPosition,\n getNodeFromCacheList,\n traverseTree,\n} from '@midscene/shared/extractor';\nimport { resizeImgBase64 } from '@midscene/shared/img';\nimport { type DebugFunction, getDebug } from '@midscene/shared/logger';\nimport { assert, logMsg, uuid } from '@midscene/shared/utils';\nimport dayjs from 'dayjs';\nimport type { Page as PlaywrightPage } from 'playwright';\nimport type { Page as PuppeteerPage } from 'puppeteer';\nimport type { AbstractPage } from '../page';\nimport { WebElementInfo, type WebUIContext } from '../web-element';\nimport type { WebPage } from './page';\nimport { debug as cacheDebug } from './task-cache';\nimport type { PageTaskExecutor } from './tasks';\nimport { getKeyCommands } from './ui-utils';\n\nconst debug = getDebug('tool:profile');\n\nexport async function parseContextFromWebPage(\n page: WebPage,\n _opt?: PlaywrightParserOpt,\n): Promise<WebUIContext> {\n assert(page, 'page is required');\n if ((page as StaticPage)._forceUsePageContext) {\n return await (page as any)._forceUsePageContext();\n }\n\n debug('Getting page URL');\n const url = await page.url();\n debug('URL end');\n\n debug('Uploading test info to server');\n uploadTestInfoToServer({ testUrl: url });\n debug('UploadTestInfoToServer end');\n\n let screenshotBase64: string;\n let tree: ElementTreeNode<ElementInfo>;\n\n debug('Starting parallel operations: screenshot and element tree');\n await Promise.all([\n page.screenshotBase64().then((base64) => {\n screenshotBase64 = base64;\n debug('ScreenshotBase64 end');\n }),\n page.getElementsNodeTree().then(async (treeRoot) => {\n tree = treeRoot;\n debug('GetElementsNodeTree end');\n }),\n ]);\n debug('ParseContextFromWebPage end');\n debug('Traversing element tree');\n const webTree = traverseTree(tree!, (elementInfo) => {\n const { rect, id, content, attributes, indexId, isVisible } = elementInfo;\n return new WebElementInfo({\n rect,\n id,\n content,\n attributes,\n indexId,\n isVisible,\n });\n });\n debug('TraverseTree end');\n assert(screenshotBase64!, 'screenshotBase64 is required');\n\n const size = await page.size();\n\n debug(`size: ${size.width}x${size.height} dpr: ${size.dpr}`);\n\n if (size.dpr && size.dpr > 1) {\n debug('Resizing screenshot for high DPR display');\n screenshotBase64 = await resizeImgBase64(screenshotBase64, {\n width: size.width,\n height: size.height,\n });\n debug('ResizeImgBase64 end');\n }\n\n return {\n tree: webTree,\n size,\n screenshotBase64: screenshotBase64!,\n url,\n };\n}\n\nexport function getReportFileName(tag = 'web') {\n const reportTagName = getAIConfig(MIDSCENE_REPORT_TAG_NAME);\n const dateTimeInFileName = dayjs().format('YYYY-MM-DD_HH-mm-ss');\n // ensure uniqueness at the same time\n const uniqueId = uuid().substring(0, 8);\n return `${reportTagName || tag}-${dateTimeInFileName}-${uniqueId}`;\n}\n\nexport function printReportMsg(filepath: string) {\n logMsg(`Midscene - report file updated: ${filepath}`);\n}\n\n/**\n * Get the current execution file name\n * @returns The name of the current execution file\n */\nexport function getCurrentExecutionFile(trace?: string): string | false {\n const error = new Error();\n const stackTrace = trace || error.stack;\n const pkgDir = process.cwd() || '';\n if (stackTrace) {\n const stackLines = stackTrace.split('\\n');\n for (const line of stackLines) {\n if (\n line.includes('.spec.') ||\n line.includes('.test.') ||\n line.includes('.ts') ||\n line.includes('.js')\n ) {\n const match = line.match(/(?:at\\s+)?(.*?\\.(?:spec|test)\\.[jt]s)/);\n if (match?.[1]) {\n const targetFileName = match[1]\n .replace(pkgDir, '')\n .trim()\n .replace('at ', '');\n return targetFileName;\n }\n }\n }\n }\n return false;\n}\n\nconst testFileIndex = new Map<string, number>();\n\nexport function generateCacheId(fileName?: string): string {\n let taskFile = fileName || getCurrentExecutionFile();\n if (!taskFile) {\n taskFile = uuid();\n console.warn(\n 'Midscene - using random UUID for cache id. Cache may be invalid.',\n );\n }\n\n if (testFileIndex.has(taskFile)) {\n const currentIndex = testFileIndex.get(taskFile);\n if (currentIndex !== undefined) {\n testFileIndex.set(taskFile, currentIndex + 1);\n }\n } else {\n testFileIndex.set(taskFile, 1);\n }\n return `${taskFile}-${testFileIndex.get(taskFile)}`;\n}\n\nexport const ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED =\n 'NOT_IMPLEMENTED_AS_DESIGNED';\n\nexport function replaceIllegalPathCharsAndSpace(str: string) {\n // Only replace characters that are illegal in filenames, but preserve path separators\n return str.replace(/[:*?\"<>| ]/g, '-');\n}\n\nexport function forceClosePopup(\n page: PuppeteerPage | PlaywrightPage,\n debug: DebugFunction,\n) {\n page.on('popup', async (popup) => {\n if (!popup) {\n console.warn('got a popup event, but the popup is not ready yet, skip');\n return;\n }\n const url = await (popup as PuppeteerPage).url();\n console.log(`Popup opened: ${url}`);\n if (!(popup as PuppeteerPage).isClosed()) {\n try {\n await (popup as PuppeteerPage).close(); // Close the newly opened TAB\n } catch (error) {\n debug(`failed to close popup ${url}, error: ${error}`);\n }\n } else {\n debug(`popup is already closed, skip close ${url}`);\n }\n\n if (!page.isClosed()) {\n try {\n await page.goto(url);\n } catch (error) {\n debug(`failed to goto ${url}, error: ${error}`);\n }\n } else {\n debug(`page is already closed, skip goto ${url}`);\n }\n });\n}\n\nexport function matchElementFromPlan(\n planLocateParam: PlanningLocateParam,\n tree: ElementTreeNode<BaseElement>,\n) {\n if (!planLocateParam) {\n return undefined;\n }\n if (planLocateParam.id) {\n return getNodeFromCacheList(planLocateParam.id);\n }\n\n if (planLocateParam.bbox) {\n const centerPosition = {\n x: Math.floor((planLocateParam.bbox[0] + planLocateParam.bbox[2]) / 2),\n y: Math.floor((planLocateParam.bbox[1] + planLocateParam.bbox[3]) / 2),\n };\n let element = elementByPositionWithElementInfo(tree, centerPosition);\n\n if (!element) {\n element = generateElementByPosition(centerPosition) as BaseElement;\n }\n\n return element;\n }\n\n return undefined;\n}\n\nexport async function matchElementFromCache(\n taskExecutor: PageTaskExecutor,\n xpaths: string[] | undefined,\n cachePrompt: TUserPrompt,\n cacheable: boolean | undefined,\n) {\n try {\n if (\n xpaths?.length &&\n taskExecutor.taskCache?.isCacheResultUsed &&\n cacheable !== false\n ) {\n // hit cache, use new id\n for (let i = 0; i < xpaths.length; i++) {\n const element = await taskExecutor.page.getElementInfoByXpath(\n xpaths[i],\n );\n\n if (element?.id) {\n cacheDebug('cache hit, prompt: %s', cachePrompt);\n cacheDebug(\n 'found a new element with same xpath, xpath: %s, id: %s',\n xpaths[i],\n element?.id,\n );\n return element;\n }\n }\n }\n } catch (error) {\n cacheDebug('get element info by xpath error: ', error);\n }\n}\n\nexport function trimContextByViewport(execution: ExecutionDump) {\n function filterVisibleTree(\n node: ElementTreeNode<BaseElement>,\n ): ElementTreeNode<BaseElement> | null {\n if (!node) return null;\n\n // recursively process all children\n const filteredChildren = Array.isArray(node.children)\n ? (node.children\n .map(filterVisibleTree)\n .filter((child) => child !== null) as ElementTreeNode<BaseElement>[])\n : [];\n\n // if the current node is visible, keep it and the filtered children\n if (node.node && node.node.isVisible === true) {\n return {\n ...node,\n children: filteredChildren,\n };\n }\n\n // if the current node is invisible, but has visible children, create an empty node to include these children\n if (filteredChildren.length > 0) {\n return {\n node: null,\n children: filteredChildren,\n };\n }\n\n // if the current node is invisible and has no visible children, return null\n return null;\n }\n\n return {\n ...execution,\n tasks: Array.isArray(execution.tasks)\n ? execution.tasks.map((task: ExecutionTask) => {\n const newTask = { ...task };\n if (task.pageContext?.tree) {\n newTask.pageContext = {\n ...task.pageContext,\n tree: filterVisibleTree(task.pageContext.tree) || {\n node: null,\n children: [],\n },\n };\n }\n return newTask;\n })\n : execution.tasks,\n };\n}\n\ndeclare const __VERSION__: string | undefined;\n\nexport const getMidsceneVersion = (): string => {\n if (typeof __VERSION__ !== 'undefined') {\n return __VERSION__;\n } else if (\n process.env.__VERSION__ &&\n process.env.__VERSION__ !== 'undefined'\n ) {\n return process.env.__VERSION__;\n }\n throw new Error('__VERSION__ inject failed during build');\n};\n\nexport const parsePrompt = (\n prompt: TUserPrompt,\n): {\n textPrompt: string;\n multimodalPrompt?: TMultimodalPrompt;\n} => {\n if (typeof prompt === 'string') {\n return {\n textPrompt: prompt,\n multimodalPrompt: undefined,\n };\n }\n return {\n textPrompt: prompt.prompt,\n multimodalPrompt: prompt.images\n ? {\n images: prompt.images,\n convertHttpImage2Base64: !!prompt.convertHttpImage2Base64,\n }\n : undefined,\n };\n};\n\nexport const commonWebActionsForWebPage = <T extends AbstractPage>(\n page: T,\n): DeviceAction[] => [\n {\n name: 'Tap',\n description: 'Tap the element',\n location: 'required',\n call: async (context) => {\n const { element } = context;\n assert(element, 'Element not found, cannot tap');\n await page.mouse.click(element.center[0], element.center[1], {\n button: 'left',\n });\n },\n },\n {\n name: 'RightClick',\n description: 'Right click the element',\n location: 'required',\n call: async (context) => {\n const { element } = context;\n assert(element, 'Element not found, cannot right click');\n await page.mouse.click(element.center[0], element.center[1], {\n button: 'right',\n });\n },\n },\n {\n name: 'Hover',\n description: 'Move the mouse to the element',\n location: 'required',\n call: async (context) => {\n const { element } = context;\n assert(element, 'Element not found, cannot hover');\n await page.mouse.move(element.center[0], element.center[1]);\n },\n },\n {\n name: 'Input',\n description: 'Replace the input field with a new value',\n paramSchema: '{ value: string }',\n paramDescription:\n '`value` is the final that should be filled in the input box. No matter what modifications are required, just provide the final value to replace the existing input value. Giving a blank string means clear the input field.',\n location: 'required',\n whatToLocate: 'The input field to be filled',\n call: async (context, param) => {\n const { element } = context;\n if (element) {\n await page.clearInput(element as unknown as ElementInfo);\n\n if (!param || !param.value) {\n return;\n }\n }\n\n // Note: there is another implementation in AndroidDevicePage, which is more complex\n await page.keyboard.type(param.value);\n },\n } as DeviceAction<{ value: string }>,\n {\n name: 'KeyboardPress',\n description: 'Press a key',\n paramSchema: '{ value: string }',\n paramDescription: 'The key to be pressed',\n location: false,\n call: async (context, param) => {\n const keys = getKeyCommands(param.value);\n await page.keyboard.press(keys as any); // TODO: fix this type error\n },\n } as DeviceAction<{ value: string }>,\n {\n name: 'Scroll',\n description: 'Scroll the page or an element',\n paramSchema:\n '{ direction: \"down\"(default) | \"up\" | \"right\" | \"left\", scrollType: \"once\" (default) | \"untilBottom\" | \"untilTop\" | \"untilRight\" | \"untilLeft\", distance: number | null }',\n paramDescription:\n 'The direction to scroll, the scroll type, and the distance to scroll. The distance is the number of pixels to scroll. If not specified, use `down` direction, `once` scroll type, and `null` distance.',\n location: 'optional',\n whatToLocate: 'The element to be scrolled',\n call: async (context, param) => {\n const { element } = context;\n const startingPoint = element\n ? {\n left: element.center[0],\n top: element.center[1],\n }\n : undefined;\n const scrollToEventName = param?.scrollType;\n if (scrollToEventName === 'untilTop') {\n await page.scrollUntilTop(startingPoint);\n } else if (scrollToEventName === 'untilBottom') {\n await page.scrollUntilBottom(startingPoint);\n } else if (scrollToEventName === 'untilRight') {\n await page.scrollUntilRight(startingPoint);\n } else if (scrollToEventName === 'untilLeft') {\n await page.scrollUntilLeft(startingPoint);\n } else if (scrollToEventName === 'once' || !scrollToEventName) {\n if (param?.direction === 'down' || !param || !param.direction) {\n await page.scrollDown(param?.distance || undefined, startingPoint);\n } else if (param.direction === 'up') {\n await page.scrollUp(param.distance || undefined, startingPoint);\n } else if (param.direction === 'left') {\n await page.scrollLeft(param.distance || undefined, startingPoint);\n } else if (param.direction === 'right') {\n await page.scrollRight(param.distance || undefined, startingPoint);\n } else {\n throw new Error(`Unknown scroll direction: ${param.direction}`);\n }\n // until mouse event is done\n await sleep(500);\n } else {\n throw new Error(\n `Unknown scroll event type: ${scrollToEventName}, param: ${JSON.stringify(\n param,\n )}`,\n );\n }\n },\n } as DeviceAction<ScrollParam>,\n];\n"],"names":["__webpack_require__","module","getter","definition","key","Object","obj","prop","Symbol","debug","getDebug","parseContextFromWebPage","page","_opt","assert","url","uploadTestInfoToServer","screenshotBase64","tree","Promise","base64","treeRoot","webTree","traverseTree","elementInfo","rect","id","content","attributes","indexId","isVisible","WebElementInfo","size","resizeImgBase64","getReportFileName","tag","reportTagName","getAIConfig","MIDSCENE_REPORT_TAG_NAME","dateTimeInFileName","dayjs","uniqueId","uuid","printReportMsg","filepath","logMsg","getCurrentExecutionFile","trace","error","Error","stackTrace","pkgDir","process","stackLines","line","match","targetFileName","testFileIndex","Map","generateCacheId","fileName","taskFile","console","currentIndex","undefined","ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED","replaceIllegalPathCharsAndSpace","str","forceClosePopup","popup","matchElementFromPlan","planLocateParam","getNodeFromCacheList","centerPosition","Math","element","elementByPositionWithElementInfo","generateElementByPosition","matchElementFromCache","taskExecutor","xpaths","cachePrompt","cacheable","_taskExecutor_taskCache","i","cacheDebug","trimContextByViewport","execution","filterVisibleTree","node","filteredChildren","Array","child","task","_task_pageContext","newTask","getMidsceneVersion","__VERSION__","parsePrompt","prompt","commonWebActionsForWebPage","context","param","keys","getKeyCommands","startingPoint","scrollToEventName","JSON","sleep"],"mappings":"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"}
1
+ {"version":3,"file":"common/utils.js","sources":["webpack://@midscene/web/webpack/runtime/compat_get_default_export","webpack://@midscene/web/webpack/runtime/define_property_getters","webpack://@midscene/web/webpack/runtime/has_own_property","webpack://@midscene/web/webpack/runtime/make_namespace_object","webpack://@midscene/web/./src/common/utils.ts"],"sourcesContent":["// getDefaultExport function for compatibility with non-ESM modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};\n","__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import type { StaticPage } from '@/playground';\nimport type {\n BaseElement,\n DeviceAction,\n ElementTreeNode,\n ExecutionDump,\n ExecutionTask,\n ExecutorContext,\n PlanningLocateParam,\n PlaywrightParserOpt,\n ScrollParam,\n TMultimodalPrompt,\n TUserPrompt,\n UIContext,\n} from '@midscene/core';\nimport { elementByPositionWithElementInfo } from '@midscene/core/ai-model';\nimport { sleep, uploadTestInfoToServer } from '@midscene/core/utils';\nimport { MIDSCENE_REPORT_TAG_NAME, getAIConfig } from '@midscene/shared/env';\nimport type { ElementInfo } from '@midscene/shared/extractor';\nimport {\n generateElementByPosition,\n getNodeFromCacheList,\n traverseTree,\n} from '@midscene/shared/extractor';\nimport { resizeImgBase64 } from '@midscene/shared/img';\nimport { type DebugFunction, getDebug } from '@midscene/shared/logger';\nimport { assert, logMsg, uuid } from '@midscene/shared/utils';\nimport dayjs from 'dayjs';\nimport type { Page as PlaywrightPage } from 'playwright';\nimport type { Page as PuppeteerPage } from 'puppeteer';\nimport type { AbstractPage } from '../page';\nimport { WebElementInfo, type WebUIContext } from '../web-element';\nimport type { WebPage } from './page';\nimport { debug as cacheDebug } from './task-cache';\nimport type { PageTaskExecutor } from './tasks';\nimport { getKeyCommands } from './ui-utils';\n\nconst debug = getDebug('tool:profile');\n\nexport async function parseContextFromWebPage(\n page: WebPage,\n _opt?: PlaywrightParserOpt,\n): Promise<WebUIContext> {\n assert(page, 'page is required');\n if ((page as StaticPage)._forceUsePageContext) {\n return await (page as any)._forceUsePageContext();\n }\n\n debug('Getting page URL');\n const url = await page.url();\n debug('URL end');\n\n debug('Uploading test info to server');\n uploadTestInfoToServer({ testUrl: url });\n debug('UploadTestInfoToServer end');\n\n let screenshotBase64: string;\n let tree: ElementTreeNode<ElementInfo>;\n\n debug('Starting parallel operations: screenshot and element tree');\n await Promise.all([\n page.screenshotBase64().then((base64) => {\n screenshotBase64 = base64;\n debug('ScreenshotBase64 end');\n }),\n page.getElementsNodeTree().then(async (treeRoot) => {\n tree = treeRoot;\n debug('GetElementsNodeTree end');\n }),\n ]);\n debug('ParseContextFromWebPage end');\n debug('Traversing element tree');\n const webTree = traverseTree(tree!, (elementInfo) => {\n const { rect, id, content, attributes, indexId, isVisible } = elementInfo;\n return new WebElementInfo({\n rect,\n id,\n content,\n attributes,\n indexId,\n isVisible,\n });\n });\n debug('TraverseTree end');\n assert(screenshotBase64!, 'screenshotBase64 is required');\n\n const size = await page.size();\n\n debug(`size: ${size.width}x${size.height} dpr: ${size.dpr}`);\n\n if (size.dpr && size.dpr > 1) {\n debug('Resizing screenshot for high DPR display');\n screenshotBase64 = await resizeImgBase64(screenshotBase64, {\n width: size.width,\n height: size.height,\n });\n debug('ResizeImgBase64 end');\n }\n\n return {\n tree: webTree,\n size,\n screenshotBase64: screenshotBase64!,\n url,\n };\n}\n\nexport function getReportFileName(tag = 'web') {\n const reportTagName = getAIConfig(MIDSCENE_REPORT_TAG_NAME);\n const dateTimeInFileName = dayjs().format('YYYY-MM-DD_HH-mm-ss');\n // ensure uniqueness at the same time\n const uniqueId = uuid().substring(0, 8);\n return `${reportTagName || tag}-${dateTimeInFileName}-${uniqueId}`;\n}\n\nexport function printReportMsg(filepath: string) {\n logMsg(`Midscene - report file updated: ${filepath}`);\n}\n\n/**\n * Get the current execution file name\n * @returns The name of the current execution file\n */\nexport function getCurrentExecutionFile(trace?: string): string | false {\n const error = new Error();\n const stackTrace = trace || error.stack;\n const pkgDir = process.cwd() || '';\n if (stackTrace) {\n const stackLines = stackTrace.split('\\n');\n for (const line of stackLines) {\n if (\n line.includes('.spec.') ||\n line.includes('.test.') ||\n line.includes('.ts') ||\n line.includes('.js')\n ) {\n const match = line.match(/(?:at\\s+)?(.*?\\.(?:spec|test)\\.[jt]s)/);\n if (match?.[1]) {\n const targetFileName = match[1]\n .replace(pkgDir, '')\n .trim()\n .replace('at ', '');\n return targetFileName;\n }\n }\n }\n }\n return false;\n}\n\nconst testFileIndex = new Map<string, number>();\n\nexport function generateCacheId(fileName?: string): string {\n let taskFile = fileName || getCurrentExecutionFile();\n if (!taskFile) {\n taskFile = uuid();\n console.warn(\n 'Midscene - using random UUID for cache id. Cache may be invalid.',\n );\n }\n\n if (testFileIndex.has(taskFile)) {\n const currentIndex = testFileIndex.get(taskFile);\n if (currentIndex !== undefined) {\n testFileIndex.set(taskFile, currentIndex + 1);\n }\n } else {\n testFileIndex.set(taskFile, 1);\n }\n return `${taskFile}-${testFileIndex.get(taskFile)}`;\n}\n\nexport const ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED =\n 'NOT_IMPLEMENTED_AS_DESIGNED';\n\nexport function replaceIllegalPathCharsAndSpace(str: string) {\n // Only replace characters that are illegal in filenames, but preserve path separators\n return str.replace(/[:*?\"<>| ]/g, '-');\n}\n\nexport function forceClosePopup(\n page: PuppeteerPage | PlaywrightPage,\n debug: DebugFunction,\n) {\n page.on('popup', async (popup) => {\n if (!popup) {\n console.warn('got a popup event, but the popup is not ready yet, skip');\n return;\n }\n const url = await (popup as PuppeteerPage).url();\n console.log(`Popup opened: ${url}`);\n if (!(popup as PuppeteerPage).isClosed()) {\n try {\n await (popup as PuppeteerPage).close(); // Close the newly opened TAB\n } catch (error) {\n debug(`failed to close popup ${url}, error: ${error}`);\n }\n } else {\n debug(`popup is already closed, skip close ${url}`);\n }\n\n if (!page.isClosed()) {\n try {\n await page.goto(url);\n } catch (error) {\n debug(`failed to goto ${url}, error: ${error}`);\n }\n } else {\n debug(`page is already closed, skip goto ${url}`);\n }\n });\n}\n\nexport function matchElementFromPlan(\n planLocateParam: PlanningLocateParam,\n tree: ElementTreeNode<BaseElement>,\n) {\n if (!planLocateParam) {\n return undefined;\n }\n if (planLocateParam.id) {\n return getNodeFromCacheList(planLocateParam.id);\n }\n\n if (planLocateParam.bbox) {\n const centerPosition = {\n x: Math.floor((planLocateParam.bbox[0] + planLocateParam.bbox[2]) / 2),\n y: Math.floor((planLocateParam.bbox[1] + planLocateParam.bbox[3]) / 2),\n };\n let element = elementByPositionWithElementInfo(tree, centerPosition);\n\n if (!element) {\n element = generateElementByPosition(centerPosition) as BaseElement;\n }\n\n return element;\n }\n\n return undefined;\n}\n\nexport async function matchElementFromCache(\n taskExecutor: PageTaskExecutor,\n xpaths: string[] | undefined,\n cachePrompt: TUserPrompt,\n cacheable: boolean | undefined,\n) {\n try {\n if (\n xpaths?.length &&\n taskExecutor.taskCache?.isCacheResultUsed &&\n cacheable !== false\n ) {\n // hit cache, use new id\n for (let i = 0; i < xpaths.length; i++) {\n const element = await taskExecutor.page.getElementInfoByXpath(\n xpaths[i],\n );\n\n if (element?.id) {\n cacheDebug('cache hit, prompt: %s', cachePrompt);\n cacheDebug(\n 'found a new element with same xpath, xpath: %s, id: %s',\n xpaths[i],\n element?.id,\n );\n return element;\n }\n }\n }\n } catch (error) {\n cacheDebug('get element info by xpath error: ', error);\n }\n}\n\nexport function trimContextByViewport(execution: ExecutionDump) {\n function filterVisibleTree(\n node: ElementTreeNode<BaseElement>,\n ): ElementTreeNode<BaseElement> | null {\n if (!node) return null;\n\n // recursively process all children\n const filteredChildren = Array.isArray(node.children)\n ? (node.children\n .map(filterVisibleTree)\n .filter((child) => child !== null) as ElementTreeNode<BaseElement>[])\n : [];\n\n // if the current node is visible, keep it and the filtered children\n if (node.node && node.node.isVisible === true) {\n return {\n ...node,\n children: filteredChildren,\n };\n }\n\n // if the current node is invisible, but has visible children, create an empty node to include these children\n if (filteredChildren.length > 0) {\n return {\n node: null,\n children: filteredChildren,\n };\n }\n\n // if the current node is invisible and has no visible children, return null\n return null;\n }\n\n return {\n ...execution,\n tasks: Array.isArray(execution.tasks)\n ? execution.tasks.map((task: ExecutionTask) => {\n const newTask = { ...task };\n if (task.pageContext?.tree) {\n newTask.pageContext = {\n ...task.pageContext,\n tree: filterVisibleTree(task.pageContext.tree) || {\n node: null,\n children: [],\n },\n };\n }\n return newTask;\n })\n : execution.tasks,\n };\n}\n\ndeclare const __VERSION__: string | undefined;\n\nexport const getMidsceneVersion = (): string => {\n if (typeof __VERSION__ !== 'undefined') {\n return __VERSION__;\n } else if (\n process.env.__VERSION__ &&\n process.env.__VERSION__ !== 'undefined'\n ) {\n return process.env.__VERSION__;\n }\n throw new Error('__VERSION__ inject failed during build');\n};\n\nexport const parsePrompt = (\n prompt: TUserPrompt,\n): {\n textPrompt: string;\n multimodalPrompt?: TMultimodalPrompt;\n} => {\n if (typeof prompt === 'string') {\n return {\n textPrompt: prompt,\n multimodalPrompt: undefined,\n };\n }\n return {\n textPrompt: prompt.prompt,\n multimodalPrompt: prompt.images\n ? {\n images: prompt.images,\n convertHttpImage2Base64: !!prompt.convertHttpImage2Base64,\n }\n : undefined,\n };\n};\n\nexport const commonWebActionsForWebPage = <T extends AbstractPage>(\n page: T,\n): DeviceAction[] => [\n {\n name: 'Tap',\n description: 'Tap the element',\n location: 'required',\n interfaceAlias: 'aiTap',\n call: async (context) => {\n const { element } = context;\n assert(element, 'Element not found, cannot tap');\n await page.mouse.click(element.center[0], element.center[1], {\n button: 'left',\n });\n },\n },\n {\n name: 'RightClick',\n description: 'Right click the element',\n location: 'required',\n call: async (context) => {\n const { element } = context;\n assert(element, 'Element not found, cannot right click');\n await page.mouse.click(element.center[0], element.center[1], {\n button: 'right',\n });\n },\n },\n {\n name: 'Hover',\n description: 'Move the mouse to the element',\n location: 'required',\n interfaceAlias: 'aiHover',\n call: async (context) => {\n const { element } = context;\n assert(element, 'Element not found, cannot hover');\n await page.mouse.move(element.center[0], element.center[1]);\n },\n },\n {\n name: 'Input',\n description: 'Replace the input field with a new value',\n paramSchema: '{ value: string }',\n paramDescription:\n '`value` is the final that should be filled in the input box. No matter what modifications are required, just provide the final value to replace the existing input value. Giving a blank string means clear the input field.',\n location: 'required',\n whatToLocate: 'The input field to be filled',\n interfaceAlias: 'aiInput',\n call: async (context, param) => {\n const { element } = context;\n if (element) {\n await page.clearInput(element as unknown as ElementInfo);\n\n if (!param || !param.value) {\n return;\n }\n }\n\n // Note: there is another implementation in AndroidDevicePage, which is more complex\n await page.keyboard.type(param.value);\n },\n } as DeviceAction<{ value: string }>,\n {\n name: 'KeyboardPress',\n description: 'Press a key',\n paramSchema: '{ value: string }',\n paramDescription: 'The key to be pressed',\n location: false,\n interfaceAlias: 'aiKeyboardPress',\n call: async (context, param) => {\n const keys = getKeyCommands(param.value);\n await page.keyboard.press(keys as any); // TODO: fix this type error\n },\n } as DeviceAction<{ value: string }>,\n {\n name: 'Scroll',\n description: 'Scroll the page or an element',\n paramSchema:\n '{ direction: \"down\"(default) | \"up\" | \"right\" | \"left\", scrollType: \"once\" (default) | \"untilBottom\" | \"untilTop\" | \"untilRight\" | \"untilLeft\", distance: number | null }',\n paramDescription:\n 'The direction to scroll, the scroll type, and the distance to scroll. The distance is the number of pixels to scroll. If not specified, use `down` direction, `once` scroll type, and `null` distance.',\n location: 'optional',\n whatToLocate: 'The element to be scrolled',\n interfaceAlias: 'aiScroll',\n call: async (context, param) => {\n const { element } = context;\n const startingPoint = element\n ? {\n left: element.center[0],\n top: element.center[1],\n }\n : undefined;\n const scrollToEventName = param?.scrollType;\n if (scrollToEventName === 'untilTop') {\n await page.scrollUntilTop(startingPoint);\n } else if (scrollToEventName === 'untilBottom') {\n await page.scrollUntilBottom(startingPoint);\n } else if (scrollToEventName === 'untilRight') {\n await page.scrollUntilRight(startingPoint);\n } else if (scrollToEventName === 'untilLeft') {\n await page.scrollUntilLeft(startingPoint);\n } else if (scrollToEventName === 'once' || !scrollToEventName) {\n if (param?.direction === 'down' || !param || !param.direction) {\n await page.scrollDown(param?.distance || undefined, startingPoint);\n } else if (param.direction === 'up') {\n await page.scrollUp(param.distance || undefined, startingPoint);\n } else if (param.direction === 'left') {\n await page.scrollLeft(param.distance || undefined, startingPoint);\n } else if (param.direction === 'right') {\n await page.scrollRight(param.distance || undefined, startingPoint);\n } else {\n throw new Error(`Unknown scroll direction: ${param.direction}`);\n }\n // until mouse event is done\n await sleep(500);\n } else {\n throw new Error(\n `Unknown scroll event type: ${scrollToEventName}, param: ${JSON.stringify(\n param,\n )}`,\n );\n }\n },\n } as DeviceAction<ScrollParam>,\n];\n"],"names":["__webpack_require__","module","getter","definition","key","Object","obj","prop","Symbol","debug","getDebug","parseContextFromWebPage","page","_opt","assert","url","uploadTestInfoToServer","screenshotBase64","tree","Promise","base64","treeRoot","webTree","traverseTree","elementInfo","rect","id","content","attributes","indexId","isVisible","WebElementInfo","size","resizeImgBase64","getReportFileName","tag","reportTagName","getAIConfig","MIDSCENE_REPORT_TAG_NAME","dateTimeInFileName","dayjs","uniqueId","uuid","printReportMsg","filepath","logMsg","getCurrentExecutionFile","trace","error","Error","stackTrace","pkgDir","process","stackLines","line","match","targetFileName","testFileIndex","Map","generateCacheId","fileName","taskFile","console","currentIndex","undefined","ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED","replaceIllegalPathCharsAndSpace","str","forceClosePopup","popup","matchElementFromPlan","planLocateParam","getNodeFromCacheList","centerPosition","Math","element","elementByPositionWithElementInfo","generateElementByPosition","matchElementFromCache","taskExecutor","xpaths","cachePrompt","cacheable","_taskExecutor_taskCache","i","cacheDebug","trimContextByViewport","execution","filterVisibleTree","node","filteredChildren","Array","child","task","_task_pageContext","newTask","getMidsceneVersion","__VERSION__","parsePrompt","prompt","commonWebActionsForWebPage","context","param","keys","getKeyCommands","startingPoint","scrollToEventName","JSON","sleep"],"mappings":"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"}
@@ -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 ai_model_namespaceObject = require("@midscene/core/ai-model");
32
33
  const common_namespaceObject = require("@midscene/shared/common");
33
34
  function _define_property(obj, key, value) {
34
35
  if (key in obj) Object.defineProperty(obj, key, {
@@ -183,24 +184,62 @@ class ScriptPlayer {
183
184
  if ('string' == typeof ms) msNumber = Number.parseInt(ms, 10);
184
185
  (0, utils_namespaceObject.assert)(msNumber && msNumber > 0, `ms for sleep must be greater than 0, but got ${ms}`);
185
186
  await new Promise((resolve)=>setTimeout(resolve, msNumber));
186
- } else if ('aiTap' in flowItem) {
187
- const tapTask = flowItem;
188
- await agent.aiTap(tapTask.aiTap, tapTask);
189
- } else if ('aiRightClick' in flowItem) {
190
- const rightClickTask = flowItem;
191
- await agent.aiRightClick(rightClickTask.aiRightClick, rightClickTask);
192
- } else if ('aiHover' in flowItem) {
193
- const hoverTask = flowItem;
194
- await agent.aiHover(hoverTask.aiHover, hoverTask);
195
187
  } else if ('aiInput' in flowItem) {
196
188
  const inputTask = flowItem;
197
- await agent.aiInput(inputTask.aiInput, inputTask.locate, inputTask);
189
+ if (inputTask.locate) {
190
+ const value = inputTask.aiInput;
191
+ const locatePrompt = inputTask.locate;
192
+ await agent.aiInput(value, locatePrompt, inputTask);
193
+ } else {
194
+ const locatePrompt = inputTask.aiInput;
195
+ const value = inputTask.value;
196
+ if (locatePrompt) await agent.aiInput(locatePrompt, {
197
+ ...inputTask,
198
+ value: value
199
+ });
200
+ else throw new Error('aiInput requires either locatePrompt or value and locate');
201
+ }
198
202
  } else if ('aiKeyboardPress' in flowItem) {
199
203
  const keyboardPressTask = flowItem;
200
- await agent.aiKeyboardPress(keyboardPressTask.aiKeyboardPress, keyboardPressTask.locate, keyboardPressTask);
204
+ if (keyboardPressTask.locate) {
205
+ const keyName = keyboardPressTask.aiKeyboardPress;
206
+ const locatePrompt = keyboardPressTask.locate;
207
+ await agent.aiKeyboardPress(keyName, locatePrompt, keyboardPressTask);
208
+ } else if (keyboardPressTask.key) {
209
+ const locatePrompt = keyboardPressTask.aiKeyboardPress;
210
+ const keyName = keyboardPressTask.key;
211
+ if (locatePrompt) await agent.aiKeyboardPress(locatePrompt, {
212
+ ...keyboardPressTask,
213
+ keyName: keyName
214
+ });
215
+ else throw new Error('aiKeyboardPress in new format requires locatePrompt');
216
+ } else {
217
+ const keyName = keyboardPressTask.aiKeyboardPress;
218
+ await agent.aiKeyboardPress(keyName, void 0, keyboardPressTask);
219
+ }
201
220
  } else if ('aiScroll' in flowItem) {
202
221
  const scrollTask = flowItem;
203
- await agent.aiScroll(scrollTask, scrollTask.locate, scrollTask);
222
+ if (scrollTask.locate) {
223
+ const locatePrompt = scrollTask.locate;
224
+ const scrollParam = {
225
+ direction: scrollTask.direction,
226
+ scrollType: scrollTask.scrollType,
227
+ distance: scrollTask.distance
228
+ };
229
+ await agent.aiScroll(scrollParam, locatePrompt, scrollTask);
230
+ } else {
231
+ const locatePrompt = scrollTask.aiScroll;
232
+ const scrollParam = {
233
+ direction: scrollTask.direction,
234
+ scrollType: scrollTask.scrollType,
235
+ distance: scrollTask.distance
236
+ };
237
+ if (locatePrompt) await agent.aiScroll(locatePrompt, {
238
+ ...scrollTask,
239
+ ...scrollParam
240
+ });
241
+ else await agent.aiScroll(scrollParam, void 0, scrollTask);
242
+ }
204
243
  } else if ("javascript" in flowItem) {
205
244
  const evaluateJavaScriptTask = flowItem;
206
245
  const result = await agent.evaluateJavaScript(evaluateJavaScriptTask.javascript);
@@ -210,7 +249,27 @@ class ScriptPlayer {
210
249
  await agent.logScreenshot(logScreenshotTask.logScreenshot, {
211
250
  content: logScreenshotTask.content || ''
212
251
  });
213
- } else throw new Error(`unknown flowItem: ${JSON.stringify(flowItem)}`);
252
+ } else {
253
+ const actionSpace = this.actionSpace;
254
+ let locatePrompt;
255
+ const matchedAction = actionSpace.find((action)=>{
256
+ const actionInterfaceAlias = action.interfaceAlias;
257
+ if (actionInterfaceAlias && Object.prototype.hasOwnProperty.call(flowItem, actionInterfaceAlias)) {
258
+ locatePrompt = flowItem[actionInterfaceAlias];
259
+ return true;
260
+ }
261
+ const keyOfActionInActionSpace = `${ai_model_namespaceObject.actionSpaceTypePrefix}${action.name}`;
262
+ if (Object.prototype.hasOwnProperty.call(flowItem, keyOfActionInActionSpace)) {
263
+ locatePrompt = flowItem[keyOfActionInActionSpace];
264
+ return true;
265
+ }
266
+ return false;
267
+ });
268
+ if (matchedAction) {
269
+ const { [matchedAction.interfaceAlias]: _, [ai_model_namespaceObject.actionSpaceTypePrefix + matchedAction.name]: __, ...restParams } = flowItem;
270
+ await agent.callActionInActionSpace(matchedAction.name, locatePrompt, restParams);
271
+ } else throw new Error(`unknown flowItem: ${JSON.stringify(flowItem)}`);
272
+ }
214
273
  }
215
274
  this.reportFile = agent.reportFile;
216
275
  await this.flushUnstableLogContent();
@@ -225,6 +284,7 @@ class ScriptPlayer {
225
284
  let freeFn = [];
226
285
  try {
227
286
  const { agent: newAgent, freeFn: newFreeFn } = await this.setupAgent(platform);
287
+ this.actionSpace = await newAgent.getActionSpace();
228
288
  agent = newAgent;
229
289
  const originalOnTaskStartTip = agent.onTaskStartTip;
230
290
  agent.onTaskStartTip = (tip)=>{
@@ -291,6 +351,7 @@ class ScriptPlayer {
291
351
  _define_property(this, "pageAgent", void 0);
292
352
  _define_property(this, "agentStatusTip", void 0);
293
353
  _define_property(this, "target", void 0);
354
+ _define_property(this, "actionSpace", void 0);
294
355
  _define_property(this, "scriptPath", void 0);
295
356
  this.script = script;
296
357
  this.setupAgent = setupAgent;
@@ -299,6 +360,7 @@ class ScriptPlayer {
299
360
  this.status = 'init';
300
361
  this.unnamedResultIndex = 0;
301
362
  this.pageAgent = null;
363
+ this.actionSpace = [];
302
364
  this.scriptPath = scriptPath;
303
365
  this.result = {};
304
366
  this.target = script.target || script.web || script.android;
@@ -1 +1 @@
1
- {"version":3,"file":"yaml/player.js","sources":["webpack://@midscene/web/webpack/runtime/define_property_getters","webpack://@midscene/web/webpack/runtime/has_own_property","webpack://@midscene/web/webpack/runtime/make_namespace_object","webpack://@midscene/web/./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\nimport type { PageAgent } from '@/common/agent';\nimport type {\n FreeFn,\n MidsceneYamlFlowItemAIAction,\n MidsceneYamlFlowItemAIAsk,\n MidsceneYamlFlowItemAIAssert,\n MidsceneYamlFlowItemAIBoolean,\n MidsceneYamlFlowItemAIHover,\n MidsceneYamlFlowItemAIInput,\n MidsceneYamlFlowItemAIKeyboardPress,\n MidsceneYamlFlowItemAILocate,\n MidsceneYamlFlowItemAINumber,\n MidsceneYamlFlowItemAIQuery,\n MidsceneYamlFlowItemAIRightClick,\n MidsceneYamlFlowItemAIScroll,\n MidsceneYamlFlowItemAIString,\n MidsceneYamlFlowItemAITap,\n MidsceneYamlFlowItemAIWaitFor,\n MidsceneYamlFlowItemEvaluateJavaScript,\n MidsceneYamlFlowItemLogScreenshot,\n MidsceneYamlFlowItemSleep,\n MidsceneYamlScript,\n MidsceneYamlScriptEnv,\n ScriptPlayerStatusValue,\n ScriptPlayerTaskStatus,\n} from '@midscene/core';\nimport { getMidsceneRunSubDir } from '@midscene/shared/common';\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 pageAgent: PageAgent | null = null;\n public agentStatusTip?: string;\n public target?: MidsceneYamlScriptEnv;\n private scriptPath?: string;\n constructor(\n private script: MidsceneYamlScript,\n private setupAgent: (platform: T) => Promise<{\n agent: PageAgent;\n freeFn: FreeFn[];\n }>,\n public onTaskStatusChange?: (taskStatus: ScriptPlayerTaskStatus) => void,\n scriptPath?: string,\n ) {\n this.scriptPath = scriptPath;\n this.result = {};\n\n this.target = script.target || script.web || script.android;\n\n if (ifInBrowser || ifInWorker) {\n this.output = undefined;\n } else if (this.target?.output) {\n this.output = resolve(process.cwd(), this.target.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 }\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.pageAgent?._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: PageAgent) {\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 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 assert(\n typeof prompt === 'string',\n 'prompt for aiAction must be a string',\n );\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 assert(\n typeof prompt === 'string',\n 'prompt for aiAssert must be a string',\n );\n await agent.aiAssert(prompt, msg);\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 assert(\n typeof prompt === 'string',\n 'prompt for aiQuery must be a string',\n );\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 assert(\n typeof prompt === 'string',\n 'prompt for number must be a string',\n );\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 assert(\n typeof prompt === 'string',\n 'prompt for string must be a string',\n );\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 assert(\n typeof prompt === 'string',\n 'prompt for boolean must be a string',\n );\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 assert(typeof prompt === 'string', 'prompt for aiAsk must be a string');\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 assert(\n typeof prompt === 'string',\n 'prompt for aiLocate must be a string',\n );\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 assert(\n typeof prompt === 'string',\n 'prompt for aiWaitFor must be a string',\n );\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 ('aiTap' in (flowItem as MidsceneYamlFlowItemAITap)) {\n const tapTask = flowItem as MidsceneYamlFlowItemAITap;\n await agent.aiTap(tapTask.aiTap, tapTask);\n } else if (\n 'aiRightClick' in (flowItem as MidsceneYamlFlowItemAIRightClick)\n ) {\n const rightClickTask = flowItem as MidsceneYamlFlowItemAIRightClick;\n await agent.aiRightClick(rightClickTask.aiRightClick, rightClickTask);\n } else if ('aiHover' in (flowItem as MidsceneYamlFlowItemAIHover)) {\n const hoverTask = flowItem as MidsceneYamlFlowItemAIHover;\n await agent.aiHover(hoverTask.aiHover, hoverTask);\n } else if ('aiInput' in (flowItem as MidsceneYamlFlowItemAIInput)) {\n // may be input empty string ''\n const inputTask = flowItem as MidsceneYamlFlowItemAIInput;\n await agent.aiInput(inputTask.aiInput, inputTask.locate, inputTask);\n } else if (\n 'aiKeyboardPress' in (flowItem as MidsceneYamlFlowItemAIKeyboardPress)\n ) {\n const keyboardPressTask =\n flowItem as MidsceneYamlFlowItemAIKeyboardPress;\n await agent.aiKeyboardPress(\n keyboardPressTask.aiKeyboardPress,\n keyboardPressTask.locate,\n keyboardPressTask,\n );\n } else if ('aiScroll' in (flowItem as MidsceneYamlFlowItemAIScroll)) {\n const scrollTask = flowItem as MidsceneYamlFlowItemAIScroll;\n await agent.aiScroll(scrollTask, scrollTask.locate, scrollTask);\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 {\n throw new Error(`unknown flowItem: ${JSON.stringify(flowItem)}`);\n }\n }\n this.reportFile = agent.reportFile;\n await this.flushUnstableLogContent();\n }\n\n async run() {\n const { target, web, android, tasks } = this.script;\n const webEnv = web || target;\n const androidEnv = android;\n const platform = webEnv || androidEnv;\n\n this.setPlayerStatus('running');\n\n let agent: PageAgent | null = null;\n let freeFn: FreeFn[] = [];\n try {\n const { agent: newAgent, freeFn: newFreeFn } = await this.setupAgent(\n platform as T,\n );\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.pageAgent = 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.pageAgent);\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","ScriptPlayer","value","keyToUse","console","status","error","taskIndex","taskIndexToNotify","taskStatus","index","statusValue","output","resolve","process","outputDir","dirname","existsSync","mkdirSync","writeFileSync","JSON","undefined","_this_pageAgent","content","filePath","agent","flow","assert","flowItemIndex","currentStep","Number","flowItem","actionTask","prompt","assertTask","msg","queryTask","options","queryResult","numberTask","numberResult","stringTask","stringResult","booleanTask","booleanResult","askTask","askResult","locateTask","locateResult","waitForTask","timeout","sleepTask","ms","msNumber","Promise","setTimeout","tapTask","rightClickTask","hoverTask","inputTask","keyboardPressTask","scrollTask","evaluateJavaScriptTask","result","logScreenshotTask","Error","target","web","android","tasks","webEnv","androidEnv","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/web/webpack/runtime/define_property_getters","webpack://@midscene/web/webpack/runtime/has_own_property","webpack://@midscene/web/webpack/runtime/make_namespace_object","webpack://@midscene/web/./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\nimport type { PageAgent } from '@/common/agent';\nimport type {\n DeviceAction,\n FreeFn,\n MidsceneYamlFlowItemAIAction,\n MidsceneYamlFlowItemAIAsk,\n MidsceneYamlFlowItemAIAssert,\n MidsceneYamlFlowItemAIBoolean,\n MidsceneYamlFlowItemAIInput,\n MidsceneYamlFlowItemAIKeyboardPress,\n MidsceneYamlFlowItemAILocate,\n MidsceneYamlFlowItemAINumber,\n MidsceneYamlFlowItemAIQuery,\n MidsceneYamlFlowItemAIScroll,\n MidsceneYamlFlowItemAIString,\n MidsceneYamlFlowItemAIWaitFor,\n MidsceneYamlFlowItemEvaluateJavaScript,\n MidsceneYamlFlowItemLogScreenshot,\n MidsceneYamlFlowItemSleep,\n MidsceneYamlScript,\n MidsceneYamlScriptEnv,\n ScriptPlayerStatusValue,\n ScriptPlayerTaskStatus,\n TUserPrompt,\n} from '@midscene/core';\nimport { actionSpaceTypePrefix } from '@midscene/core/ai-model';\nimport { getMidsceneRunSubDir } from '@midscene/shared/common';\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 pageAgent: PageAgent | 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: PageAgent;\n freeFn: FreeFn[];\n }>,\n public onTaskStatusChange?: (taskStatus: ScriptPlayerTaskStatus) => void,\n scriptPath?: string,\n ) {\n this.scriptPath = scriptPath;\n this.result = {};\n this.target = script.target || script.web || script.android;\n\n if (ifInBrowser || ifInWorker) {\n this.output = undefined;\n } else if (this.target?.output) {\n this.output = resolve(process.cwd(), this.target.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 }\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.pageAgent?._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: PageAgent) {\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 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 assert(\n typeof prompt === 'string',\n 'prompt for aiAction must be a string',\n );\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 assert(\n typeof prompt === 'string',\n 'prompt for aiAssert must be a string',\n );\n await agent.aiAssert(prompt, msg);\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 assert(\n typeof prompt === 'string',\n 'prompt for aiQuery must be a string',\n );\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 assert(\n typeof prompt === 'string',\n 'prompt for number must be a string',\n );\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 assert(\n typeof prompt === 'string',\n 'prompt for string must be a string',\n );\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 assert(\n typeof prompt === 'string',\n 'prompt for boolean must be a string',\n );\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 assert(typeof prompt === 'string', 'prompt for aiAsk must be a string');\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 assert(\n typeof prompt === 'string',\n 'prompt for aiLocate must be a string',\n );\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 assert(\n typeof prompt === 'string',\n 'prompt for aiWaitFor must be a string',\n );\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 ('aiInput' in (flowItem as MidsceneYamlFlowItemAIInput)) {\n // may be input empty string ''\n const inputTask = flowItem as MidsceneYamlFlowItemAIInput;\n\n // Compatibility with previous version:\n // Old format: { aiInput: string (value), locate: TUserPrompt }\n // New format: { aiInput: TUserPrompt, value: string }\n if ((inputTask as any).locate) {\n // Old format - aiInput is the value, locate is the prompt\n const value = inputTask.aiInput as string;\n const locatePrompt = (inputTask as any).locate;\n await agent.aiInput(value, locatePrompt, inputTask);\n } else {\n // New format - aiInput is the prompt, value is the value\n const locatePrompt = inputTask.aiInput;\n const value = inputTask.value;\n if (locatePrompt) {\n await agent.aiInput(locatePrompt, {\n ...inputTask,\n value: value,\n });\n } else {\n throw new Error(\n 'aiInput requires either locatePrompt or value and locate',\n );\n }\n }\n } else if (\n 'aiKeyboardPress' in (flowItem as MidsceneYamlFlowItemAIKeyboardPress)\n ) {\n const keyboardPressTask =\n flowItem as MidsceneYamlFlowItemAIKeyboardPress;\n\n // Compatibility with previous version:\n // Old format: { aiKeyboardPress: string (key), locate?: TUserPrompt }\n // New format: { aiKeyboardPress: TUserPrompt, key: string }\n if ((keyboardPressTask as any).locate) {\n // Old format - aiKeyboardPress is the key, locate is the prompt\n const keyName = keyboardPressTask.aiKeyboardPress as string;\n const locatePrompt = (keyboardPressTask as any).locate;\n await agent.aiKeyboardPress(keyName, locatePrompt, keyboardPressTask);\n } else if ((keyboardPressTask as any).key) {\n // New format - aiKeyboardPress is the prompt, key is the key\n const locatePrompt = keyboardPressTask.aiKeyboardPress;\n const keyName = (keyboardPressTask as any).key;\n if (locatePrompt) {\n await agent.aiKeyboardPress(locatePrompt, {\n ...keyboardPressTask,\n keyName: keyName,\n });\n } else {\n throw new Error(\n 'aiKeyboardPress in new format requires locatePrompt',\n );\n }\n } else {\n // Fallback to old format without locate (global key press)\n const keyName = keyboardPressTask.aiKeyboardPress as string;\n await agent.aiKeyboardPress(keyName, undefined, keyboardPressTask);\n }\n } else if ('aiScroll' in (flowItem as MidsceneYamlFlowItemAIScroll)) {\n const scrollTask = flowItem as MidsceneYamlFlowItemAIScroll;\n\n // Compatibility with previous version:\n // Old format: { aiScroll: null, locate?: TUserPrompt, direction, scrollType, distance? }\n // New format: { aiScroll: TUserPrompt, direction, scrollType, distance? }\n if ((scrollTask as any).locate) {\n // Old format - locate is the prompt, aiScroll is null/ignored\n const locatePrompt = (scrollTask as any).locate;\n const scrollParam = {\n direction: scrollTask.direction,\n scrollType: scrollTask.scrollType,\n distance: scrollTask.distance,\n };\n await agent.aiScroll(scrollParam, locatePrompt, scrollTask);\n } else {\n // New format - aiScroll is the prompt, or no prompt for global scroll\n const locatePrompt = scrollTask.aiScroll;\n const scrollParam = {\n direction: scrollTask.direction,\n scrollType: scrollTask.scrollType,\n distance: scrollTask.distance,\n };\n if (locatePrompt) {\n await agent.aiScroll(locatePrompt, {\n ...scrollTask,\n ...scrollParam,\n });\n } else {\n // Global scroll without specific element\n await agent.aiScroll(scrollParam, undefined, scrollTask);\n }\n }\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 {\n // generic action, find the action in actionSpace\n const actionSpace = this.actionSpace;\n let locatePrompt: TUserPrompt | 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 locatePrompt = flowItem[\n actionInterfaceAlias as keyof typeof flowItem\n ] as TUserPrompt;\n return true;\n }\n\n const keyOfActionInActionSpace = `${actionSpaceTypePrefix}${action.name}`;\n if (\n Object.prototype.hasOwnProperty.call(\n flowItem,\n keyOfActionInActionSpace,\n )\n ) {\n locatePrompt = flowItem[\n keyOfActionInActionSpace as keyof typeof flowItem\n ] as TUserPrompt;\n return true;\n }\n\n return false;\n });\n\n if (matchedAction) {\n const {\n [matchedAction.interfaceAlias as string]: _,\n [actionSpaceTypePrefix + matchedAction.name]: __,\n ...restParams\n } = flowItem as any;\n await agent.callActionInActionSpace(\n matchedAction.name,\n locatePrompt,\n restParams,\n );\n } else {\n throw new Error(`unknown flowItem: ${JSON.stringify(flowItem)}`);\n }\n }\n }\n this.reportFile = agent.reportFile;\n await this.flushUnstableLogContent();\n }\n\n async run() {\n const { target, web, android, tasks } = this.script;\n const webEnv = web || target;\n const androidEnv = android;\n const platform = webEnv || androidEnv;\n\n this.setPlayerStatus('running');\n\n let agent: PageAgent | 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.pageAgent = 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.pageAgent);\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","ScriptPlayer","value","keyToUse","console","status","error","taskIndex","taskIndexToNotify","taskStatus","index","statusValue","output","resolve","process","outputDir","dirname","existsSync","mkdirSync","writeFileSync","JSON","undefined","_this_pageAgent","content","filePath","agent","flow","assert","flowItemIndex","currentStep","Number","flowItem","actionTask","prompt","assertTask","msg","queryTask","options","queryResult","numberTask","numberResult","stringTask","stringResult","booleanTask","booleanResult","askTask","askResult","locateTask","locateResult","waitForTask","timeout","sleepTask","ms","msNumber","Promise","setTimeout","inputTask","locatePrompt","Error","keyboardPressTask","keyName","scrollTask","scrollParam","evaluateJavaScriptTask","result","logScreenshotTask","actionSpace","matchedAction","action","actionInterfaceAlias","keyOfActionInActionSpace","actionSpaceTypePrefix","_","__","restParams","target","web","android","tasks","webEnv","androidEnv","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,5 +1,5 @@
1
1
  import type { WebPage } from './page.d';
2
- import { type AgentAssertOpt, type AgentDescribeElementAtPointResult, type AgentWaitForOpt, type ExecutionDump, type GroupedActionDump, Insight, type InsightAction, type InsightExtractOption, type InsightExtractParam, type LocateOption, type LocateResultElement, type LocateValidatorResult, type LocatorValidatorOption, type OnTaskStartTip, type ScrollParam, type TUserPrompt } from '@midscene/core';
2
+ import { type AgentAssertOpt, type AgentDescribeElementAtPointResult, type AgentWaitForOpt, type DeviceAction, type ExecutionDump, type GroupedActionDump, Insight, type InsightAction, type InsightExtractOption, type InsightExtractParam, type LocateOption, type LocateResultElement, type LocateValidatorResult, type LocatorValidatorOption, type OnTaskStartTip, type ScrollParam, type TUserPrompt } from '@midscene/core';
3
3
  import { PageTaskExecutor } from '../common/tasks';
4
4
  import type { WebElementInfo, WebUIContext } from '../web-element';
5
5
  import type { AndroidDeviceInputOpt } from './page';
@@ -42,6 +42,7 @@ export declare class PageAgent<PageType extends WebPage = WebPage> {
42
42
  */
43
43
  private frozenPageContext?;
44
44
  constructor(page: PageType, opts?: PageAgentOpt);
45
+ getActionSpace(): Promise<DeviceAction[]>;
45
46
  getUIContext(action?: InsightAction): Promise<WebUIContext>;
46
47
  _snapshotContext(): Promise<WebUIContext>;
47
48
  setAIActionContext(prompt: string): Promise<void>;
@@ -53,11 +54,29 @@ export declare class PageAgent<PageType extends WebPage = WebPage> {
53
54
  private callbackOnTaskStartTip;
54
55
  private afterTaskRunning;
55
56
  private buildDetailedLocateParam;
56
- aiTap(locatePrompt: TUserPrompt, opt?: LocateOption): Promise<any>;
57
- aiRightClick(locatePrompt: TUserPrompt, opt?: LocateOption): Promise<any>;
58
- aiHover(locatePrompt: TUserPrompt, opt?: LocateOption): Promise<any>;
57
+ private locateTaskForLocate;
58
+ callActionInActionSpace<T = any>(type: string, locatePrompt?: TUserPrompt, opt?: LocateOption): Promise<void>;
59
+ aiTap(locatePrompt: TUserPrompt, opt?: LocateOption): Promise<void>;
60
+ aiRightClick(locatePrompt: TUserPrompt, opt?: LocateOption): Promise<void>;
61
+ aiHover(locatePrompt: TUserPrompt, opt?: LocateOption): Promise<void>;
62
+ aiInput(locatePrompt: TUserPrompt, opt: AndroidDeviceInputOpt & LocateOption & {
63
+ value: string;
64
+ }): Promise<any>;
65
+ /**
66
+ * @deprecated Use aiInput(locatePrompt, opt) instead where opt contains the value
67
+ */
59
68
  aiInput(value: string, locatePrompt: TUserPrompt, opt?: AndroidDeviceInputOpt & LocateOption): Promise<any>;
69
+ aiKeyboardPress(locatePrompt: TUserPrompt, opt: LocateOption & {
70
+ keyName: string;
71
+ }): Promise<any>;
72
+ /**
73
+ * @deprecated Use aiKeyboardPress(locatePrompt, opt) instead where opt contains the keyName
74
+ */
60
75
  aiKeyboardPress(keyName: string, locatePrompt?: TUserPrompt, opt?: LocateOption): Promise<any>;
76
+ aiScroll(locatePrompt: TUserPrompt | undefined, opt: LocateOption & ScrollParam): Promise<any>;
77
+ /**
78
+ * @deprecated Use aiScroll(locatePrompt, opt) instead where opt contains the scroll parameters
79
+ */
61
80
  aiScroll(scrollParam: ScrollParam, locatePrompt?: TUserPrompt, opt?: LocateOption): Promise<any>;
62
81
  aiAction(taskPrompt: string, opt?: {
63
82
  cacheable?: boolean;
@@ -16,6 +16,7 @@ export declare class ScriptPlayer<T extends MidsceneYamlScriptEnv> {
16
16
  private pageAgent;
17
17
  agentStatusTip?: string;
18
18
  target?: MidsceneYamlScriptEnv;
19
+ private actionSpace;
19
20
  private scriptPath?;
20
21
  constructor(script: MidsceneYamlScript, setupAgent: (platform: T) => Promise<{
21
22
  agent: PageAgent;
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "Browser use",
9
9
  "Android use"
10
10
  ],
11
- "version": "0.26.6",
11
+ "version": "0.26.7-beta-20250815153024.0",
12
12
  "repository": "https://github.com/web-infra-dev/midscene",
13
13
  "homepage": "https://midscenejs.com/",
14
14
  "main": "./dist/lib/index.js",
@@ -131,8 +131,8 @@
131
131
  "semver": "7.5.2",
132
132
  "socket.io": "^4.8.1",
133
133
  "socket.io-client": "4.8.1",
134
- "@midscene/core": "0.26.6",
135
- "@midscene/shared": "0.26.6"
134
+ "@midscene/core": "0.26.7-beta-20250815153024.0",
135
+ "@midscene/shared": "0.26.7-beta-20250815153024.0"
136
136
  },
137
137
  "devDependencies": {
138
138
  "@playwright/test": "^1.44.1",