@midscene/core 0.30.5-beta-20251020035347.0 → 0.30.5

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.
@@ -1 +1 @@
1
- {"version":3,"file":"utils.mjs","sources":["webpack://@midscene/core/./src/utils.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport * as fs from 'node:fs';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport * as path from 'node:path';\nimport {\n defaultRunDirName,\n getMidsceneRunSubDir,\n} from '@midscene/shared/common';\nimport {\n MIDSCENE_CACHE,\n MIDSCENE_DEBUG_MODE,\n globalConfigManager,\n} from '@midscene/shared/env';\nimport { getRunningPkgInfo } from '@midscene/shared/node';\nimport { assert, logMsg } from '@midscene/shared/utils';\nimport {\n escapeScriptTag,\n ifInBrowser,\n ifInWorker,\n uuid,\n} from '@midscene/shared/utils';\nimport type { Cache, Rect, ReportDumpWithAttributes } from './types';\n\nlet logEnvReady = false;\n\nexport { appendFileSync } from 'node:fs';\n\nexport const groupedActionDumpFileExt = 'web-dump.json';\n\n/**\n * Process cache configuration with environment variable support and backward compatibility.\n *\n * @param cache - The original cache configuration\n * @param fallbackId - The fallback ID to use when cache is enabled but no ID is specified\n * @param cacheId - Optional legacy cacheId for backward compatibility (requires MIDSCENE_CACHE env var)\n * @returns Processed cache configuration\n */\nexport function processCacheConfig(\n cache: Cache | undefined,\n fallbackId: string,\n cacheId?: string,\n): Cache | undefined {\n // 1. New cache object configuration (highest priority)\n if (cache !== undefined) {\n if (cache === false) {\n return undefined; // Completely disable cache\n }\n\n if (cache === true) {\n // Auto-generate ID using fallback for CLI/YAML scenarios\n // Agent will validate and reject this later if needed\n return { id: fallbackId };\n }\n\n // cache is object configuration\n if (typeof cache === 'object' && cache !== null) {\n // Auto-generate ID using fallback when missing (for CLI/YAML scenarios)\n if (!cache.id) {\n return { ...cache, id: fallbackId };\n }\n return cache;\n }\n }\n\n // 2. Backward compatibility: support old cacheId (requires environment variable)\n if (cacheId) {\n const envEnabled =\n globalConfigManager.getEnvConfigInBoolean(MIDSCENE_CACHE);\n if (envEnabled) {\n return { id: cacheId };\n }\n }\n\n // 3. No cache configuration\n return undefined;\n}\n\nconst reportInitializedMap = new Map<string, boolean>();\n\ndeclare const __DEV_REPORT_PATH__: string;\n\nexport function getReportTpl() {\n if (typeof __DEV_REPORT_PATH__ === 'string' && __DEV_REPORT_PATH__) {\n return fs.readFileSync(__DEV_REPORT_PATH__, 'utf-8');\n }\n const reportTpl = 'REPLACE_ME_WITH_REPORT_HTML';\n\n return reportTpl;\n}\n\n/**\n * high performance, insert script before </html> in HTML file\n * only truncate and append, no temporary file\n */\nexport function insertScriptBeforeClosingHtml(\n filePath: string,\n scriptContent: string,\n): void {\n const htmlEndTag = '</html>';\n const stat = fs.statSync(filePath);\n\n const readSize = Math.min(stat.size, 4096);\n const start = Math.max(0, stat.size - readSize);\n const buffer = Buffer.alloc(stat.size - start);\n const fd = fs.openSync(filePath, 'r');\n fs.readSync(fd, buffer, 0, buffer.length, start);\n fs.closeSync(fd);\n\n const tailStr = buffer.toString('utf8');\n const htmlEndIdx = tailStr.lastIndexOf(htmlEndTag);\n if (htmlEndIdx === -1) {\n throw new Error(`No </html> found in file:${filePath}`);\n }\n\n // calculate the correct byte position: char position to byte position\n const beforeHtmlInTail = tailStr.slice(0, htmlEndIdx);\n const htmlEndPos = start + Buffer.byteLength(beforeHtmlInTail, 'utf8');\n\n // truncate to </html> before\n fs.truncateSync(filePath, htmlEndPos);\n // append script and </html>\n fs.appendFileSync(filePath, `${scriptContent}\\n${htmlEndTag}\\n`);\n}\n\nexport function reportHTMLContent(\n dumpData: string | ReportDumpWithAttributes,\n reportPath?: string,\n appendReport?: boolean,\n withTpl = true, // whether return with report template, default = true\n): string {\n let tpl = '';\n if (withTpl) {\n tpl = getReportTpl();\n\n if (!tpl) {\n console.warn('reportTpl is not set, will not write report');\n return '';\n }\n }\n // if reportPath is set, it means we are in write to file mode\n const writeToFile = reportPath && !ifInBrowser;\n let dumpContent = '';\n\n if (typeof dumpData === 'string') {\n // do not use template string here, will cause bundle error\n dumpContent =\n // biome-ignore lint/style/useTemplate: <explanation>\n '<script type=\"midscene_web_dump\" type=\"application/json\">\\n' +\n escapeScriptTag(dumpData) +\n '\\n</script>';\n } else {\n const { dumpString, attributes } = dumpData;\n const attributesArr = Object.keys(attributes || {}).map((key) => {\n return `${key}=\"${encodeURIComponent(attributes![key])}\"`;\n });\n\n dumpContent =\n // do not use template string here, will cause bundle error\n // biome-ignore lint/style/useTemplate: <explanation>\n '<script type=\"midscene_web_dump\" type=\"application/json\" ' +\n attributesArr.join(' ') +\n '>\\n' +\n escapeScriptTag(dumpString) +\n '\\n</script>';\n }\n\n if (writeToFile) {\n if (!appendReport) {\n writeFileSync(reportPath!, tpl + dumpContent, { flag: 'w' });\n return reportPath!;\n }\n\n if (!reportInitializedMap.get(reportPath!)) {\n writeFileSync(reportPath!, tpl, { flag: 'w' });\n reportInitializedMap.set(reportPath!, true);\n }\n\n insertScriptBeforeClosingHtml(reportPath!, dumpContent);\n return reportPath!;\n }\n\n return tpl + dumpContent;\n}\n\nexport function writeDumpReport(\n fileName: string,\n dumpData: string | ReportDumpWithAttributes,\n appendReport?: boolean,\n): string | null {\n if (ifInBrowser || ifInWorker) {\n console.log('will not write report in browser');\n return null;\n }\n\n const reportPath = path.join(\n getMidsceneRunSubDir('report'),\n `${fileName}.html`,\n );\n\n reportHTMLContent(dumpData, reportPath, appendReport);\n\n if (process.env.MIDSCENE_DEBUG_LOG_JSON) {\n const jsonPath = `${reportPath}.json`;\n let data;\n\n if (typeof dumpData === 'string') {\n data = JSON.parse(dumpData) as ReportDumpWithAttributes;\n } else {\n data = dumpData;\n }\n\n writeFileSync(jsonPath, JSON.stringify(data, null, 2), {\n flag: appendReport ? 'a' : 'w',\n });\n\n logMsg(`Midscene - dump file written: ${jsonPath}`);\n }\n\n return reportPath;\n}\n\nexport function writeLogFile(opts: {\n fileName: string;\n fileExt: string;\n fileContent: string | ReportDumpWithAttributes;\n type: 'dump' | 'cache' | 'report' | 'tmp';\n generateReport?: boolean;\n appendReport?: boolean;\n}) {\n if (ifInBrowser || ifInWorker) {\n return '/mock/report.html';\n }\n const { fileName, fileExt, fileContent, type = 'dump' } = opts;\n const targetDir = getMidsceneRunSubDir(type);\n // Ensure directory exists\n if (!logEnvReady) {\n assert(targetDir, 'logDir should be set before writing dump file');\n\n // gitIgnore in the parent directory\n const gitIgnorePath = path.join(targetDir, '../../.gitignore');\n const gitPath = path.join(targetDir, '../../.git');\n let gitIgnoreContent = '';\n\n if (existsSync(gitPath)) {\n // if the git path exists, we need to add the log folder to the git ignore file\n if (existsSync(gitIgnorePath)) {\n gitIgnoreContent = readFileSync(gitIgnorePath, 'utf-8');\n }\n\n // ignore the log folder\n if (!gitIgnoreContent.includes(`${defaultRunDirName}/`)) {\n writeFileSync(\n gitIgnorePath,\n `${gitIgnoreContent}\\n# Midscene.js dump files\\n${defaultRunDirName}/dump\\n${defaultRunDirName}/report\\n${defaultRunDirName}/tmp\\n${defaultRunDirName}/log\\n`,\n 'utf-8',\n );\n }\n }\n\n logEnvReady = true;\n }\n\n const filePath = path.join(targetDir, `${fileName}.${fileExt}`);\n\n if (type !== 'dump') {\n // do not write dump file any more\n writeFileSync(filePath, JSON.stringify(fileContent));\n }\n\n if (opts?.generateReport) {\n return writeDumpReport(fileName, fileContent, opts.appendReport);\n }\n\n return filePath;\n}\n\nexport function getTmpDir(): string | null {\n try {\n const runningPkgInfo = getRunningPkgInfo();\n if (!runningPkgInfo) {\n return null;\n }\n const { name } = runningPkgInfo;\n const tmpPath = path.join(tmpdir(), name);\n mkdirSync(tmpPath, { recursive: true });\n return tmpPath;\n } catch (e) {\n return null;\n }\n}\n\nexport function getTmpFile(fileExtWithoutDot: string): string | null {\n if (ifInBrowser || ifInWorker) {\n return null;\n }\n const tmpDir = getTmpDir();\n const filename = `${uuid()}.${fileExtWithoutDot}`;\n return path.join(tmpDir!, filename);\n}\n\nexport function overlapped(container: Rect, target: Rect) {\n // container and the target have some part overlapped\n return (\n container.left < target.left + target.width &&\n container.left + container.width > target.left &&\n container.top < target.top + target.height &&\n container.top + container.height > target.top\n );\n}\n\nexport async function sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function replacerForPageObject(_key: string, value: any) {\n if (value && value.constructor?.name === 'Page') {\n return '[Page object]';\n }\n if (value && value.constructor?.name === 'Browser') {\n return '[Browser object]';\n }\n return value;\n}\n\nexport function stringifyDumpData(data: any, indents?: number) {\n return JSON.stringify(data, replacerForPageObject, indents);\n}\n\ndeclare const __VERSION__: string;\n\nexport function getVersion() {\n return __VERSION__;\n}\n\nfunction debugLog(...message: any[]) {\n // always read from process.env, and cannot be override by modelConfig, overrideAIConfig, etc.\n // also avoid circular dependency\n const debugMode = process.env[MIDSCENE_DEBUG_MODE];\n if (debugMode) {\n console.log('[Midscene]', ...message);\n }\n}\n\nlet lastReportedRepoUrl = '';\nexport function uploadTestInfoToServer({\n testUrl,\n serverUrl,\n}: { testUrl: string; serverUrl?: string }) {\n let repoUrl = '';\n let userEmail = '';\n\n try {\n repoUrl = execSync('git config --get remote.origin.url').toString().trim();\n userEmail = execSync('git config --get user.email').toString().trim();\n } catch (error) {\n debugLog('Failed to get git info:', error);\n }\n\n // Only upload test info if:\n // 1. Server URL is configured AND\n // 2. Either:\n // - We have a repo URL that's different from last reported one (to avoid duplicate reports)\n // - OR we don't have a repo URL but have a test URL (for non-git environments)\n if (\n serverUrl &&\n ((repoUrl && repoUrl !== lastReportedRepoUrl) || (!repoUrl && testUrl))\n ) {\n debugLog('Uploading test info to server', {\n serverUrl,\n repoUrl,\n testUrl,\n userEmail,\n });\n\n fetch(serverUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n repo_url: repoUrl,\n test_url: testUrl,\n user_email: userEmail,\n }),\n })\n .then((response) => response.json())\n .then((data) => {\n debugLog('Successfully uploaded test info to server:', data);\n })\n .catch((error) =>\n debugLog('Failed to upload test info to server:', error),\n );\n lastReportedRepoUrl = repoUrl;\n }\n}\n"],"names":["logEnvReady","groupedActionDumpFileExt","processCacheConfig","cache","fallbackId","cacheId","undefined","envEnabled","globalConfigManager","MIDSCENE_CACHE","reportInitializedMap","Map","getReportTpl","reportTpl","insertScriptBeforeClosingHtml","filePath","scriptContent","htmlEndTag","stat","fs","readSize","Math","start","buffer","Buffer","fd","tailStr","htmlEndIdx","Error","beforeHtmlInTail","htmlEndPos","reportHTMLContent","dumpData","reportPath","appendReport","withTpl","tpl","console","writeToFile","ifInBrowser","dumpContent","escapeScriptTag","dumpString","attributes","attributesArr","Object","key","encodeURIComponent","writeFileSync","writeDumpReport","fileName","ifInWorker","path","getMidsceneRunSubDir","process","jsonPath","data","JSON","logMsg","writeLogFile","opts","fileExt","fileContent","type","targetDir","assert","gitIgnorePath","gitPath","gitIgnoreContent","existsSync","readFileSync","defaultRunDirName","getTmpDir","runningPkgInfo","getRunningPkgInfo","name","tmpPath","tmpdir","mkdirSync","e","getTmpFile","fileExtWithoutDot","tmpDir","filename","uuid","overlapped","container","target","sleep","ms","Promise","resolve","setTimeout","replacerForPageObject","_key","value","_value_constructor","_value_constructor1","stringifyDumpData","indents","getVersion","__VERSION__","debugLog","message","debugMode","MIDSCENE_DEBUG_MODE","lastReportedRepoUrl","uploadTestInfoToServer","testUrl","serverUrl","repoUrl","userEmail","execSync","error","fetch","response"],"mappings":"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"}
1
+ {"version":3,"file":"utils.mjs","sources":["webpack://@midscene/core/./src/utils.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport * as fs from 'node:fs';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport * as path from 'node:path';\nimport {\n defaultRunDirName,\n getMidsceneRunSubDir,\n} from '@midscene/shared/common';\nimport {\n MIDSCENE_CACHE,\n MIDSCENE_DEBUG_MODE,\n globalConfigManager,\n} from '@midscene/shared/env';\nimport { getRunningPkgInfo } from '@midscene/shared/node';\nimport { assert, logMsg } from '@midscene/shared/utils';\nimport {\n escapeScriptTag,\n ifInBrowser,\n ifInWorker,\n uuid,\n} from '@midscene/shared/utils';\nimport type { Cache, Rect, ReportDumpWithAttributes } from './types';\n\nlet logEnvReady = false;\n\nexport { appendFileSync } from 'node:fs';\n\nexport const groupedActionDumpFileExt = 'web-dump.json';\n\n/**\n * Process cache configuration with environment variable support and backward compatibility.\n *\n * @param cache - The original cache configuration\n * @param cacheId - The cache ID to use as:\n * 1. Fallback ID when cache is true or cache object has no ID\n * 2. Legacy cacheId when cache is undefined (requires MIDSCENE_CACHE env var)\n * @returns Processed cache configuration\n */\nexport function processCacheConfig(\n cache: Cache | undefined,\n cacheId: string,\n): Cache | undefined {\n // 1. New cache object configuration (highest priority)\n if (cache !== undefined) {\n if (cache === false) {\n return undefined; // Completely disable cache\n }\n\n if (cache === true) {\n // Auto-generate ID using cacheId for CLI/YAML scenarios\n // Agent will validate and reject this later if needed\n return { id: cacheId };\n }\n\n // cache is object configuration\n if (typeof cache === 'object' && cache !== null) {\n // Auto-generate ID using cacheId when missing (for CLI/YAML scenarios)\n if (!cache.id) {\n return { ...cache, id: cacheId };\n }\n return cache;\n }\n }\n\n // 2. Backward compatibility: support old cacheId (requires environment variable)\n // When cache is undefined, check if legacy cacheId mode is enabled via env var\n const envEnabled = globalConfigManager.getEnvConfigInBoolean(MIDSCENE_CACHE);\n\n if (envEnabled && cacheId) {\n return { id: cacheId };\n }\n\n // 3. No cache configuration\n return undefined;\n}\n\nconst reportInitializedMap = new Map<string, boolean>();\n\ndeclare const __DEV_REPORT_PATH__: string;\n\nexport function getReportTpl() {\n if (typeof __DEV_REPORT_PATH__ === 'string' && __DEV_REPORT_PATH__) {\n return fs.readFileSync(__DEV_REPORT_PATH__, 'utf-8');\n }\n const reportTpl = 'REPLACE_ME_WITH_REPORT_HTML';\n\n return reportTpl;\n}\n\n/**\n * high performance, insert script before </html> in HTML file\n * only truncate and append, no temporary file\n */\nexport function insertScriptBeforeClosingHtml(\n filePath: string,\n scriptContent: string,\n): void {\n const htmlEndTag = '</html>';\n const stat = fs.statSync(filePath);\n\n const readSize = Math.min(stat.size, 4096);\n const start = Math.max(0, stat.size - readSize);\n const buffer = Buffer.alloc(stat.size - start);\n const fd = fs.openSync(filePath, 'r');\n fs.readSync(fd, buffer, 0, buffer.length, start);\n fs.closeSync(fd);\n\n const tailStr = buffer.toString('utf8');\n const htmlEndIdx = tailStr.lastIndexOf(htmlEndTag);\n if (htmlEndIdx === -1) {\n throw new Error(`No </html> found in file:${filePath}`);\n }\n\n // calculate the correct byte position: char position to byte position\n const beforeHtmlInTail = tailStr.slice(0, htmlEndIdx);\n const htmlEndPos = start + Buffer.byteLength(beforeHtmlInTail, 'utf8');\n\n // truncate to </html> before\n fs.truncateSync(filePath, htmlEndPos);\n // append script and </html>\n fs.appendFileSync(filePath, `${scriptContent}\\n${htmlEndTag}\\n`);\n}\n\nexport function reportHTMLContent(\n dumpData: string | ReportDumpWithAttributes,\n reportPath?: string,\n appendReport?: boolean,\n withTpl = true, // whether return with report template, default = true\n): string {\n let tpl = '';\n if (withTpl) {\n tpl = getReportTpl();\n\n if (!tpl) {\n console.warn('reportTpl is not set, will not write report');\n return '';\n }\n }\n // if reportPath is set, it means we are in write to file mode\n const writeToFile = reportPath && !ifInBrowser;\n let dumpContent = '';\n\n if (typeof dumpData === 'string') {\n // do not use template string here, will cause bundle error\n dumpContent =\n // biome-ignore lint/style/useTemplate: <explanation>\n '<script type=\"midscene_web_dump\" type=\"application/json\">\\n' +\n escapeScriptTag(dumpData) +\n '\\n</script>';\n } else {\n const { dumpString, attributes } = dumpData;\n const attributesArr = Object.keys(attributes || {}).map((key) => {\n return `${key}=\"${encodeURIComponent(attributes![key])}\"`;\n });\n\n dumpContent =\n // do not use template string here, will cause bundle error\n // biome-ignore lint/style/useTemplate: <explanation>\n '<script type=\"midscene_web_dump\" type=\"application/json\" ' +\n attributesArr.join(' ') +\n '>\\n' +\n escapeScriptTag(dumpString) +\n '\\n</script>';\n }\n\n if (writeToFile) {\n if (!appendReport) {\n writeFileSync(reportPath!, tpl + dumpContent, { flag: 'w' });\n return reportPath!;\n }\n\n if (!reportInitializedMap.get(reportPath!)) {\n writeFileSync(reportPath!, tpl, { flag: 'w' });\n reportInitializedMap.set(reportPath!, true);\n }\n\n insertScriptBeforeClosingHtml(reportPath!, dumpContent);\n return reportPath!;\n }\n\n return tpl + dumpContent;\n}\n\nexport function writeDumpReport(\n fileName: string,\n dumpData: string | ReportDumpWithAttributes,\n appendReport?: boolean,\n): string | null {\n if (ifInBrowser || ifInWorker) {\n console.log('will not write report in browser');\n return null;\n }\n\n const reportPath = path.join(\n getMidsceneRunSubDir('report'),\n `${fileName}.html`,\n );\n\n reportHTMLContent(dumpData, reportPath, appendReport);\n\n if (process.env.MIDSCENE_DEBUG_LOG_JSON) {\n const jsonPath = `${reportPath}.json`;\n let data;\n\n if (typeof dumpData === 'string') {\n data = JSON.parse(dumpData) as ReportDumpWithAttributes;\n } else {\n data = dumpData;\n }\n\n writeFileSync(jsonPath, JSON.stringify(data, null, 2), {\n flag: appendReport ? 'a' : 'w',\n });\n\n logMsg(`Midscene - dump file written: ${jsonPath}`);\n }\n\n return reportPath;\n}\n\nexport function writeLogFile(opts: {\n fileName: string;\n fileExt: string;\n fileContent: string | ReportDumpWithAttributes;\n type: 'dump' | 'cache' | 'report' | 'tmp';\n generateReport?: boolean;\n appendReport?: boolean;\n}) {\n if (ifInBrowser || ifInWorker) {\n return '/mock/report.html';\n }\n const { fileName, fileExt, fileContent, type = 'dump' } = opts;\n const targetDir = getMidsceneRunSubDir(type);\n // Ensure directory exists\n if (!logEnvReady) {\n assert(targetDir, 'logDir should be set before writing dump file');\n\n // gitIgnore in the parent directory\n const gitIgnorePath = path.join(targetDir, '../../.gitignore');\n const gitPath = path.join(targetDir, '../../.git');\n let gitIgnoreContent = '';\n\n if (existsSync(gitPath)) {\n // if the git path exists, we need to add the log folder to the git ignore file\n if (existsSync(gitIgnorePath)) {\n gitIgnoreContent = readFileSync(gitIgnorePath, 'utf-8');\n }\n\n // ignore the log folder\n if (!gitIgnoreContent.includes(`${defaultRunDirName}/`)) {\n writeFileSync(\n gitIgnorePath,\n `${gitIgnoreContent}\\n# Midscene.js dump files\\n${defaultRunDirName}/dump\\n${defaultRunDirName}/report\\n${defaultRunDirName}/tmp\\n${defaultRunDirName}/log\\n`,\n 'utf-8',\n );\n }\n }\n\n logEnvReady = true;\n }\n\n const filePath = path.join(targetDir, `${fileName}.${fileExt}`);\n\n if (type !== 'dump') {\n // do not write dump file any more\n writeFileSync(filePath, JSON.stringify(fileContent));\n }\n\n if (opts?.generateReport) {\n return writeDumpReport(fileName, fileContent, opts.appendReport);\n }\n\n return filePath;\n}\n\nexport function getTmpDir(): string | null {\n try {\n const runningPkgInfo = getRunningPkgInfo();\n if (!runningPkgInfo) {\n return null;\n }\n const { name } = runningPkgInfo;\n const tmpPath = path.join(tmpdir(), name);\n mkdirSync(tmpPath, { recursive: true });\n return tmpPath;\n } catch (e) {\n return null;\n }\n}\n\nexport function getTmpFile(fileExtWithoutDot: string): string | null {\n if (ifInBrowser || ifInWorker) {\n return null;\n }\n const tmpDir = getTmpDir();\n const filename = `${uuid()}.${fileExtWithoutDot}`;\n return path.join(tmpDir!, filename);\n}\n\nexport function overlapped(container: Rect, target: Rect) {\n // container and the target have some part overlapped\n return (\n container.left < target.left + target.width &&\n container.left + container.width > target.left &&\n container.top < target.top + target.height &&\n container.top + container.height > target.top\n );\n}\n\nexport async function sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function replacerForPageObject(_key: string, value: any) {\n if (value && value.constructor?.name === 'Page') {\n return '[Page object]';\n }\n if (value && value.constructor?.name === 'Browser') {\n return '[Browser object]';\n }\n return value;\n}\n\nexport function stringifyDumpData(data: any, indents?: number) {\n return JSON.stringify(data, replacerForPageObject, indents);\n}\n\ndeclare const __VERSION__: string;\n\nexport function getVersion() {\n return __VERSION__;\n}\n\nfunction debugLog(...message: any[]) {\n // always read from process.env, and cannot be override by modelConfig, overrideAIConfig, etc.\n // also avoid circular dependency\n const debugMode = process.env[MIDSCENE_DEBUG_MODE];\n if (debugMode) {\n console.log('[Midscene]', ...message);\n }\n}\n\nlet lastReportedRepoUrl = '';\nexport function uploadTestInfoToServer({\n testUrl,\n serverUrl,\n}: { testUrl: string; serverUrl?: string }) {\n let repoUrl = '';\n let userEmail = '';\n\n try {\n repoUrl = execSync('git config --get remote.origin.url').toString().trim();\n userEmail = execSync('git config --get user.email').toString().trim();\n } catch (error) {\n debugLog('Failed to get git info:', error);\n }\n\n // Only upload test info if:\n // 1. Server URL is configured AND\n // 2. Either:\n // - We have a repo URL that's different from last reported one (to avoid duplicate reports)\n // - OR we don't have a repo URL but have a test URL (for non-git environments)\n if (\n serverUrl &&\n ((repoUrl && repoUrl !== lastReportedRepoUrl) || (!repoUrl && testUrl))\n ) {\n debugLog('Uploading test info to server', {\n serverUrl,\n repoUrl,\n testUrl,\n userEmail,\n });\n\n fetch(serverUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n repo_url: repoUrl,\n test_url: testUrl,\n user_email: userEmail,\n }),\n })\n .then((response) => response.json())\n .then((data) => {\n debugLog('Successfully uploaded test info to server:', data);\n })\n .catch((error) =>\n debugLog('Failed to upload test info to server:', error),\n );\n lastReportedRepoUrl = repoUrl;\n }\n}\n"],"names":["logEnvReady","groupedActionDumpFileExt","processCacheConfig","cache","cacheId","undefined","envEnabled","globalConfigManager","MIDSCENE_CACHE","reportInitializedMap","Map","getReportTpl","reportTpl","insertScriptBeforeClosingHtml","filePath","scriptContent","htmlEndTag","stat","fs","readSize","Math","start","buffer","Buffer","fd","tailStr","htmlEndIdx","Error","beforeHtmlInTail","htmlEndPos","reportHTMLContent","dumpData","reportPath","appendReport","withTpl","tpl","console","writeToFile","ifInBrowser","dumpContent","escapeScriptTag","dumpString","attributes","attributesArr","Object","key","encodeURIComponent","writeFileSync","writeDumpReport","fileName","ifInWorker","path","getMidsceneRunSubDir","process","jsonPath","data","JSON","logMsg","writeLogFile","opts","fileExt","fileContent","type","targetDir","assert","gitIgnorePath","gitPath","gitIgnoreContent","existsSync","readFileSync","defaultRunDirName","getTmpDir","runningPkgInfo","getRunningPkgInfo","name","tmpPath","tmpdir","mkdirSync","e","getTmpFile","fileExtWithoutDot","tmpDir","filename","uuid","overlapped","container","target","sleep","ms","Promise","resolve","setTimeout","replacerForPageObject","_key","value","_value_constructor","_value_constructor1","stringifyDumpData","indents","getVersion","__VERSION__","debugLog","message","debugMode","MIDSCENE_DEBUG_MODE","lastReportedRepoUrl","uploadTestInfoToServer","testUrl","serverUrl","repoUrl","userEmail","execSync","error","fetch","response"],"mappings":"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"}
@@ -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 ('aiAct' in flowItem || 'aiAction' in flowItem || 'ai' in flowItem) {
73
+ if ('aiAction' in flowItem || 'ai' in flowItem) {
74
74
  const actionTask = flowItem;
75
- const prompt = actionTask.aiAct || actionTask.aiAction || actionTask.ai;
76
- assert(prompt, 'missing prompt for ai (aiAct)');
77
- await agent.aiAct(prompt, {
75
+ const prompt = actionTask.aiAction || actionTask.ai;
76
+ assert(prompt, 'missing prompt for ai (aiAction)');
77
+ await agent.aiAction(prompt, {
78
78
  cacheable: actionTask.cacheable
79
79
  });
80
80
  } else if ('aiAssert' in flowItem) {
@@ -162,12 +162,10 @@ 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 || '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
165
+ } else if ('logScreenshot' in flowItem) {
166
+ const logScreenshotTask = flowItem;
167
+ await agent.logScreenshot(logScreenshotTask.logScreenshot, {
168
+ content: logScreenshotTask.content || ''
171
169
  });
172
170
  } else if ('aiInput' in flowItem) {
173
171
  const { aiInput, ...inputTask } = flowItem;
@@ -183,7 +181,7 @@ class ScriptPlayer {
183
181
  await agent.callActionInActionSpace('Input', {
184
182
  ...inputTask,
185
183
  ...void 0 !== value ? {
186
- value
184
+ value: String(value)
187
185
  } : {},
188
186
  ...locatePrompt ? {
189
187
  locate: buildDetailedLocateParam(locatePrompt, inputTask)
@@ -236,11 +234,9 @@ class ScriptPlayer {
236
234
  return false;
237
235
  });
238
236
  assert(matchedAction, `unknown flowItem in yaml: ${JSON.stringify(flowItem)}`);
239
- const flowItemForProcessing = locatePromptShortcut ? {
240
- ...flowItem,
241
- prompt: locatePromptShortcut
242
- } : flowItem;
243
- const { locateParam, restParams } = buildDetailedLocateParamAndRestParams(locatePromptShortcut || '', flowItemForProcessing, [
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, [
244
240
  matchedAction.name,
245
241
  matchedAction.interfaceAlias || '_never_mind_'
246
242
  ]);
@@ -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; // 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, ...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 }\n // New format - 2: { aiInput: undefined, locate: TUserPrompt, value: string }\n let locatePrompt: TUserPrompt | undefined;\n let value: string | 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 } : {}),\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","inputTask","locatePrompt","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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"}
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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"}
@@ -271,7 +271,7 @@ class Agent {
271
271
  value
272
272
  };
273
273
  }
274
- (0, utils_namespaceObject.assert)('string' == typeof value, 'input value must be a string, use empty string if you want to clear the input');
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
277
  return this.callActionInActionSpace('Input', {
@@ -322,7 +322,7 @@ class Agent {
322
322
  locate: detailedLocateParam
323
323
  });
324
324
  }
325
- async aiAct(taskPrompt, opt) {
325
+ async aiAction(taskPrompt, opt) {
326
326
  var _this_taskCache, _this_taskCache1;
327
327
  const modelConfig = this.modelConfigManager.getModelConfig('planning');
328
328
  const cacheable = null == opt ? void 0 : opt.cacheable;
@@ -356,9 +356,6 @@ class Agent {
356
356
  await this.afterTaskRunning(executor);
357
357
  return output;
358
358
  }
359
- async aiAction(taskPrompt, opt) {
360
- return this.aiAct(taskPrompt, opt);
361
- }
362
359
  async aiQuery(demand, opt = defaultInsightExtractOption) {
363
360
  const modelConfig = this.modelConfigManager.getModelConfig('VQA');
364
361
  const { output, executor } = await this.taskExecutor.createTypeQueryExecution('Query', demand, modelConfig, opt);
@@ -486,7 +483,7 @@ class Agent {
486
483
  }
487
484
  }
488
485
  async ai(taskPrompt, type = 'action') {
489
- if ('action' === type) return this.aiAct(taskPrompt);
486
+ if ('action' === type) return this.aiAction(taskPrompt);
490
487
  if ('query' === type) return this.aiQuery(taskPrompt);
491
488
  if ('assert' === type) return this.aiAssert(taskPrompt);
492
489
  if ('tap' === type) return this.aiTap(taskPrompt);
@@ -523,7 +520,7 @@ class Agent {
523
520
  this.resetDump();
524
521
  this.destroyed = true;
525
522
  }
526
- async recordToReport(title, opt) {
523
+ async logScreenshot(title, opt) {
527
524
  const base64 = await this.interface.screenshotBase64();
528
525
  const now = Date.now();
529
526
  const recorder = [
@@ -566,9 +563,6 @@ class Agent {
566
563
  }
567
564
  this.writeOutActionDumps();
568
565
  }
569
- async logScreenshot(title, opt) {
570
- await this.recordToReport(title, opt);
571
- }
572
566
  _unstableLogContent() {
573
567
  const { groupName, groupDescription, executions } = this.dump;
574
568
  const newExecutions = Array.isArray(executions) ? executions.map((execution)=>{
@@ -606,7 +600,7 @@ class Agent {
606
600
  processCacheConfig(opts) {
607
601
  if (true === opts.cache) throw new Error('cache: true requires an explicit cache ID. Please provide:\nExample: cache: { id: "my-cache-id" }');
608
602
  if (opts.cache && 'object' == typeof opts.cache && null !== opts.cache && !opts.cache.id) throw new Error('cache configuration requires an explicit id.\nExample: cache: { id: "my-cache-id" }');
609
- const cacheConfig = (0, external_utils_js_namespaceObject.processCacheConfig)(opts.cache, opts.testId || 'default', opts.cacheId);
603
+ const cacheConfig = (0, external_utils_js_namespaceObject.processCacheConfig)(opts.cache, opts.cacheId || opts.testId || 'default');
610
604
  if (!cacheConfig) return null;
611
605
  if ('object' == typeof cacheConfig && null !== cacheConfig) {
612
606
  const id = cacheConfig.id;