@midscene/core 0.28.2 → 0.28.3-beta-20250910131004.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.
- package/dist/es/agent/agent.mjs +27 -17
- package/dist/es/agent/agent.mjs.map +1 -1
- package/dist/es/agent/tasks.mjs +43 -31
- package/dist/es/agent/tasks.mjs.map +1 -1
- package/dist/es/agent/utils.mjs +4 -3
- package/dist/es/agent/utils.mjs.map +1 -1
- package/dist/es/ai-model/common.mjs +12 -22
- package/dist/es/ai-model/common.mjs.map +1 -1
- package/dist/es/ai-model/index.mjs +3 -3
- package/dist/es/ai-model/inspect.mjs +26 -34
- package/dist/es/ai-model/inspect.mjs.map +1 -1
- package/dist/es/ai-model/llm-planning.mjs +14 -15
- package/dist/es/ai-model/llm-planning.mjs.map +1 -1
- package/dist/es/ai-model/prompt/common.mjs.map +1 -1
- package/dist/es/ai-model/prompt/llm-locator.mjs.map +1 -1
- package/dist/es/ai-model/prompt/llm-planning.mjs.map +1 -1
- package/dist/es/ai-model/prompt/llm-section-locator.mjs.map +1 -1
- package/dist/es/ai-model/prompt/playwright-generator.mjs +6 -12
- package/dist/es/ai-model/prompt/playwright-generator.mjs.map +1 -1
- package/dist/es/ai-model/prompt/util.mjs +3 -3
- package/dist/es/ai-model/prompt/util.mjs.map +1 -1
- package/dist/es/ai-model/prompt/yaml-generator.mjs +6 -12
- package/dist/es/ai-model/prompt/yaml-generator.mjs.map +1 -1
- package/dist/es/ai-model/service-caller/index.mjs +28 -23
- package/dist/es/ai-model/service-caller/index.mjs.map +1 -1
- package/dist/es/ai-model/ui-tars-planning.mjs +10 -10
- package/dist/es/ai-model/ui-tars-planning.mjs.map +1 -1
- package/dist/es/insight/index.mjs +20 -26
- package/dist/es/insight/index.mjs.map +1 -1
- package/dist/es/types.mjs.map +1 -1
- package/dist/es/utils.mjs +4 -5
- package/dist/es/utils.mjs.map +1 -1
- package/dist/lib/agent/agent.js +26 -16
- package/dist/lib/agent/agent.js.map +1 -1
- package/dist/lib/agent/tasks.js +43 -31
- package/dist/lib/agent/tasks.js.map +1 -1
- package/dist/lib/agent/utils.js +4 -3
- package/dist/lib/agent/utils.js.map +1 -1
- package/dist/lib/ai-model/common.js +14 -27
- package/dist/lib/ai-model/common.js.map +1 -1
- package/dist/lib/ai-model/index.js +12 -15
- package/dist/lib/ai-model/inspect.js +24 -32
- package/dist/lib/ai-model/inspect.js.map +1 -1
- package/dist/lib/ai-model/llm-planning.js +13 -14
- package/dist/lib/ai-model/llm-planning.js.map +1 -1
- package/dist/lib/ai-model/prompt/common.js.map +1 -1
- package/dist/lib/ai-model/prompt/llm-locator.js.map +1 -1
- package/dist/lib/ai-model/prompt/llm-planning.js.map +1 -1
- package/dist/lib/ai-model/prompt/llm-section-locator.js.map +1 -1
- package/dist/lib/ai-model/prompt/playwright-generator.js +5 -11
- package/dist/lib/ai-model/prompt/playwright-generator.js.map +1 -1
- package/dist/lib/ai-model/prompt/util.js +3 -3
- package/dist/lib/ai-model/prompt/util.js.map +1 -1
- package/dist/lib/ai-model/prompt/yaml-generator.js +5 -11
- package/dist/lib/ai-model/prompt/yaml-generator.js.map +1 -1
- package/dist/lib/ai-model/service-caller/index.js +36 -31
- package/dist/lib/ai-model/service-caller/index.js.map +1 -1
- package/dist/lib/ai-model/ui-tars-planning.js +8 -8
- package/dist/lib/ai-model/ui-tars-planning.js.map +1 -1
- package/dist/lib/insight/index.js +17 -23
- package/dist/lib/insight/index.js.map +1 -1
- package/dist/lib/types.js.map +1 -1
- package/dist/lib/utils.js +3 -4
- package/dist/lib/utils.js.map +1 -1
- package/dist/types/agent/agent.d.ts +2 -0
- package/dist/types/agent/tasks.d.ts +8 -7
- package/dist/types/agent/utils.d.ts +3 -1
- package/dist/types/ai-model/common.d.ts +9 -16
- package/dist/types/ai-model/index.d.ts +2 -2
- package/dist/types/ai-model/inspect.d.ts +7 -6
- package/dist/types/ai-model/llm-planning.d.ts +2 -2
- package/dist/types/ai-model/prompt/common.d.ts +2 -2
- package/dist/types/ai-model/prompt/llm-locator.d.ts +2 -2
- package/dist/types/ai-model/prompt/llm-planning.d.ts +3 -3
- package/dist/types/ai-model/prompt/llm-section-locator.d.ts +2 -2
- package/dist/types/ai-model/prompt/playwright-generator.d.ts +3 -2
- package/dist/types/ai-model/prompt/util.d.ts +3 -2
- package/dist/types/ai-model/prompt/yaml-generator.d.ts +3 -2
- package/dist/types/ai-model/service-caller/index.d.ts +5 -5
- package/dist/types/ai-model/ui-tars-planning.d.ts +3 -3
- package/dist/types/device/index.d.ts +2 -2
- package/dist/types/insight/index.d.ts +12 -7
- package/dist/types/types.d.ts +0 -9
- package/dist/types/utils.d.ts +2 -1
- package/package.json +3 -3
package/dist/lib/utils.js.map
CHANGED
|
@@ -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 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 (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): 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 // 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({ 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
|
+
{"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 { MIDSCENE_DEBUG_MODE } 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 (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): 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 // 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":["__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","serverUrl","repoUrl","userEmail","execSync","error","fetch","response"],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type AgentAssertOpt, type AgentDescribeElementAtPointResult, type AgentWaitForOpt, type DeviceAction, type ExecutionDump, type GroupedActionDump, Insight, type InsightAction, type InsightExtractOption, type InsightExtractParam, type LocateOption, type LocateResultElement, type LocateValidatorResult, type LocatorValidatorOption, type OnTaskStartTip, type ScrollParam, type TUserPrompt, type UIContext } from '../index';
|
|
2
2
|
import type { AbstractInterface } from '../device';
|
|
3
3
|
import type { AgentOpt } from '../types';
|
|
4
|
+
import { ModelConfigManager } from '@midscene/shared/env';
|
|
4
5
|
import { TaskCache } from './task-cache';
|
|
5
6
|
import { TaskExecutor } from './tasks';
|
|
6
7
|
export declare class Agent<InterfaceType extends AbstractInterface = AbstractInterface> {
|
|
@@ -19,6 +20,7 @@ export declare class Agent<InterfaceType extends AbstractInterface = AbstractInt
|
|
|
19
20
|
taskCache?: TaskCache;
|
|
20
21
|
onDumpUpdate?: (dump: string) => void;
|
|
21
22
|
destroyed: boolean;
|
|
23
|
+
modelConfigManager: ModelConfigManager;
|
|
22
24
|
/**
|
|
23
25
|
* Frozen page context for consistent AI operations
|
|
24
26
|
*/
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type ChatCompletionMessageParam } from '../ai-model';
|
|
2
2
|
import type { AbstractInterface } from '../device';
|
|
3
3
|
import { type DetailedLocateParam, type ExecutionTaskApply, type ExecutionTaskProgressOptions, Executor, type Insight, type InsightExtractOption, type InsightExtractParam, type MidsceneYamlFlowItem, type PlanningAction, type PlanningActionParamWaitFor, type PlanningLocateParam, type TMultimodalPrompt, type TUserPrompt } from '../index';
|
|
4
|
+
import { type IModelConfig } from '@midscene/shared/env';
|
|
4
5
|
import type { TaskCache } from './task-cache';
|
|
5
6
|
interface ExecutionResult<OutputType = any> {
|
|
6
7
|
output: OutputType;
|
|
@@ -22,7 +23,7 @@ export declare class TaskExecutor {
|
|
|
22
23
|
private recordScreenshot;
|
|
23
24
|
private getElementXpath;
|
|
24
25
|
private prependExecutorWithScreenshot;
|
|
25
|
-
convertPlanToExecutable(plans: PlanningAction[]): Promise<{
|
|
26
|
+
convertPlanToExecutable(plans: PlanningAction[], modelConfig: IModelConfig): Promise<{
|
|
26
27
|
tasks: ExecutionTaskApply<any, any, any, any>[];
|
|
27
28
|
}>;
|
|
28
29
|
private setupPlanningContext;
|
|
@@ -31,16 +32,16 @@ export declare class TaskExecutor {
|
|
|
31
32
|
}>;
|
|
32
33
|
private planningTaskFromPrompt;
|
|
33
34
|
private planningTaskToGoal;
|
|
34
|
-
runPlans(title: string, plans: PlanningAction[]): Promise<ExecutionResult>;
|
|
35
|
-
action(userPrompt: string, actionContext?: string): Promise<ExecutionResult<{
|
|
35
|
+
runPlans(title: string, plans: PlanningAction[], modelConfig: IModelConfig): Promise<ExecutionResult>;
|
|
36
|
+
action(userPrompt: string, modelConfig: IModelConfig, actionContext?: string): Promise<ExecutionResult<{
|
|
36
37
|
yamlFlow?: MidsceneYamlFlowItem[];
|
|
37
38
|
} | undefined>>;
|
|
38
|
-
actionToGoal(userPrompt: string): Promise<ExecutionResult<{
|
|
39
|
+
actionToGoal(userPrompt: string, modelConfig: IModelConfig): Promise<ExecutionResult<{
|
|
39
40
|
yamlFlow?: MidsceneYamlFlowItem[];
|
|
40
41
|
} | undefined>>;
|
|
41
42
|
private createTypeQueryTask;
|
|
42
|
-
createTypeQueryExecution<T>(type: 'Query' | 'Boolean' | 'Number' | 'String' | 'Assert', demand: InsightExtractParam, opt?: InsightExtractOption, multimodalPrompt?: TMultimodalPrompt): Promise<ExecutionResult<T>>;
|
|
43
|
-
assert(assertion: TUserPrompt, opt?: InsightExtractOption): Promise<ExecutionResult<boolean>>;
|
|
43
|
+
createTypeQueryExecution<T>(type: 'Query' | 'Boolean' | 'Number' | 'String' | 'Assert', demand: InsightExtractParam, modelConfig: IModelConfig, opt?: InsightExtractOption, multimodalPrompt?: TMultimodalPrompt): Promise<ExecutionResult<T>>;
|
|
44
|
+
assert(assertion: TUserPrompt, modelConfig: IModelConfig, opt?: InsightExtractOption): Promise<ExecutionResult<boolean>>;
|
|
44
45
|
/**
|
|
45
46
|
* Append a message to the conversation history
|
|
46
47
|
* For user messages with images:
|
|
@@ -52,6 +53,6 @@ export declare class TaskExecutor {
|
|
|
52
53
|
*/
|
|
53
54
|
private appendConversationHistory;
|
|
54
55
|
private appendErrorPlan;
|
|
55
|
-
waitFor(assertion: TUserPrompt, opt: PlanningActionParamWaitFor): Promise<ExecutionResult<void>>;
|
|
56
|
+
waitFor(assertion: TUserPrompt, opt: PlanningActionParamWaitFor, modelConfig: IModelConfig): Promise<ExecutionResult<void>>;
|
|
56
57
|
}
|
|
57
58
|
export {};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { AbstractInterface } from '../device';
|
|
2
2
|
import type { BaseElement, ElementTreeNode, ExecutionDump, ExecutorContext, PlanningLocateParam, TMultimodalPrompt, TUserPrompt, UIContext } from '../index';
|
|
3
3
|
import type { TaskExecutor } from './tasks';
|
|
4
|
-
export declare function commonContextParser(interfaceInstance: AbstractInterface
|
|
4
|
+
export declare function commonContextParser(interfaceInstance: AbstractInterface, _opt: {
|
|
5
|
+
uploadServerUrl?: string;
|
|
6
|
+
}): Promise<UIContext>;
|
|
5
7
|
export declare function getReportFileName(tag?: string): string;
|
|
6
8
|
export declare function printReportMsg(filepath: string): void;
|
|
7
9
|
/**
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { BaseElement, DeviceAction, ElementTreeNode, MidsceneYamlFlowItem, PlanningAction, Rect, Size } from '../types';
|
|
2
|
+
import type { ChatCompletionMessageParam } from 'openai/resources/index';
|
|
3
3
|
import type { PlanningLocateParam } from '../types';
|
|
4
|
-
import {
|
|
4
|
+
import type { TVlModeTypes } from '@midscene/shared/env';
|
|
5
5
|
import { z } from 'zod';
|
|
6
|
-
export type AIArgs = [
|
|
7
|
-
ChatCompletionSystemMessageParam,
|
|
8
|
-
...ChatCompletionUserMessageParam[]
|
|
9
|
-
];
|
|
6
|
+
export type AIArgs = ChatCompletionMessageParam[];
|
|
10
7
|
export declare enum AIActionType {
|
|
11
8
|
ASSERT = 0,
|
|
12
9
|
INSPECT_ELEMENT = 1,
|
|
@@ -14,24 +11,20 @@ export declare enum AIActionType {
|
|
|
14
11
|
PLAN = 3,
|
|
15
12
|
DESCRIBE_ELEMENT = 4
|
|
16
13
|
}
|
|
17
|
-
export declare function
|
|
18
|
-
content: T;
|
|
19
|
-
usage?: AIUsageInfo;
|
|
20
|
-
}>;
|
|
21
|
-
export declare function fillBboxParam(locate: PlanningLocateParam, width: number, height: number, modelPreferences: IModelPreferences): PlanningLocateParam;
|
|
14
|
+
export declare function fillBboxParam(locate: PlanningLocateParam, width: number, height: number, vlMode: TVlModeTypes | undefined): PlanningLocateParam;
|
|
22
15
|
export declare function adaptQwenBbox(bbox: number[]): [number, number, number, number];
|
|
23
16
|
export declare function adaptDoubaoBbox(bbox: string[] | number[] | string, width: number, height: number): [number, number, number, number];
|
|
24
|
-
export declare function adaptBbox(bbox: number[], width: number, height: number,
|
|
17
|
+
export declare function adaptBbox(bbox: number[], width: number, height: number, vlMode: TVlModeTypes | undefined): [number, number, number, number];
|
|
25
18
|
export declare function adaptGeminiBbox(bbox: number[], width: number, height: number): [number, number, number, number];
|
|
26
|
-
export declare function adaptBboxToRect(bbox: number[], width: number, height: number,
|
|
27
|
-
export declare function warnGPT4oSizeLimit(size: Size,
|
|
19
|
+
export declare function adaptBboxToRect(bbox: number[], width: number, height: number, offsetX?: number, offsetY?: number, vlMode?: TVlModeTypes | undefined): Rect;
|
|
20
|
+
export declare function warnGPT4oSizeLimit(size: Size, modelName: string): void;
|
|
28
21
|
export declare function mergeRects(rects: Rect[]): {
|
|
29
22
|
left: number;
|
|
30
23
|
top: number;
|
|
31
24
|
width: number;
|
|
32
25
|
height: number;
|
|
33
26
|
};
|
|
34
|
-
export declare function expandSearchArea(rect: Rect, screenSize: Size,
|
|
27
|
+
export declare function expandSearchArea(rect: Rect, screenSize: Size, vlMode: TVlModeTypes | undefined): Rect;
|
|
35
28
|
export declare function markupImageForLLM(screenshotBase64: string, tree: ElementTreeNode<BaseElement>, size: Size): Promise<string>;
|
|
36
29
|
export declare function buildYamlFlowFromPlans(plans: PlanningAction[], actionSpace: DeviceAction<any>[], sleep?: number): MidsceneYamlFlowItem[];
|
|
37
30
|
export declare const PointSchema: z.ZodObject<{
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { callAIWithStringResponse, callAIWithObjectResponse, callAI, } from './service-caller/index';
|
|
2
2
|
export { systemPromptToLocateElement } from './prompt/llm-locator';
|
|
3
3
|
export { describeUserPage, elementByPositionWithElementInfo, } from './prompt/util';
|
|
4
4
|
export { generatePlaywrightTest, generatePlaywrightTestStream, } from './prompt/playwright-generator';
|
|
@@ -6,7 +6,7 @@ export { generateYamlTest, generateYamlTestStream, } from './prompt/yaml-generat
|
|
|
6
6
|
export type { ChatCompletionMessageParam } from 'openai/resources/index';
|
|
7
7
|
export { AiLocateElement, AiExtractElementInfo, AiLocateSection, } from './inspect';
|
|
8
8
|
export { plan } from './llm-planning';
|
|
9
|
-
export {
|
|
9
|
+
export { adaptBboxToRect } from './common';
|
|
10
10
|
export { vlmPlanning, resizeImageForUiTars } from './ui-tars-planning';
|
|
11
11
|
export { AIActionType, type AIArgs } from './common';
|
|
12
12
|
export { getMidsceneLocationSchema, type MidsceneLocationResultType, PointSchema, SizeSchema, RectSchema, TMultimodalPromptSchema, TUserPromptSchema, type TMultimodalPrompt, type TUserPrompt, findAllMidsceneLocatorField, dumpActionParam, loadActionParam, } from './common';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { AIDataExtractionResponse, AIElementLocatorResponse, AIElementResponse,
|
|
2
|
-
import {
|
|
1
|
+
import type { AIDataExtractionResponse, AIElementLocatorResponse, AIElementResponse, AIUsageInfo, BaseElement, ElementById, InsightExtractOption, Rect, ReferenceImage, UIContext } from '../types';
|
|
2
|
+
import type { IModelConfig } from '@midscene/shared/env';
|
|
3
3
|
import type { ChatCompletionSystemMessageParam, ChatCompletionUserMessageParam } from 'openai/resources/index';
|
|
4
4
|
import type { TMultimodalPrompt, TUserPrompt } from './common';
|
|
5
|
-
import {
|
|
5
|
+
import { callAIWithObjectResponse } from './service-caller/index';
|
|
6
6
|
export type AIArgs = [
|
|
7
7
|
ChatCompletionSystemMessageParam,
|
|
8
8
|
...ChatCompletionUserMessageParam[]
|
|
@@ -11,8 +11,9 @@ export declare function AiLocateElement<ElementType extends BaseElement = BaseEl
|
|
|
11
11
|
context: UIContext<ElementType>;
|
|
12
12
|
targetElementDescription: TUserPrompt;
|
|
13
13
|
referenceImage?: ReferenceImage;
|
|
14
|
-
|
|
14
|
+
callAIFn: typeof callAIWithObjectResponse<AIElementResponse | [number, number]>;
|
|
15
15
|
searchConfig?: Awaited<ReturnType<typeof AiLocateSection>>;
|
|
16
|
+
modelConfig: IModelConfig;
|
|
16
17
|
}): Promise<{
|
|
17
18
|
parseResult: AIElementLocatorResponse;
|
|
18
19
|
rect?: Rect;
|
|
@@ -24,7 +25,7 @@ export declare function AiLocateElement<ElementType extends BaseElement = BaseEl
|
|
|
24
25
|
export declare function AiLocateSection(options: {
|
|
25
26
|
context: UIContext<BaseElement>;
|
|
26
27
|
sectionDescription: TUserPrompt;
|
|
27
|
-
|
|
28
|
+
modelConfig: IModelConfig;
|
|
28
29
|
}): Promise<{
|
|
29
30
|
rect?: Rect;
|
|
30
31
|
imageBase64?: string;
|
|
@@ -37,7 +38,7 @@ export declare function AiExtractElementInfo<T, ElementType extends BaseElement
|
|
|
37
38
|
multimodalPrompt?: TMultimodalPrompt;
|
|
38
39
|
context: UIContext<ElementType>;
|
|
39
40
|
extractOption?: InsightExtractOption;
|
|
40
|
-
|
|
41
|
+
modelConfig: IModelConfig;
|
|
41
42
|
}): Promise<{
|
|
42
43
|
parseResult: AIDataExtractionResponse<T>;
|
|
43
44
|
elementById: (idOrIndexId: string) => ElementType;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { DeviceAction, InterfaceType, PlanningAIResponse, UIContext } from '../types';
|
|
2
|
-
import {
|
|
2
|
+
import type { IModelConfig } from '@midscene/shared/env';
|
|
3
3
|
export declare function plan(userInstruction: string, opts: {
|
|
4
4
|
context: UIContext;
|
|
5
5
|
interfaceType: InterfaceType;
|
|
6
6
|
actionSpace: DeviceAction<any>[];
|
|
7
|
-
callAI?: typeof callAiFn<PlanningAIResponse>;
|
|
8
7
|
log?: string;
|
|
9
8
|
actionContext?: string;
|
|
9
|
+
modelConfig: IModelConfig;
|
|
10
10
|
}): Promise<PlanningAIResponse>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function bboxDescription(vlMode:
|
|
1
|
+
import type { TVlModeTypes } from '@midscene/shared/env';
|
|
2
|
+
export declare function bboxDescription(vlMode: TVlModeTypes | undefined): "2d bounding box as [ymin, xmin, ymax, xmax]" | "2d bounding box as [xmin, ymin, xmax, ymax]";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PromptTemplate } from '@langchain/core/prompts';
|
|
2
|
-
import type {
|
|
2
|
+
import type { TVlModeTypes } from '@midscene/shared/env';
|
|
3
3
|
import type { ResponseFormatJSONSchema } from 'openai/resources/index';
|
|
4
|
-
export declare function systemPromptToLocateElement(vlMode:
|
|
4
|
+
export declare function systemPromptToLocateElement(vlMode: TVlModeTypes | undefined): string;
|
|
5
5
|
export declare const locatorSchema: ResponseFormatJSONSchema;
|
|
6
6
|
export declare const findElementPrompt: PromptTemplate<{
|
|
7
7
|
pageDescription: any;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import type { DeviceAction } from '../../types';
|
|
2
2
|
import { PromptTemplate } from '@langchain/core/prompts';
|
|
3
|
-
import type {
|
|
3
|
+
import type { TVlModeTypes } from '@midscene/shared/env';
|
|
4
4
|
import type { ResponseFormatJSONSchema } from 'openai/resources/index';
|
|
5
5
|
export declare const descriptionForAction: (action: DeviceAction<any>, locatorSchemaTypeDescription: string) => string;
|
|
6
6
|
export declare function systemPromptToTaskPlanning({ actionSpace, vlMode, }: {
|
|
7
7
|
actionSpace: DeviceAction<any>[];
|
|
8
|
-
vlMode:
|
|
8
|
+
vlMode: TVlModeTypes | undefined;
|
|
9
9
|
}): Promise<string>;
|
|
10
10
|
export declare const planSchema: ResponseFormatJSONSchema;
|
|
11
11
|
export declare const generateTaskBackgroundContext: (userInstruction: string, log?: string, userActionContext?: string) => string;
|
|
12
|
-
export declare const automationUserPrompt: (vlMode:
|
|
12
|
+
export declare const automationUserPrompt: (vlMode: TVlModeTypes | undefined) => PromptTemplate<{
|
|
13
13
|
pageDescription: any;
|
|
14
14
|
taskBackgroundContext: any;
|
|
15
15
|
}, any>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PromptTemplate } from '@langchain/core/prompts';
|
|
2
|
-
import type {
|
|
3
|
-
export declare function systemPromptToLocateSection(vlMode:
|
|
2
|
+
import type { TVlModeTypes } from '@midscene/shared/env';
|
|
3
|
+
export declare function systemPromptToLocateSection(vlMode: TVlModeTypes | undefined): string;
|
|
4
4
|
export declare const sectionLocatorInstruction: PromptTemplate<{
|
|
5
5
|
sectionDescription: any;
|
|
6
6
|
}, any>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { StreamingAIResponse, StreamingCodeGenerationOptions } from '../../types';
|
|
2
|
+
import type { IModelConfig } from '@midscene/shared/env';
|
|
2
3
|
import { type ChromeRecordedEvent, type EventCounts, type EventSummary, type InputDescription, type ProcessedEvent, createEventCounts, createMessageContent, extractInputDescriptions, filterEventsByType, getScreenshotsForLLM, prepareEventSummary, processEventsForLLM, validateEvents } from './yaml-generator';
|
|
3
4
|
export interface PlaywrightGenerationOptions {
|
|
4
5
|
testName?: string;
|
|
@@ -18,8 +19,8 @@ export { getScreenshotsForLLM, filterEventsByType, createEventCounts, extractInp
|
|
|
18
19
|
/**
|
|
19
20
|
* Generates Playwright test code from recorded events
|
|
20
21
|
*/
|
|
21
|
-
export declare const generatePlaywrightTest: (events: ChromeRecordedEvent[], options
|
|
22
|
+
export declare const generatePlaywrightTest: (events: ChromeRecordedEvent[], options: PlaywrightGenerationOptions, modelConfig: IModelConfig) => Promise<string>;
|
|
22
23
|
/**
|
|
23
24
|
* Generates Playwright test code from recorded events with streaming support
|
|
24
25
|
*/
|
|
25
|
-
export declare const generatePlaywrightTestStream: (events: ChromeRecordedEvent[], options
|
|
26
|
+
export declare const generatePlaywrightTestStream: (events: ChromeRecordedEvent[], options: PlaywrightGenerationOptions & StreamingCodeGenerationOptions, modelConfig: IModelConfig) => Promise<StreamingAIResponse>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { BaseElement, ElementTreeNode, Size, UIContext } from '../../types';
|
|
2
|
-
import {
|
|
2
|
+
import type { TVlModeTypes } from '@midscene/shared/env';
|
|
3
3
|
export declare function describeSize(size: Size): string;
|
|
4
4
|
export declare function describeElement(elements: (Pick<BaseElement, 'rect' | 'content'> & {
|
|
5
5
|
id: string;
|
|
@@ -20,11 +20,12 @@ export declare function distance(point1: {
|
|
|
20
20
|
y: number;
|
|
21
21
|
}): number;
|
|
22
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";
|
|
23
|
-
export declare function describeUserPage<ElementType extends BaseElement = BaseElement>(context: Omit<UIContext<ElementType>, 'describer'>,
|
|
23
|
+
export declare function describeUserPage<ElementType extends BaseElement = BaseElement>(context: Omit<UIContext<ElementType>, 'describer'>, opt: {
|
|
24
24
|
truncateTextLength?: number;
|
|
25
25
|
filterNonTextContent?: boolean;
|
|
26
26
|
domIncluded?: boolean | 'visible-only';
|
|
27
27
|
visibleOnly?: boolean;
|
|
28
|
+
vlMode: TVlModeTypes | undefined;
|
|
28
29
|
}): Promise<{
|
|
29
30
|
description: string;
|
|
30
31
|
elementById(idOrIndexId: string): ElementType;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { StreamingAIResponse, StreamingCodeGenerationOptions } from '../../types';
|
|
2
|
+
import type { IModelConfig } from '@midscene/shared/env';
|
|
2
3
|
export interface EventCounts {
|
|
3
4
|
navigation: number;
|
|
4
5
|
click: number;
|
|
@@ -92,8 +93,8 @@ export declare const validateEvents: (events: ChromeRecordedEvent[]) => void;
|
|
|
92
93
|
/**
|
|
93
94
|
* Generates YAML test configuration from recorded events using AI
|
|
94
95
|
*/
|
|
95
|
-
export declare const generateYamlTest: (events: ChromeRecordedEvent[], options
|
|
96
|
+
export declare const generateYamlTest: (events: ChromeRecordedEvent[], options: YamlGenerationOptions, modelConfig: IModelConfig) => Promise<string>;
|
|
96
97
|
/**
|
|
97
98
|
* Generates YAML test configuration from recorded events using AI with streaming support
|
|
98
99
|
*/
|
|
99
|
-
export declare const generateYamlTestStream: (events: ChromeRecordedEvent[], options
|
|
100
|
+
export declare const generateYamlTestStream: (events: ChromeRecordedEvent[], options: YamlGenerationOptions & StreamingCodeGenerationOptions, modelConfig: IModelConfig) => Promise<StreamingAIResponse>;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { type AIUsageInfo } from '../../types';
|
|
2
2
|
import type { StreamingCallback } from '../../types';
|
|
3
|
-
import { type
|
|
3
|
+
import { type IModelConfig, type TVlModeTypes } from '@midscene/shared/env';
|
|
4
4
|
import OpenAI from 'openai';
|
|
5
5
|
import type { ChatCompletionMessageParam } from 'openai/resources/index';
|
|
6
6
|
import { AIActionType, type AIArgs } from '../common';
|
|
7
|
-
export declare function
|
|
7
|
+
export declare function callAI(messages: ChatCompletionMessageParam[], AIActionTypeValue: AIActionType, modelConfig: IModelConfig, options?: {
|
|
8
8
|
stream?: boolean;
|
|
9
9
|
onChunk?: StreamingCallback;
|
|
10
10
|
}): Promise<{
|
|
@@ -13,14 +13,14 @@ export declare function call(messages: ChatCompletionMessageParam[], AIActionTyp
|
|
|
13
13
|
isStreamed: boolean;
|
|
14
14
|
}>;
|
|
15
15
|
export declare const getResponseFormat: (modelName: string, AIActionTypeValue: AIActionType) => OpenAI.ChatCompletionCreateParams["response_format"] | OpenAI.ResponseFormatJSONObject;
|
|
16
|
-
export declare function
|
|
16
|
+
export declare function callAIWithObjectResponse<T>(messages: AIArgs, AIActionTypeValue: AIActionType, modelConfig: IModelConfig): Promise<{
|
|
17
17
|
content: T;
|
|
18
18
|
usage?: AIUsageInfo;
|
|
19
19
|
}>;
|
|
20
|
-
export declare function
|
|
20
|
+
export declare function callAIWithStringResponse(msgs: AIArgs, AIActionTypeValue: AIActionType, modelConfig: IModelConfig): 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,
|
|
26
|
+
export declare function safeParseJson(input: string, vlMode: TVlModeTypes | undefined): any;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AIUsageInfo, MidsceneYamlFlowItem, PlanningAction, Size } from '../types';
|
|
2
|
-
import { type
|
|
2
|
+
import { type IModelConfig, UITarsModelVersion } from '@midscene/shared/env';
|
|
3
3
|
import { actionParser } from '@ui-tars/action-parser';
|
|
4
4
|
import type { ChatCompletionMessageParam } from 'openai/resources/index';
|
|
5
5
|
type ActionType = 'click' | 'drag' | 'type' | 'hotkey' | 'finished' | 'scroll' | 'wait';
|
|
@@ -10,7 +10,7 @@ export declare function vlmPlanning(options: {
|
|
|
10
10
|
width: number;
|
|
11
11
|
height: number;
|
|
12
12
|
};
|
|
13
|
-
|
|
13
|
+
modelConfig: IModelConfig;
|
|
14
14
|
}): Promise<{
|
|
15
15
|
actions: PlanningAction<any>[];
|
|
16
16
|
actionsFromModel: ReturnType<typeof actionParser>['parsed'];
|
|
@@ -67,5 +67,5 @@ interface FinishedAction extends BaseAction {
|
|
|
67
67
|
action_inputs: Record<string, never>;
|
|
68
68
|
}
|
|
69
69
|
export type Action = ClickAction | DragAction | TypeAction | HotkeyAction | ScrollAction | FinishedAction | WaitAction;
|
|
70
|
-
export declare function resizeImageForUiTars(imageBase64: string, size: Size,
|
|
70
|
+
export declare function resizeImageForUiTars(imageBase64: string, size: Size, uiTarsVersion: UITarsModelVersion | undefined): Promise<string>;
|
|
71
71
|
export {};
|
|
@@ -1254,6 +1254,7 @@ export declare const actionInputParamSchema: z.ZodObject<{
|
|
|
1254
1254
|
}>>;
|
|
1255
1255
|
}, z.ZodTypeAny, "passthrough">>;
|
|
1256
1256
|
}, "strip", z.ZodTypeAny, {
|
|
1257
|
+
value: string;
|
|
1257
1258
|
locate: {
|
|
1258
1259
|
prompt: string | ({
|
|
1259
1260
|
prompt: string;
|
|
@@ -1282,8 +1283,8 @@ export declare const actionInputParamSchema: z.ZodObject<{
|
|
|
1282
1283
|
} & {
|
|
1283
1284
|
[k: string]: unknown;
|
|
1284
1285
|
};
|
|
1285
|
-
value: string;
|
|
1286
1286
|
}, {
|
|
1287
|
+
value: string;
|
|
1287
1288
|
locate: {
|
|
1288
1289
|
prompt: string | ({
|
|
1289
1290
|
prompt: string;
|
|
@@ -1312,7 +1313,6 @@ export declare const actionInputParamSchema: z.ZodObject<{
|
|
|
1312
1313
|
} & {
|
|
1313
1314
|
[k: string]: unknown;
|
|
1314
1315
|
};
|
|
1315
|
-
value: string;
|
|
1316
1316
|
}>;
|
|
1317
1317
|
export type ActionInputParam = z.infer<typeof actionInputParamSchema>;
|
|
1318
1318
|
export declare const defineActionInput: (call: (param: ActionInputParam) => Promise<void>) => DeviceAction<ActionInputParam>;
|
|
@@ -1,26 +1,31 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { AIDescribeElementResponse,
|
|
1
|
+
import { callAIWithObjectResponse } from '../ai-model/index';
|
|
2
|
+
import type { AIDescribeElementResponse, AIUsageInfo, BaseElement, DetailedLocateParam, DumpSubscriber, InsightAction, InsightExtractOption, InsightExtractParam, InsightTaskInfo, LocateResult, Rect, UIContext } from '../types';
|
|
3
|
+
import { type IModelConfig } from '@midscene/shared/env';
|
|
3
4
|
import type { TMultimodalPrompt } from '../ai-model/common';
|
|
4
5
|
export interface LocateOpts {
|
|
5
6
|
context?: UIContext<BaseElement>;
|
|
6
|
-
callAI?: typeof callAiFn<AIElementResponse>;
|
|
7
7
|
}
|
|
8
8
|
export type AnyValue<T> = {
|
|
9
9
|
[K in keyof T]: unknown extends T[K] ? any : T[K];
|
|
10
10
|
};
|
|
11
|
+
interface InsightOptions {
|
|
12
|
+
taskInfo?: Omit<InsightTaskInfo, 'durationMs'>;
|
|
13
|
+
aiVendorFn?: typeof callAIWithObjectResponse;
|
|
14
|
+
}
|
|
11
15
|
export default class Insight<ElementType extends BaseElement = BaseElement, ContextType extends UIContext<ElementType> = UIContext<ElementType>> {
|
|
12
16
|
contextRetrieverFn: (action: InsightAction) => Promise<ContextType> | ContextType;
|
|
13
|
-
aiVendorFn:
|
|
17
|
+
aiVendorFn: Exclude<InsightOptions['aiVendorFn'], undefined>;
|
|
14
18
|
onceDumpUpdatedFn?: DumpSubscriber;
|
|
15
19
|
taskInfo?: Omit<InsightTaskInfo, 'durationMs'>;
|
|
16
20
|
constructor(context: ContextType | ((action: InsightAction) => Promise<ContextType> | ContextType), opt?: InsightOptions);
|
|
17
|
-
locate(query: DetailedLocateParam, opt
|
|
18
|
-
extract<T>(dataDemand: InsightExtractParam, opt?: InsightExtractOption, multimodalPrompt?: TMultimodalPrompt): Promise<{
|
|
21
|
+
locate(query: DetailedLocateParam, opt: LocateOpts, modelConfig: IModelConfig): Promise<LocateResult>;
|
|
22
|
+
extract<T>(dataDemand: InsightExtractParam, modelConfig: IModelConfig, opt?: InsightExtractOption, multimodalPrompt?: TMultimodalPrompt): Promise<{
|
|
19
23
|
data: T;
|
|
20
24
|
thought?: string;
|
|
21
25
|
usage?: AIUsageInfo;
|
|
22
26
|
}>;
|
|
23
|
-
describe(target: Rect | [number, number], opt?: {
|
|
27
|
+
describe(target: Rect | [number, number], modelConfig: IModelConfig, opt?: {
|
|
24
28
|
deepThink?: boolean;
|
|
25
29
|
}): Promise<Pick<AIDescribeElementResponse, 'description'>>;
|
|
26
30
|
}
|
|
31
|
+
export {};
|
package/dist/types/types.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { NodeType } from '@midscene/shared/constants';
|
|
2
2
|
import type { TModelConfigFn } from '@midscene/shared/env';
|
|
3
3
|
import type { BaseElement, ElementTreeNode, Rect, Size } from '@midscene/shared/types';
|
|
4
|
-
import type { ChatCompletionMessageParam } from 'openai/resources/index';
|
|
5
4
|
import type { z } from 'zod';
|
|
6
5
|
import type { TUserPrompt } from './ai-model/common';
|
|
7
6
|
import type { DetailedLocateParam, MidsceneYamlFlowItem } from './yaml';
|
|
@@ -98,14 +97,6 @@ export declare abstract class UIContext<ElementType extends BaseElement = BaseEl
|
|
|
98
97
|
abstract size: Size;
|
|
99
98
|
abstract _isFrozen?: boolean;
|
|
100
99
|
}
|
|
101
|
-
/**
|
|
102
|
-
* insight
|
|
103
|
-
*/
|
|
104
|
-
export type CallAIFn = <T>(messages: ChatCompletionMessageParam[]) => Promise<T>;
|
|
105
|
-
export interface InsightOptions {
|
|
106
|
-
taskInfo?: Omit<InsightTaskInfo, 'durationMs'>;
|
|
107
|
-
aiVendorFn?: CallAIFn;
|
|
108
|
-
}
|
|
109
100
|
export type EnsureObject<T> = {
|
|
110
101
|
[K in keyof T]: any;
|
|
111
102
|
};
|
package/dist/types/utils.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export declare function sleep(ms: number): Promise<unknown>;
|
|
|
22
22
|
export declare function replacerForPageObject(key: string, value: any): any;
|
|
23
23
|
export declare function stringifyDumpData(data: any, indents?: number): string;
|
|
24
24
|
export declare function getVersion(): string;
|
|
25
|
-
export declare function uploadTestInfoToServer({ testUrl }: {
|
|
25
|
+
export declare function uploadTestInfoToServer({ testUrl, serverUrl, }: {
|
|
26
26
|
testUrl: string;
|
|
27
|
+
serverUrl?: string;
|
|
27
28
|
}): void;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@midscene/core",
|
|
3
3
|
"description": "Automate browser actions, extract data, and perform assertions using AI. It offers JavaScript SDK, Chrome extension, and support for scripting in YAML. See https://midscenejs.com/ for details.",
|
|
4
|
-
"version": "0.28.
|
|
4
|
+
"version": "0.28.3-beta-20250910131004.0",
|
|
5
5
|
"repository": "https://github.com/web-infra-dev/midscene",
|
|
6
6
|
"homepage": "https://midscenejs.com/",
|
|
7
7
|
"main": "./dist/lib/index.js",
|
|
@@ -87,8 +87,8 @@
|
|
|
87
87
|
"zod": "3.24.3",
|
|
88
88
|
"semver": "7.5.2",
|
|
89
89
|
"js-yaml": "4.1.0",
|
|
90
|
-
"@midscene/recorder": "0.28.
|
|
91
|
-
"@midscene/shared": "0.28.
|
|
90
|
+
"@midscene/recorder": "0.28.3-beta-20250910131004.0",
|
|
91
|
+
"@midscene/shared": "0.28.3-beta-20250910131004.0"
|
|
92
92
|
},
|
|
93
93
|
"devDependencies": {
|
|
94
94
|
"@microsoft/api-extractor": "^7.52.10",
|