@midscene/core 0.26.7-beta-20250818035341.0 → 0.26.7-beta-20250820105545.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 (78) hide show
  1. package/dist/es/ai-model/action-executor.mjs +0 -8
  2. package/dist/es/ai-model/action-executor.mjs.map +1 -1
  3. package/dist/es/ai-model/common.mjs +73 -52
  4. package/dist/es/ai-model/common.mjs.map +1 -1
  5. package/dist/es/ai-model/index.mjs +3 -3
  6. package/dist/es/ai-model/inspect.mjs +29 -66
  7. package/dist/es/ai-model/inspect.mjs.map +1 -1
  8. package/dist/es/ai-model/llm-planning.mjs +27 -24
  9. package/dist/es/ai-model/llm-planning.mjs.map +1 -1
  10. package/dist/es/ai-model/prompt/assertion.mjs +1 -25
  11. package/dist/es/ai-model/prompt/assertion.mjs.map +1 -1
  12. package/dist/es/ai-model/prompt/llm-planning.mjs +50 -23
  13. package/dist/es/ai-model/prompt/llm-planning.mjs.map +1 -1
  14. package/dist/es/ai-model/prompt/playwright-generator.mjs +9 -3
  15. package/dist/es/ai-model/prompt/playwright-generator.mjs.map +1 -1
  16. package/dist/es/ai-model/prompt/util.mjs +2 -2
  17. package/dist/es/ai-model/prompt/util.mjs.map +1 -1
  18. package/dist/es/ai-model/prompt/yaml-generator.mjs +9 -3
  19. package/dist/es/ai-model/prompt/yaml-generator.mjs.map +1 -1
  20. package/dist/es/ai-model/service-caller/index.mjs +75 -118
  21. package/dist/es/ai-model/service-caller/index.mjs.map +1 -1
  22. package/dist/es/ai-model/ui-tars-planning.mjs +5 -5
  23. package/dist/es/ai-model/ui-tars-planning.mjs.map +1 -1
  24. package/dist/es/index.mjs +3 -2
  25. package/dist/es/index.mjs.map +1 -1
  26. package/dist/es/insight/index.mjs +14 -97
  27. package/dist/es/insight/index.mjs.map +1 -1
  28. package/dist/es/insight/utils.mjs +1 -3
  29. package/dist/es/insight/utils.mjs.map +1 -1
  30. package/dist/es/types.mjs.map +1 -1
  31. package/dist/es/utils.mjs +5 -6
  32. package/dist/es/utils.mjs.map +1 -1
  33. package/dist/lib/ai-model/action-executor.js +0 -8
  34. package/dist/lib/ai-model/action-executor.js.map +1 -1
  35. package/dist/lib/ai-model/common.js +97 -55
  36. package/dist/lib/ai-model/common.js.map +1 -1
  37. package/dist/lib/ai-model/index.js +16 -4
  38. package/dist/lib/ai-model/inspect.js +29 -69
  39. package/dist/lib/ai-model/inspect.js.map +1 -1
  40. package/dist/lib/ai-model/llm-planning.js +26 -23
  41. package/dist/lib/ai-model/llm-planning.js.map +1 -1
  42. package/dist/lib/ai-model/prompt/assertion.js +2 -29
  43. package/dist/lib/ai-model/prompt/assertion.js.map +1 -1
  44. package/dist/lib/ai-model/prompt/llm-planning.js +52 -25
  45. package/dist/lib/ai-model/prompt/llm-planning.js.map +1 -1
  46. package/dist/lib/ai-model/prompt/playwright-generator.js +9 -3
  47. package/dist/lib/ai-model/prompt/playwright-generator.js.map +1 -1
  48. package/dist/lib/ai-model/prompt/util.js +2 -2
  49. package/dist/lib/ai-model/prompt/util.js.map +1 -1
  50. package/dist/lib/ai-model/prompt/yaml-generator.js +9 -3
  51. package/dist/lib/ai-model/prompt/yaml-generator.js.map +1 -1
  52. package/dist/lib/ai-model/service-caller/index.js +78 -124
  53. package/dist/lib/ai-model/service-caller/index.js.map +1 -1
  54. package/dist/lib/ai-model/ui-tars-planning.js +5 -5
  55. package/dist/lib/ai-model/ui-tars-planning.js.map +1 -1
  56. package/dist/lib/index.js +20 -7
  57. package/dist/lib/index.js.map +1 -1
  58. package/dist/lib/insight/index.js +10 -93
  59. package/dist/lib/insight/index.js.map +1 -1
  60. package/dist/lib/insight/utils.js +1 -3
  61. package/dist/lib/insight/utils.js.map +1 -1
  62. package/dist/lib/types.js.map +1 -1
  63. package/dist/lib/utils.js +4 -5
  64. package/dist/lib/utils.js.map +1 -1
  65. package/dist/types/ai-model/common.d.ts +162 -8
  66. package/dist/types/ai-model/index.d.ts +2 -1
  67. package/dist/types/ai-model/inspect.d.ts +3 -8
  68. package/dist/types/ai-model/llm-planning.d.ts +1 -1
  69. package/dist/types/ai-model/prompt/assertion.d.ts +0 -3
  70. package/dist/types/ai-model/prompt/llm-planning.d.ts +2 -2
  71. package/dist/types/ai-model/prompt/util.d.ts +2 -1
  72. package/dist/types/ai-model/service-caller/index.d.ts +6 -6
  73. package/dist/types/ai-model/ui-tars-planning.d.ts +3 -1
  74. package/dist/types/index.d.ts +3 -1
  75. package/dist/types/insight/index.d.ts +1 -5
  76. package/dist/types/types.d.ts +11 -12
  77. package/dist/types/yaml.d.ts +7 -6
  78. package/package.json +4 -3
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["webpack://@midscene/core/webpack/runtime/define_property_getters","webpack://@midscene/core/webpack/runtime/has_own_property","webpack://@midscene/core/webpack/runtime/make_namespace_object","webpack://@midscene/core/./src/utils.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 { 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_DEBUG_MODE,\n MIDSCENE_OPENAI_INIT_CONFIG_JSON,\n getAIConfig,\n getAIConfigInJson,\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 { Rect, ReportDumpWithAttributes } from './types';\n\nlet logEnvReady = false;\n\nexport const groupedActionDumpFileExt = 'web-dump.json';\n\nconst reportInitializedMap = new Map<string, boolean>();\n\ndeclare const __DEV_REPORT_PATH__: string;\n\nfunction getReportTpl() {\n if (__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): string {\n const 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;\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, 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 const debugMode = getAIConfig(MIDSCENE_DEBUG_MODE);\n if (debugMode) {\n console.log('[Midscene]', ...message);\n }\n}\n\nlet lastReportedRepoUrl = '';\nexport function uploadTestInfoToServer({ testUrl }: { testUrl: string }) {\n let repoUrl = '';\n let userEmail = '';\n\n const extraConfig = getAIConfigInJson(MIDSCENE_OPENAI_INIT_CONFIG_JSON);\n const serverUrl = extraConfig?.REPORT_SERVER_URL;\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":["__webpack_require__","definition","key","Object","obj","prop","Symbol","logEnvReady","groupedActionDumpFileExt","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","tpl","console","writeToFile","ifInBrowser","dumpContent","escapeScriptTag","dumpString","attributes","attributesArr","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","value","_value_constructor","_value_constructor1","stringifyDumpData","indents","getVersion","__VERSION__","debugLog","message","debugMode","getAIConfig","MIDSCENE_DEBUG_MODE","lastReportedRepoUrl","uploadTestInfoToServer","testUrl","repoUrl","userEmail","extraConfig","getAIConfigInJson","MIDSCENE_OPENAI_INIT_CONFIG_JSON","serverUrl","execSync","error","fetch","response"],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sources":["webpack://@midscene/core/webpack/runtime/define_property_getters","webpack://@midscene/core/webpack/runtime/has_own_property","webpack://@midscene/core/webpack/runtime/make_namespace_object","webpack://@midscene/core/./src/utils.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 { 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_DEBUG_MODE,\n getUploadTestServerUrl,\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 { Rect, ReportDumpWithAttributes } from './types';\n\nlet logEnvReady = false;\n\nexport const groupedActionDumpFileExt = 'web-dump.json';\n\nconst reportInitializedMap = new Map<string, boolean>();\n\ndeclare const __DEV_REPORT_PATH__: string;\n\nfunction getReportTpl() {\n if (__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): string {\n const 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;\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, 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 const debugMode = process.env[MIDSCENE_DEBUG_MODE];\n if (debugMode) {\n console.log('[Midscene]', ...message);\n }\n}\n\nlet lastReportedRepoUrl = '';\nexport function uploadTestInfoToServer({ testUrl }: { testUrl: string }) {\n let repoUrl = '';\n let userEmail = '';\n\n const serverUrl = getUploadTestServerUrl();\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":["__webpack_require__","definition","key","Object","obj","prop","Symbol","logEnvReady","groupedActionDumpFileExt","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","tpl","console","writeToFile","ifInBrowser","dumpContent","escapeScriptTag","dumpString","attributes","attributesArr","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","value","_value_constructor","_value_constructor1","stringifyDumpData","indents","getVersion","__VERSION__","debugLog","message","debugMode","MIDSCENE_DEBUG_MODE","lastReportedRepoUrl","uploadTestInfoToServer","testUrl","repoUrl","userEmail","serverUrl","getUploadTestServerUrl","execSync","error","fetch","response"],"mappings":"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"}
@@ -1,6 +1,8 @@
1
- import type { AIUsageInfo, BaseElement, ElementTreeNode, MidsceneYamlFlowItem, PlanningAction, Rect, Size } from '../types';
1
+ import type { AIUsageInfo, BaseElement, DeviceAction, ElementTreeNode, MidsceneYamlFlowItem, PlanningAction, Rect, Size } from '../types';
2
2
  import type { ChatCompletionSystemMessageParam, ChatCompletionUserMessageParam } from 'openai/resources/index';
3
3
  import type { PlanningLocateParam } from '../types';
4
+ import { type IModelPreferences } from '@midscene/shared/env';
5
+ import { z } from 'zod';
4
6
  export type AIArgs = [
5
7
  ChatCompletionSystemMessageParam,
6
8
  ...ChatCompletionUserMessageParam[]
@@ -12,23 +14,175 @@ export declare enum AIActionType {
12
14
  PLAN = 3,
13
15
  DESCRIBE_ELEMENT = 4
14
16
  }
15
- export declare function callAiFn<T>(msgs: AIArgs, AIActionTypeValue: AIActionType): Promise<{
17
+ export declare const actionSpaceTypePrefix = "action_space_";
18
+ export declare function callAiFn<T>(msgs: AIArgs, AIActionTypeValue: AIActionType, modelPreferences: IModelPreferences): Promise<{
16
19
  content: T;
17
20
  usage?: AIUsageInfo;
18
21
  }>;
19
- export declare function fillBboxParam(locate: PlanningLocateParam, width: number, height: number): PlanningLocateParam;
22
+ export declare function fillBboxParam(locate: PlanningLocateParam, width: number, height: number, modelPreferences: IModelPreferences): PlanningLocateParam;
20
23
  export declare function adaptQwenBbox(bbox: number[]): [number, number, number, number];
21
24
  export declare function adaptDoubaoBbox(bbox: string[] | number[] | string, width: number, height: number): [number, number, number, number];
22
- export declare function adaptBbox(bbox: number[], width: number, height: number): [number, number, number, number];
25
+ export declare function adaptBbox(bbox: number[], width: number, height: number, modelPreferences: IModelPreferences): [number, number, number, number];
23
26
  export declare function adaptGeminiBbox(bbox: number[], width: number, height: number): [number, number, number, number];
24
- export declare function adaptBboxToRect(bbox: number[], width: number, height: number, offsetX?: number, offsetY?: number): Rect;
25
- export declare function warnGPT4oSizeLimit(size: Size): void;
27
+ export declare function adaptBboxToRect(bbox: number[], width: number, height: number, modelPreferences: IModelPreferences, offsetX?: number, offsetY?: number): Rect;
28
+ export declare function warnGPT4oSizeLimit(size: Size, modelPreferences: IModelPreferences): void;
26
29
  export declare function mergeRects(rects: Rect[]): {
27
30
  left: number;
28
31
  top: number;
29
32
  width: number;
30
33
  height: number;
31
34
  };
32
- export declare function expandSearchArea(rect: Rect, screenSize: Size): Rect;
35
+ export declare function expandSearchArea(rect: Rect, screenSize: Size, modelPreferences: IModelPreferences): Rect;
33
36
  export declare function markupImageForLLM(screenshotBase64: string, tree: ElementTreeNode<BaseElement>, size: Size): Promise<string>;
34
- export declare function buildYamlFlowFromPlans(plans: PlanningAction[], sleep?: number): MidsceneYamlFlowItem[];
37
+ export declare function buildYamlFlowFromPlans(plans: PlanningAction[], actionSpace: DeviceAction<any>[], sleep?: number): MidsceneYamlFlowItem[];
38
+ export declare const PointSchema: z.ZodObject<{
39
+ left: z.ZodNumber;
40
+ top: z.ZodNumber;
41
+ }, "strip", z.ZodTypeAny, {
42
+ left: number;
43
+ top: number;
44
+ }, {
45
+ left: number;
46
+ top: number;
47
+ }>;
48
+ export declare const SizeSchema: z.ZodObject<{
49
+ width: z.ZodNumber;
50
+ height: z.ZodNumber;
51
+ dpr: z.ZodOptional<z.ZodNumber>;
52
+ }, "strip", z.ZodTypeAny, {
53
+ width: number;
54
+ height: number;
55
+ dpr?: number | undefined;
56
+ }, {
57
+ width: number;
58
+ height: number;
59
+ dpr?: number | undefined;
60
+ }>;
61
+ export declare const RectSchema: z.ZodIntersection<z.ZodIntersection<z.ZodObject<{
62
+ left: z.ZodNumber;
63
+ top: z.ZodNumber;
64
+ }, "strip", z.ZodTypeAny, {
65
+ left: number;
66
+ top: number;
67
+ }, {
68
+ left: number;
69
+ top: number;
70
+ }>, z.ZodObject<{
71
+ width: z.ZodNumber;
72
+ height: z.ZodNumber;
73
+ dpr: z.ZodOptional<z.ZodNumber>;
74
+ }, "strip", z.ZodTypeAny, {
75
+ width: number;
76
+ height: number;
77
+ dpr?: number | undefined;
78
+ }, {
79
+ width: number;
80
+ height: number;
81
+ dpr?: number | undefined;
82
+ }>>, z.ZodObject<{
83
+ zoom: z.ZodOptional<z.ZodNumber>;
84
+ }, "strip", z.ZodTypeAny, {
85
+ zoom?: number | undefined;
86
+ }, {
87
+ zoom?: number | undefined;
88
+ }>>;
89
+ export declare const MidsceneLocation: z.ZodObject<{
90
+ midscene_location_field_flag: z.ZodLiteral<true>;
91
+ prompt: z.ZodString;
92
+ center: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
93
+ rect: z.ZodIntersection<z.ZodIntersection<z.ZodObject<{
94
+ left: z.ZodNumber;
95
+ top: z.ZodNumber;
96
+ }, "strip", z.ZodTypeAny, {
97
+ left: number;
98
+ top: number;
99
+ }, {
100
+ left: number;
101
+ top: number;
102
+ }>, z.ZodObject<{
103
+ width: z.ZodNumber;
104
+ height: z.ZodNumber;
105
+ dpr: z.ZodOptional<z.ZodNumber>;
106
+ }, "strip", z.ZodTypeAny, {
107
+ width: number;
108
+ height: number;
109
+ dpr?: number | undefined;
110
+ }, {
111
+ width: number;
112
+ height: number;
113
+ dpr?: number | undefined;
114
+ }>>, z.ZodObject<{
115
+ zoom: z.ZodOptional<z.ZodNumber>;
116
+ }, "strip", z.ZodTypeAny, {
117
+ zoom?: number | undefined;
118
+ }, {
119
+ zoom?: number | undefined;
120
+ }>>;
121
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
122
+ midscene_location_field_flag: z.ZodLiteral<true>;
123
+ prompt: z.ZodString;
124
+ center: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
125
+ rect: z.ZodIntersection<z.ZodIntersection<z.ZodObject<{
126
+ left: z.ZodNumber;
127
+ top: z.ZodNumber;
128
+ }, "strip", z.ZodTypeAny, {
129
+ left: number;
130
+ top: number;
131
+ }, {
132
+ left: number;
133
+ top: number;
134
+ }>, z.ZodObject<{
135
+ width: z.ZodNumber;
136
+ height: z.ZodNumber;
137
+ dpr: z.ZodOptional<z.ZodNumber>;
138
+ }, "strip", z.ZodTypeAny, {
139
+ width: number;
140
+ height: number;
141
+ dpr?: number | undefined;
142
+ }, {
143
+ width: number;
144
+ height: number;
145
+ dpr?: number | undefined;
146
+ }>>, z.ZodObject<{
147
+ zoom: z.ZodOptional<z.ZodNumber>;
148
+ }, "strip", z.ZodTypeAny, {
149
+ zoom?: number | undefined;
150
+ }, {
151
+ zoom?: number | undefined;
152
+ }>>;
153
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
154
+ midscene_location_field_flag: z.ZodLiteral<true>;
155
+ prompt: z.ZodString;
156
+ center: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
157
+ rect: z.ZodIntersection<z.ZodIntersection<z.ZodObject<{
158
+ left: z.ZodNumber;
159
+ top: z.ZodNumber;
160
+ }, "strip", z.ZodTypeAny, {
161
+ left: number;
162
+ top: number;
163
+ }, {
164
+ left: number;
165
+ top: number;
166
+ }>, z.ZodObject<{
167
+ width: z.ZodNumber;
168
+ height: z.ZodNumber;
169
+ dpr: z.ZodOptional<z.ZodNumber>;
170
+ }, "strip", z.ZodTypeAny, {
171
+ width: number;
172
+ height: number;
173
+ dpr?: number | undefined;
174
+ }, {
175
+ width: number;
176
+ height: number;
177
+ dpr?: number | undefined;
178
+ }>>, z.ZodObject<{
179
+ zoom: z.ZodOptional<z.ZodNumber>;
180
+ }, "strip", z.ZodTypeAny, {
181
+ zoom?: number | undefined;
182
+ }, {
183
+ zoom?: number | undefined;
184
+ }>>;
185
+ }, z.ZodTypeAny, "passthrough">>;
186
+ export type MidsceneLocationType = z.infer<typeof MidsceneLocation>;
187
+ export declare const ifMidsceneLocatorField: (field: any) => boolean;
188
+ export declare const findAllMidsceneLocatorField: (zodType?: z.ZodType<any>) => string[];
@@ -4,8 +4,9 @@ export { describeUserPage, elementByPositionWithElementInfo, } from './prompt/ut
4
4
  export { generatePlaywrightTest, generatePlaywrightTestStream, } from './prompt/playwright-generator';
5
5
  export { generateYamlTest, generateYamlTestStream, } from './prompt/yaml-generator';
6
6
  export type { ChatCompletionMessageParam } from 'openai/resources/index';
7
- export { AiLocateElement, AiExtractElementInfo, AiAssert, AiLocateSection, } from './inspect';
7
+ export { AiLocateElement, AiExtractElementInfo, AiLocateSection, } from './inspect';
8
8
  export { plan } from './llm-planning';
9
9
  export { callAiFn, adaptBboxToRect, } from './common';
10
10
  export { vlmPlanning, resizeImageForUiTars } from './ui-tars-planning';
11
11
  export { AIActionType, type AIArgs } from './common';
12
+ export { actionSpaceTypePrefix, MidsceneLocation, type MidsceneLocationType, PointSchema, SizeSchema, RectSchema, } from './common';
@@ -1,4 +1,5 @@
1
- import type { AIAssertionResponse, AIDataExtractionResponse, AIElementLocatorResponse, AIElementResponse, AISectionLocatorResponse, AIUsageInfo, BaseElement, ElementById, InsightExtractOption, Rect, ReferenceImage, TMultimodalPrompt, TUserPrompt, UIContext } from '../types';
1
+ import type { AIDataExtractionResponse, AIElementLocatorResponse, AIElementResponse, AISectionLocatorResponse, AIUsageInfo, BaseElement, ElementById, InsightExtractOption, Rect, ReferenceImage, TMultimodalPrompt, TUserPrompt, UIContext } from '../types';
2
+ import { type IModelPreferences } from '@midscene/shared/env';
2
3
  import type { ChatCompletionSystemMessageParam, ChatCompletionUserMessageParam } from 'openai/resources/index';
3
4
  import { callAiFn } from './common';
4
5
  export type AIArgs = [
@@ -35,15 +36,9 @@ export declare function AiExtractElementInfo<T, ElementType extends BaseElement
35
36
  multimodalPrompt?: TMultimodalPrompt;
36
37
  context: UIContext<ElementType>;
37
38
  extractOption?: InsightExtractOption;
39
+ modelPreferences: IModelPreferences;
38
40
  }): Promise<{
39
41
  parseResult: AIDataExtractionResponse<T>;
40
42
  elementById: (idOrIndexId: string) => ElementType;
41
43
  usage: AIUsageInfo | undefined;
42
44
  }>;
43
- export declare function AiAssert<ElementType extends BaseElement = BaseElement>(options: {
44
- assertion: TUserPrompt;
45
- context: UIContext<ElementType>;
46
- }): Promise<{
47
- content: AIAssertionResponse;
48
- usage: AIUsageInfo | undefined;
49
- }>;
@@ -3,7 +3,7 @@ import { callAiFn } from './common';
3
3
  export declare function plan(userInstruction: string, opts: {
4
4
  context: UIContext;
5
5
  pageType: PageType;
6
- actionSpace: DeviceAction[];
6
+ actionSpace: DeviceAction<any>[];
7
7
  callAI?: typeof callAiFn<PlanningAIResponse>;
8
8
  log?: string;
9
9
  actionContext?: string;
@@ -1,5 +1,2 @@
1
1
  import type { ResponseFormatJSONSchema } from 'openai/resources/index';
2
- export declare function systemPromptToAssert(model: {
3
- isUITars: boolean;
4
- }): string;
5
2
  export declare const assertSchema: ResponseFormatJSONSchema;
@@ -2,9 +2,9 @@ import type { DeviceAction } from '../../types';
2
2
  import { PromptTemplate } from '@langchain/core/prompts';
3
3
  import type { vlLocateMode } from '@midscene/shared/env';
4
4
  import type { ResponseFormatJSONSchema } from 'openai/resources/index';
5
- export declare const descriptionForAction: (action: DeviceAction, locatorScheme: string) => string;
5
+ export declare const descriptionForAction: (action: DeviceAction<any>, locatorSchemaTypeDescription: string) => string;
6
6
  export declare function systemPromptToTaskPlanning({ actionSpace, vlMode, }: {
7
- actionSpace: DeviceAction[];
7
+ actionSpace: DeviceAction<any>[];
8
8
  vlMode: ReturnType<typeof vlLocateMode>;
9
9
  }): Promise<string>;
10
10
  export declare const planSchema: ResponseFormatJSONSchema;
@@ -1,4 +1,5 @@
1
1
  import type { BaseElement, ElementTreeNode, Size, UIContext } from '../../types';
2
+ import { type IModelPreferences } from '@midscene/shared/env';
2
3
  export declare function describeSize(size: Size): string;
3
4
  export declare function describeElement(elements: (Pick<BaseElement, 'rect' | 'content'> & {
4
5
  id: string;
@@ -19,7 +20,7 @@ export declare function distance(point1: {
19
20
  y: number;
20
21
  }): number;
21
22
  export declare const samplePageDescription = "\nAnd the page is described as follows:\n====================\nThe size of the page: 1280 x 720\nSome of the elements are marked with a rectangle in the screenshot corresponding to the markerId, some are not.\n\nDescription of all the elements in screenshot:\n<div id=\"969f1637\" markerId=\"1\" left=\"100\" top=\"100\" width=\"100\" height=\"100\"> // The markerId indicated by the rectangle label in the screenshot\n <h4 id=\"b211ecb2\" markerId=\"5\" left=\"150\" top=\"150\" width=\"90\" height=\"60\">\n The username is accepted\n </h4>\n ...many more\n</div>\n====================\n";
22
- export declare function describeUserPage<ElementType extends BaseElement = BaseElement>(context: Omit<UIContext<ElementType>, 'describer'>, opt?: {
23
+ export declare function describeUserPage<ElementType extends BaseElement = BaseElement>(context: Omit<UIContext<ElementType>, 'describer'>, modelPreferences: IModelPreferences, opt?: {
23
24
  truncateTextLength?: number;
24
25
  filterNonTextContent?: boolean;
25
26
  domIncluded?: boolean | 'visible-only';
@@ -1,11 +1,10 @@
1
1
  import { type AIUsageInfo } from '../../types';
2
2
  import type { StreamingCallback } from '../../types';
3
+ import { type IModelPreferences } from '@midscene/shared/env';
3
4
  import OpenAI from 'openai';
4
5
  import type { ChatCompletionMessageParam } from 'openai/resources/index';
5
6
  import { AIActionType, type AIArgs } from '../common';
6
- export declare function checkAIConfig(): boolean;
7
- export declare function getModelName(): string;
8
- export declare function call(messages: ChatCompletionMessageParam[], AIActionTypeValue: AIActionType, responseFormat?: OpenAI.ChatCompletionCreateParams['response_format'] | OpenAI.ResponseFormatJSONObject, options?: {
7
+ export declare function call(messages: ChatCompletionMessageParam[], AIActionTypeValue: AIActionType, modelPreferences: IModelPreferences, options?: {
9
8
  stream?: boolean;
10
9
  onChunk?: StreamingCallback;
11
10
  }): Promise<{
@@ -13,14 +12,15 @@ export declare function call(messages: ChatCompletionMessageParam[], AIActionTyp
13
12
  usage?: AIUsageInfo;
14
13
  isStreamed: boolean;
15
14
  }>;
16
- export declare function callToGetJSONObject<T>(messages: ChatCompletionMessageParam[], AIActionTypeValue: AIActionType): Promise<{
15
+ export declare const getResponseFormat: (modelName: string, AIActionTypeValue: AIActionType) => OpenAI.ChatCompletionCreateParams["response_format"] | OpenAI.ResponseFormatJSONObject;
16
+ export declare function callToGetJSONObject<T>(messages: ChatCompletionMessageParam[], AIActionTypeValue: AIActionType, modelPreferences: IModelPreferences): Promise<{
17
17
  content: T;
18
18
  usage?: AIUsageInfo;
19
19
  }>;
20
- export declare function callAiFnWithStringResponse<T>(msgs: AIArgs, AIActionTypeValue: AIActionType): Promise<{
20
+ export declare function callAiFnWithStringResponse<T>(msgs: AIArgs, AIActionTypeValue: AIActionType, modelPreferences: IModelPreferences): Promise<{
21
21
  content: string;
22
22
  usage?: AIUsageInfo;
23
23
  }>;
24
24
  export declare function extractJSONFromCodeBlock(response: string): string;
25
25
  export declare function preprocessDoubaoBboxJson(input: string): string;
26
- export declare function safeParseJson(input: string): any;
26
+ export declare function safeParseJson(input: string, modelPreferences: IModelPreferences): any;
@@ -1,4 +1,5 @@
1
1
  import type { AIUsageInfo, MidsceneYamlFlowItem, PlanningAction, Size } from '../types';
2
+ import { type IModelPreferences } from '@midscene/shared/env';
2
3
  import { actionParser } from '@ui-tars/action-parser';
3
4
  import type { ChatCompletionMessageParam } from 'openai/resources/index';
4
5
  type ActionType = 'click' | 'drag' | 'type' | 'hotkey' | 'finished' | 'scroll' | 'wait' | 'androidBackButton' | 'androidHomeButton' | 'androidRecentAppsButton' | 'androidLongPress' | 'androidPull';
@@ -9,6 +10,7 @@ export declare function vlmPlanning(options: {
9
10
  width: number;
10
11
  height: number;
11
12
  };
13
+ modelPreferences: IModelPreferences;
12
14
  }): Promise<{
13
15
  actions: PlanningAction<any>[];
14
16
  actionsFromModel: ReturnType<typeof actionParser>['parsed'];
@@ -72,5 +74,5 @@ interface AndroidLongPressAction extends BaseAction {
72
74
  };
73
75
  }
74
76
  export type Action = ClickAction | DragAction | TypeAction | HotkeyAction | ScrollAction | FinishedAction | WaitAction | AndroidLongPressAction;
75
- export declare function resizeImageForUiTars(imageBase64: string, size: Size): Promise<string>;
77
+ export declare function resizeImageForUiTars(imageBase64: string, size: Size, modelPreferences: IModelPreferences): Promise<string>;
76
78
  export {};
@@ -1,9 +1,11 @@
1
+ import { z } from 'zod';
1
2
  import { Executor } from './ai-model/action-executor';
2
3
  import Insight from './insight/index';
3
4
  import { getVersion } from './utils';
4
- export { plan, describeUserPage, AiLocateElement, AiAssert, } from './ai-model/index';
5
+ export { plan, describeUserPage, AiLocateElement, MidsceneLocation, type MidsceneLocationType, PointSchema, SizeSchema, RectSchema, } from './ai-model/index';
5
6
  export { getAIConfig, MIDSCENE_MODEL_NAME } from '@midscene/shared/env';
6
7
  export type * from './types';
8
+ export { z };
7
9
  export default Insight;
8
10
  export { Executor, Insight, getVersion };
9
11
  export type { MidsceneYamlScript, MidsceneYamlTask, MidsceneYamlFlowItem, MidsceneYamlFlowItemAIRightClick, MidsceneYamlConfigResult, LocateOption, DetailedLocateParam, } from './yaml';
@@ -1,5 +1,5 @@
1
1
  import { callAiFn } from '../ai-model/common';
2
- import type { AIDescribeElementResponse, AIElementResponse, AIUsageInfo, BaseElement, DetailedLocateParam, DumpSubscriber, InsightAction, InsightAssertionResponse, InsightExtractOption, InsightExtractParam, InsightOptions, InsightTaskInfo, LocateResult, Rect, TMultimodalPrompt, TUserPrompt, UIContext } from '../types';
2
+ import type { AIElementResponse, AIUsageInfo, BaseElement, DetailedLocateParam, DumpSubscriber, InsightAction, InsightExtractOption, InsightExtractParam, InsightOptions, InsightTaskInfo, LocateResult, TMultimodalPrompt, UIContext } from '../types';
3
3
  export interface LocateOpts {
4
4
  context?: UIContext<BaseElement>;
5
5
  callAI?: typeof callAiFn<AIElementResponse>;
@@ -19,8 +19,4 @@ export default class Insight<ElementType extends BaseElement = BaseElement, Cont
19
19
  thought?: string;
20
20
  usage?: AIUsageInfo;
21
21
  }>;
22
- assert(assertion: TUserPrompt): Promise<InsightAssertionResponse>;
23
- describe(target: Rect | [number, number], opt?: {
24
- deepThink?: boolean;
25
- }): Promise<Pick<AIDescribeElementResponse, 'description'>>;
26
22
  }
@@ -1,6 +1,7 @@
1
1
  import type { NodeType } from '@midscene/shared/constants';
2
2
  import type { BaseElement, ElementTreeNode, Rect, Size } from '@midscene/shared/types';
3
3
  import type { ChatCompletionMessageParam } from 'openai/resources/index';
4
+ import type { z } from 'zod';
4
5
  import type { DetailedLocateParam, MidsceneYamlFlowItem } from './yaml';
5
6
  export type { ElementTreeNode, BaseElement, Rect, Size, Point, } from '@midscene/shared/types';
6
7
  export * from './yaml';
@@ -9,6 +10,7 @@ export type AIUsageInfo = Record<string, any> & {
9
10
  completion_tokens: number | undefined;
10
11
  total_tokens: number | undefined;
11
12
  time_cost: number | undefined;
13
+ model_name: string | undefined;
12
14
  };
13
15
  /**
14
16
  * openai
@@ -105,10 +107,10 @@ export type EnsureObject<T> = {
105
107
  export type InsightAction = 'locate' | 'extract' | 'assert' | 'describe';
106
108
  export type InsightExtractParam = string | Record<string, string>;
107
109
  export type LocateResultElement = {
108
- id: string;
109
- indexId?: number;
110
110
  center: [number, number];
111
111
  rect: Rect;
112
+ id: string;
113
+ indexId?: number;
112
114
  xpaths: string[];
113
115
  attributes: {
114
116
  nodeType: NodeType;
@@ -132,8 +134,6 @@ export interface InsightTaskInfo {
132
134
  export interface DumpMeta {
133
135
  sdkVersion: string;
134
136
  logTime: number;
135
- model_name: string;
136
- model_description?: string;
137
137
  }
138
138
  export interface ReportDumpWithAttributes {
139
139
  dumpString: string;
@@ -190,7 +190,7 @@ export interface PlanningLocateParam extends DetailedLocateParam {
190
190
  }
191
191
  export interface PlanningAction<ParamType = any> {
192
192
  thought?: string;
193
- type: 'Locate' | 'Tap' | 'RightClick' | 'Hover' | 'Drag' | 'Input' | 'KeyboardPress' | 'Scroll' | 'Error' | 'Assert' | 'AssertWithoutThrow' | 'Sleep' | 'Finished' | 'AndroidBackButton' | 'AndroidHomeButton' | 'AndroidRecentAppsButton' | 'AndroidLongPress' | 'AndroidPull';
193
+ type: string;
194
194
  param: ParamType;
195
195
  locate?: PlanningLocateParam | null;
196
196
  }
@@ -242,7 +242,6 @@ export interface Color {
242
242
  }
243
243
  export interface BaseAgentParserOpt {
244
244
  selector?: string;
245
- ignoreMarker?: boolean;
246
245
  }
247
246
  export interface PuppeteerParserOpt extends BaseAgentParserOpt {
248
247
  }
@@ -334,6 +333,8 @@ export type ExecutionTaskPlanning = ExecutionTask<ExecutionTaskPlanningApply>;
334
333
  export interface GroupedActionDump {
335
334
  groupName: string;
336
335
  groupDescription?: string;
336
+ modelName: string;
337
+ modelDescription: string;
337
338
  executions: ExecutionDump[];
338
339
  }
339
340
  export type PageType = 'puppeteer' | 'playwright' | 'static' | 'chrome-extension-proxy' | 'android';
@@ -388,12 +389,10 @@ export type TMultimodalPrompt = {
388
389
  export type TUserPrompt = string | ({
389
390
  prompt: string;
390
391
  } & Partial<TMultimodalPrompt>);
391
- export interface DeviceAction<ParamType = any> {
392
+ export interface DeviceAction<T = {}> {
392
393
  name: string;
393
394
  description?: string;
394
- paramSchema?: string;
395
- paramDescription?: string;
396
- location?: 'required' | 'optional' | false;
397
- whatToLocate?: string;
398
- call: (context: ExecutorContext, param: ParamType) => Promise<void> | void;
395
+ interfaceAlias?: string;
396
+ paramSchema?: z.ZodType<T>;
397
+ call: (param: T, context: ExecutorContext) => Promise<void> | void;
399
398
  }
@@ -10,6 +10,8 @@ export interface InsightExtractOption {
10
10
  domIncluded?: boolean | 'visible-only';
11
11
  screenshotIncluded?: boolean;
12
12
  returnThought?: boolean;
13
+ isWaitForAssert?: boolean;
14
+ doNotThrowError?: boolean;
13
15
  }
14
16
  export interface ReferenceImage {
15
17
  base64: string;
@@ -110,16 +112,15 @@ export interface MidsceneYamlFlowItemAIHover extends LocateOption {
110
112
  aiHover: TUserPrompt;
111
113
  }
112
114
  export interface MidsceneYamlFlowItemAIInput extends LocateOption {
113
- aiInput: string;
114
- locate: TUserPrompt;
115
+ aiInput: TUserPrompt | undefined;
116
+ value: string;
115
117
  }
116
118
  export interface MidsceneYamlFlowItemAIKeyboardPress extends LocateOption {
117
- aiKeyboardPress: string;
118
- locate?: TUserPrompt;
119
+ aiKeyboardPress: TUserPrompt | undefined;
120
+ key: string;
119
121
  }
120
122
  export interface MidsceneYamlFlowItemAIScroll extends LocateOption, ScrollParam {
121
- aiScroll: null;
122
- locate?: TUserPrompt;
123
+ aiScroll: TUserPrompt | undefined;
123
124
  }
124
125
  export interface MidsceneYamlFlowItemEvaluateJavaScript {
125
126
  javascript: string;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@midscene/core",
3
3
  "description": "Automate browser actions, extract data, and perform assertions using AI. It offers JavaScript SDK, Chrome extension, and support for scripting in YAML. See https://midscenejs.com/ for details.",
4
- "version": "0.26.7-beta-20250818035341.0",
4
+ "version": "0.26.7-beta-20250820105545.0",
5
5
  "repository": "https://github.com/web-infra-dev/midscene",
6
6
  "homepage": "https://midscenejs.com/",
7
7
  "main": "./dist/lib/index.js",
@@ -60,8 +60,9 @@
60
60
  "langsmith": "0.3.7",
61
61
  "openai": "4.81.0",
62
62
  "socks-proxy-agent": "8.0.4",
63
- "@midscene/shared": "0.26.7-beta-20250818035341.0",
64
- "@midscene/recorder": "0.26.7-beta-20250818035341.0"
63
+ "zod": "3.24.3",
64
+ "@midscene/recorder": "0.26.7-beta-20250820105545.0",
65
+ "@midscene/shared": "0.26.7-beta-20250820105545.0"
65
66
  },
66
67
  "devDependencies": {
67
68
  "@microsoft/api-extractor": "^7.52.10",