@midscene/core 0.24.2-beta-20250730081235.0 → 0.24.2-beta-20250731010609.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/ai-model.d.ts +3 -3
- package/dist/es/ai-model.js +1 -1
- package/dist/es/{chunk-KGBLKK6O.js → chunk-EJK3T22H.js} +12 -7
- package/dist/es/chunk-EJK3T22H.js.map +1 -0
- package/dist/es/{chunk-NAMQEUK6.js → chunk-YCHAOUOW.js} +41 -31
- package/dist/es/chunk-YCHAOUOW.js.map +1 -0
- package/dist/es/index.d.ts +4 -4
- package/dist/es/index.js +12 -4
- package/dist/es/index.js.map +1 -1
- package/dist/es/{llm-planning-6575ef56.d.ts → llm-planning-3f26578e.d.ts} +2 -1
- package/dist/es/{types-7b554c6a.d.ts → types-c519555a.d.ts} +5 -7
- package/dist/es/utils.d.ts +1 -1
- package/dist/es/utils.js +1 -1
- package/dist/lib/ai-model.d.ts +3 -3
- package/dist/lib/ai-model.js +2 -2
- package/dist/lib/{chunk-KGBLKK6O.js → chunk-EJK3T22H.js} +11 -6
- package/dist/lib/chunk-EJK3T22H.js.map +1 -0
- package/dist/lib/{chunk-NAMQEUK6.js → chunk-YCHAOUOW.js} +41 -31
- package/dist/lib/chunk-YCHAOUOW.js.map +1 -0
- package/dist/lib/index.d.ts +4 -4
- package/dist/lib/index.js +21 -13
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/{llm-planning-6575ef56.d.ts → llm-planning-3f26578e.d.ts} +2 -1
- package/dist/{types/types-7b554c6a.d.ts → lib/types-c519555a.d.ts} +5 -7
- package/dist/lib/utils.d.ts +1 -1
- package/dist/lib/utils.js +2 -2
- package/dist/types/ai-model.d.ts +3 -3
- package/dist/types/index.d.ts +4 -4
- package/dist/types/{llm-planning-6575ef56.d.ts → llm-planning-3f26578e.d.ts} +2 -1
- package/dist/{lib/types-7b554c6a.d.ts → types/types-c519555a.d.ts} +5 -7
- package/dist/types/utils.d.ts +1 -1
- package/package.json +3 -3
- package/dist/es/chunk-KGBLKK6O.js.map +0 -1
- package/dist/es/chunk-NAMQEUK6.js.map +0 -1
- package/dist/lib/chunk-KGBLKK6O.js.map +0 -1
- package/dist/lib/chunk-NAMQEUK6.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"mappings":"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","names":["readFileSync"],"ignoreList":[],"sources":["../../src/utils.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport * as fs from 'node:fs';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport * as path from 'node:path';\nimport { dirname } 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/fs';\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 __dirname = dirname(__filename);\n const midscenePkgInfo = getRunningPkgInfo(__dirname);\n if (!midscenePkgInfo) {\n console.warn('midscenePkgInfo not found, will not write report');\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"]}
|
|
@@ -300,7 +300,7 @@ function buildYamlFlowFromPlans(plans, sleep) {
|
|
|
300
300
|
flow.push({
|
|
301
301
|
sleep: param.timeMs
|
|
302
302
|
});
|
|
303
|
-
} else if (type === "AndroidBackButton" || type === "AndroidHomeButton" || type === "AndroidRecentAppsButton"
|
|
303
|
+
} else if (type === "AndroidBackButton" || type === "AndroidHomeButton" || type === "AndroidRecentAppsButton") {
|
|
304
304
|
} else if (type === "Error" || type === "ExpectedFalsyCondition" || type === "Assert" || type === "AssertWithoutThrow" || type === "Finished") {
|
|
305
305
|
} else {
|
|
306
306
|
console.warn(
|
|
@@ -386,31 +386,47 @@ You are an expert in software testing.
|
|
|
386
386
|
## Objective:
|
|
387
387
|
- Identify elements in screenshots and text that match the user's description.
|
|
388
388
|
- Give the coordinates of the element that matches the user's description best in the screenshot.
|
|
389
|
+
- Determine whether the user's description is order-sensitive (e.g., contains phrases like 'the third item in the list', 'the last button', etc.).
|
|
389
390
|
|
|
390
391
|
## Output Format:
|
|
391
392
|
\`\`\`json
|
|
392
393
|
{
|
|
393
394
|
"bbox": [number, number, number, number], // ${bboxComment}
|
|
394
|
-
"errors"?: string[]
|
|
395
|
+
"errors"?: string[],
|
|
396
|
+
"isOrderSensitive": boolean // Whether the targetElementDescription is order-sensitive (true/false)
|
|
395
397
|
}
|
|
396
398
|
\`\`\`
|
|
397
399
|
|
|
398
400
|
Fields:
|
|
399
401
|
* \`bbox\` is the bounding box of the element that matches the user's description best in the screenshot
|
|
402
|
+
* \`isOrderSensitive\` is a boolean indicating whether the user's description is order-sensitive (true/false)
|
|
400
403
|
* \`errors\` is an optional array of error messages (if any)
|
|
401
404
|
|
|
402
|
-
|
|
405
|
+
Order-sensitive means the description contains phrases like:
|
|
406
|
+
- "the third item in the list"
|
|
407
|
+
- "the last button"
|
|
408
|
+
- "the first input box"
|
|
409
|
+
- "the second row"
|
|
410
|
+
|
|
411
|
+
Not order-sensitive means the description is like:
|
|
412
|
+
- "confirm button"
|
|
413
|
+
- "search box"
|
|
414
|
+
- "password input"
|
|
415
|
+
|
|
416
|
+
For example, when an element is found and the description is order-sensitive:
|
|
403
417
|
\`\`\`json
|
|
404
418
|
{
|
|
405
419
|
"bbox": [100, 100, 200, 200],
|
|
420
|
+
"isOrderSensitive": true,
|
|
406
421
|
"errors": []
|
|
407
422
|
}
|
|
408
423
|
\`\`\`
|
|
409
424
|
|
|
410
|
-
When no element is found:
|
|
425
|
+
When no element is found and the description is not order-sensitive:
|
|
411
426
|
\`\`\`json
|
|
412
427
|
{
|
|
413
428
|
"bbox": [],
|
|
429
|
+
"isOrderSensitive": false,
|
|
414
430
|
"errors": ["I can see ..., but {some element} is not found"]
|
|
415
431
|
}
|
|
416
432
|
\`\`\`
|
|
@@ -423,6 +439,7 @@ You are an expert in software page image (2D) and page element text analysis.
|
|
|
423
439
|
## Objective:
|
|
424
440
|
- Identify elements in screenshots and text that match the user's description.
|
|
425
441
|
- Return JSON data containing the selection reason and element ID.
|
|
442
|
+
- Determine whether the user's description is order-sensitive (e.g., contains phrases like 'the third item in the list', 'the last button', etc.).
|
|
426
443
|
|
|
427
444
|
## Skills:
|
|
428
445
|
- Image analysis and recognition
|
|
@@ -434,6 +451,7 @@ You are an expert in software page image (2D) and page element text analysis.
|
|
|
434
451
|
2. Based on the user's description, locate the target element ID in the list of element descriptions and the screenshot.
|
|
435
452
|
3. Found the required number of elements
|
|
436
453
|
4. Return JSON data containing the selection reason and element ID.
|
|
454
|
+
5. Judge whether the user's description is order-sensitive (see below for definition and examples).
|
|
437
455
|
|
|
438
456
|
## Constraints:
|
|
439
457
|
- Strictly adhere to the specified location when describing the required element; do not select elements from other locations.
|
|
@@ -443,6 +461,10 @@ You are an expert in software page image (2D) and page element text analysis.
|
|
|
443
461
|
- The returned data must conform to the specified JSON format.
|
|
444
462
|
- The returned value id information must use the id from element info (important: **use id not indexId, id is hash content**)
|
|
445
463
|
|
|
464
|
+
## Order-Sensitive Definition:
|
|
465
|
+
- If the description contains phrases like "the third item in the list", "the last button", "the first input box", "the second row", etc., it is order-sensitive (isOrderSensitive = true).
|
|
466
|
+
- If the description is like "confirm button", "search box", "password input", etc., it is not order-sensitive (isOrderSensitive = false).
|
|
467
|
+
|
|
446
468
|
## Output Format:
|
|
447
469
|
|
|
448
470
|
Please return the result in JSON format as follows:
|
|
@@ -458,6 +480,7 @@ Please return the result in JSON format as follows:
|
|
|
458
480
|
}
|
|
459
481
|
// More elements...
|
|
460
482
|
],
|
|
483
|
+
"isOrderSensitive": true, // or false, depending on the user's description
|
|
461
484
|
"errors": [] // Array of strings containing any error messages
|
|
462
485
|
}
|
|
463
486
|
\`\`\`
|
|
@@ -546,6 +569,7 @@ Output Example:
|
|
|
546
569
|
"id": "1231"
|
|
547
570
|
}
|
|
548
571
|
],
|
|
572
|
+
"isOrderSensitive": true,
|
|
549
573
|
"errors": []
|
|
550
574
|
}
|
|
551
575
|
\`\`\`
|
|
@@ -583,6 +607,10 @@ var locatorSchema = {
|
|
|
583
607
|
},
|
|
584
608
|
description: "List of found elements"
|
|
585
609
|
},
|
|
610
|
+
isOrderSensitive: {
|
|
611
|
+
type: "boolean",
|
|
612
|
+
description: "Whether the targetElementDescription is order-sensitive (true/false)"
|
|
613
|
+
},
|
|
586
614
|
errors: {
|
|
587
615
|
type: "array",
|
|
588
616
|
items: {
|
|
@@ -591,7 +619,7 @@ var locatorSchema = {
|
|
|
591
619
|
description: "List of error messages, if any"
|
|
592
620
|
}
|
|
593
621
|
},
|
|
594
|
-
required: ["elements", "errors"],
|
|
622
|
+
required: ["elements", "isOrderSensitive", "errors"],
|
|
595
623
|
additionalProperties: false
|
|
596
624
|
}
|
|
597
625
|
}
|
|
@@ -766,7 +794,7 @@ Target: User will give you a screenshot, an instruction and some previous logs i
|
|
|
766
794
|
|
|
767
795
|
Restriction:
|
|
768
796
|
- Don't give extra actions or plans beyond the instruction. ONLY plan for what the instruction requires. For example, don't try to submit the form if the instruction is only to fill something.
|
|
769
|
-
- Always give ONLY ONE action in \`log\` field (or null if no action should be done), instead of multiple actions. Supported actions are Tap, Hover, Input, KeyboardPress, Scroll${pageType === "android" ? ", AndroidBackButton, AndroidHomeButton, AndroidRecentAppsButton
|
|
797
|
+
- Always give ONLY ONE action in \`log\` field (or null if no action should be done), instead of multiple actions. Supported actions are Tap, Hover, Input, KeyboardPress, Scroll${pageType === "android" ? ", AndroidBackButton, AndroidHomeButton, AndroidRecentAppsButton." : "."}
|
|
770
798
|
- Don't repeat actions in the previous logs.
|
|
771
799
|
- Bbox is the bounding box of the element to be located. It's an array of 4 numbers, representing ${bboxDescription(vlMode)}.
|
|
772
800
|
|
|
@@ -779,8 +807,7 @@ Supporting actions:
|
|
|
779
807
|
- Scroll: { type: "Scroll", ${vlLocateParam} | null, param: { direction: 'down'(default) | 'up' | 'right' | 'left', scrollType: 'once' (default) | 'untilBottom' | 'untilTop' | 'untilRight' | 'untilLeft', distance: null | number }} // locate is the element to scroll. If it's a page scroll, put \`null\` in the \`locate\` field.
|
|
780
808
|
${pageType === "android" ? `- AndroidBackButton: { type: "AndroidBackButton", param: {} }
|
|
781
809
|
- AndroidHomeButton: { type: "AndroidHomeButton", param: {} }
|
|
782
|
-
- AndroidRecentAppsButton: { type: "AndroidRecentAppsButton", param: {} }
|
|
783
|
-
- AndroidLongPress: { type: "AndroidLongPress", param: { x: number, y: number, duration?: number } }` : ""}
|
|
810
|
+
- AndroidRecentAppsButton: { type: "AndroidRecentAppsButton", param: {} }` : ""}
|
|
784
811
|
|
|
785
812
|
Field description:
|
|
786
813
|
* The \`prompt\` field inside the \`locate\` field is a short description that could be used to locate the element.
|
|
@@ -830,7 +857,7 @@ You are a versatile professional in software UI automation. Your outstanding con
|
|
|
830
857
|
## Workflow
|
|
831
858
|
|
|
832
859
|
1. Receive the screenshot, element description of screenshot(if any), user's instruction and previous logs.
|
|
833
|
-
2. Decompose the user's task into a sequence of actions, and place it in the \`actions\` field. There are different types of actions (Tap / Hover / Input / KeyboardPress / Scroll / FalsyConditionStatement / Sleep ${pageType === "android" ? "/ AndroidBackButton / AndroidHomeButton / AndroidRecentAppsButton
|
|
860
|
+
2. Decompose the user's task into a sequence of actions, and place it in the \`actions\` field. There are different types of actions (Tap / Hover / Input / KeyboardPress / Scroll / FalsyConditionStatement / Sleep ${pageType === "android" ? "/ AndroidBackButton / AndroidHomeButton / AndroidRecentAppsButton" : ""}). The "About the action" section below will give you more details.
|
|
834
861
|
3. Precisely locate the target element if it's already shown in the screenshot, put the location info in the \`locate\` field of the action.
|
|
835
862
|
4. If some target elements is not shown in the screenshot, consider the user's instruction is not feasible on this page. Follow the next steps.
|
|
836
863
|
5. Consider whether the user's instruction will be accomplished after all the actions
|
|
@@ -889,9 +916,7 @@ ${pageType === "android" ? `- type: 'AndroidBackButton', trigger the system "bac
|
|
|
889
916
|
- type: 'AndroidHomeButton', trigger the system "home" operation on Android devices
|
|
890
917
|
* {{ param: {{}} }}
|
|
891
918
|
- type: 'AndroidRecentAppsButton', trigger the system "recent apps" operation on Android devices
|
|
892
|
-
* {{ param: {{}} }}
|
|
893
|
-
- type: 'AndroidLongPress', trigger a long press on the screen at specified coordinates on Android devices
|
|
894
|
-
* {{ param: {{ x: number, y: number, duration?: number }} }}` : ""}
|
|
919
|
+
* {{ param: {{}} }}` : ""}
|
|
895
920
|
`;
|
|
896
921
|
var outputTemplate = `
|
|
897
922
|
## Output JSON Format:
|
|
@@ -1005,7 +1030,7 @@ var planSchema = {
|
|
|
1005
1030
|
},
|
|
1006
1031
|
type: {
|
|
1007
1032
|
type: "string",
|
|
1008
|
-
description: 'Type of action, one of "Tap", "RightClick", "Hover" , "Input", "KeyboardPress", "Scroll", "ExpectedFalsyCondition", "Sleep", "AndroidBackButton", "AndroidHomeButton", "AndroidRecentAppsButton"
|
|
1033
|
+
description: 'Type of action, one of "Tap", "RightClick", "Hover" , "Input", "KeyboardPress", "Scroll", "ExpectedFalsyCondition", "Sleep", "AndroidBackButton", "AndroidHomeButton", "AndroidRecentAppsButton"'
|
|
1009
1034
|
},
|
|
1010
1035
|
param: {
|
|
1011
1036
|
anyOf: [
|
|
@@ -2233,7 +2258,8 @@ async function AiLocateElement(options) {
|
|
|
2233
2258
|
},
|
|
2234
2259
|
rawResponse,
|
|
2235
2260
|
elementById,
|
|
2236
|
-
usage: res.usage
|
|
2261
|
+
usage: res.usage,
|
|
2262
|
+
isOrderSensitive: typeof res.content === "object" && res.content !== null && "isOrderSensitive" in res.content ? res.content.isOrderSensitive : void 0
|
|
2237
2263
|
};
|
|
2238
2264
|
}
|
|
2239
2265
|
async function AiLocateSection(options) {
|
|
@@ -2684,22 +2710,6 @@ async function vlmPlanning(options) {
|
|
|
2684
2710
|
type: "AndroidRecentAppsButton",
|
|
2685
2711
|
param: {}
|
|
2686
2712
|
});
|
|
2687
|
-
} else if (action.action_type === "androidLongPress") {
|
|
2688
|
-
assert6(
|
|
2689
|
-
action.action_inputs.start_coords,
|
|
2690
|
-
"start_coords is required for androidLongPress"
|
|
2691
|
-
);
|
|
2692
|
-
const point = action.action_inputs.start_coords;
|
|
2693
|
-
transformActions.push({
|
|
2694
|
-
type: "AndroidLongPress",
|
|
2695
|
-
param: {
|
|
2696
|
-
x: point[0],
|
|
2697
|
-
y: point[1],
|
|
2698
|
-
duration: 1e3
|
|
2699
|
-
},
|
|
2700
|
-
locate: null,
|
|
2701
|
-
thought: action.thought || ""
|
|
2702
|
-
});
|
|
2703
2713
|
}
|
|
2704
2714
|
});
|
|
2705
2715
|
if (transformActions.length === 0) {
|
|
@@ -2783,4 +2793,4 @@ export {
|
|
|
2783
2793
|
resizeImageForUiTars
|
|
2784
2794
|
};
|
|
2785
2795
|
|
|
2786
|
-
//# sourceMappingURL=chunk-
|
|
2796
|
+
//# sourceMappingURL=chunk-YCHAOUOW.js.map
|