@aiscene/core 8.0.2 → 8.0.3
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/utils.mjs +26 -9
- package/dist/es/agent/utils.mjs.map +1 -1
- package/dist/es/utils.mjs +1 -1
- package/dist/lib/agent/utils.js +26 -9
- package/dist/lib/agent/utils.js.map +1 -1
- package/dist/lib/types.js +5 -5
- package/dist/lib/utils.js +1 -1
- package/package.json +2 -2
- package/dist/types/agent/agent.d.ts +0 -216
- package/dist/types/agent/common.d.ts +0 -0
- package/dist/types/agent/execution-session.d.ts +0 -36
- package/dist/types/agent/index.d.ts +0 -9
- package/dist/types/agent/task-builder.d.ts +0 -34
- package/dist/types/agent/task-cache.d.ts +0 -49
- package/dist/types/agent/tasks.d.ts +0 -69
- package/dist/types/agent/ui-utils.d.ts +0 -14
- package/dist/types/agent/utils.d.ts +0 -25
- package/dist/types/ai-model/auto-glm/actions.d.ts +0 -78
- package/dist/types/ai-model/auto-glm/index.d.ts +0 -6
- package/dist/types/ai-model/auto-glm/parser.d.ts +0 -18
- package/dist/types/ai-model/auto-glm/planning.d.ts +0 -12
- package/dist/types/ai-model/auto-glm/prompt.d.ts +0 -27
- package/dist/types/ai-model/auto-glm/util.d.ts +0 -13
- package/dist/types/ai-model/connectivity.d.ts +0 -20
- package/dist/types/ai-model/conversation-history.d.ts +0 -105
- package/dist/types/ai-model/index.d.ts +0 -16
- package/dist/types/ai-model/inspect.d.ts +0 -67
- package/dist/types/ai-model/llm-planning.d.ts +0 -19
- package/dist/types/ai-model/prompt/common.d.ts +0 -2
- package/dist/types/ai-model/prompt/describe.d.ts +0 -1
- package/dist/types/ai-model/prompt/extraction.d.ts +0 -7
- package/dist/types/ai-model/prompt/llm-locator.d.ts +0 -3
- package/dist/types/ai-model/prompt/llm-planning.d.ts +0 -10
- package/dist/types/ai-model/prompt/llm-section-locator.d.ts +0 -3
- package/dist/types/ai-model/prompt/order-sensitive-judge.d.ts +0 -2
- package/dist/types/ai-model/prompt/playwright-generator.d.ts +0 -26
- package/dist/types/ai-model/prompt/ui-tars-planning.d.ts +0 -2
- package/dist/types/ai-model/prompt/util.d.ts +0 -33
- package/dist/types/ai-model/prompt/yaml-generator.d.ts +0 -102
- package/dist/types/ai-model/service-caller/codex-app-server.d.ts +0 -42
- package/dist/types/ai-model/service-caller/image-detail.d.ts +0 -2
- package/dist/types/ai-model/service-caller/index.d.ts +0 -49
- package/dist/types/ai-model/ui-tars-planning.d.ts +0 -72
- package/dist/types/common.d.ts +0 -288
- package/dist/types/device/device-options.d.ts +0 -145
- package/dist/types/device/index.d.ts +0 -2528
- package/dist/types/dump/html-utils.d.ts +0 -75
- package/dist/types/dump/index.d.ts +0 -5
- package/dist/types/dump/screenshot-restoration.d.ts +0 -8
- package/dist/types/dump/screenshot-store.d.ts +0 -49
- package/dist/types/index.d.ts +0 -21
- package/dist/types/report-cli.d.ts +0 -36
- package/dist/types/report-generator.d.ts +0 -81
- package/dist/types/report-markdown.d.ts +0 -24
- package/dist/types/report.d.ts +0 -52
- package/dist/types/screenshot-item.d.ts +0 -67
- package/dist/types/service/index.d.ts +0 -24
- package/dist/types/service/utils.d.ts +0 -2
- package/dist/types/skill/index.d.ts +0 -25
- package/dist/types/task-runner.d.ts +0 -50
- package/dist/types/task-timing.d.ts +0 -8
- package/dist/types/tree.d.ts +0 -4
- package/dist/types/types.d.ts +0 -681
- package/dist/types/utils.d.ts +0 -45
- package/dist/types/yaml/builder.d.ts +0 -2
- package/dist/types/yaml/index.d.ts +0 -4
- package/dist/types/yaml/player.d.ts +0 -34
- package/dist/types/yaml/utils.d.ts +0 -9
- package/dist/types/yaml.d.ts +0 -215
package/dist/es/agent/utils.mjs
CHANGED
|
@@ -26,14 +26,31 @@ async function commonContextParser(interfaceInstance, _opt) {
|
|
|
26
26
|
if (!Number.isFinite(logicalWidth) || !Number.isFinite(logicalHeight)) throw new Error(`Invalid interface size: width and height must be finite numbers. Received width: ${logicalWidth}, height: ${logicalHeight}`);
|
|
27
27
|
if (logicalWidth <= 0 || logicalHeight <= 0) throw new Error(`Invalid interface size: width and height must be positive numbers. Received width: ${logicalWidth}, height: ${logicalHeight}`);
|
|
28
28
|
debug(`size: ${logicalWidth}x${logicalHeight}`);
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
29
|
+
const maxRetries = 3;
|
|
30
|
+
let lastError = null;
|
|
31
|
+
let screenshotBase64 = null;
|
|
32
|
+
let screenshotCapturedAt = 0;
|
|
33
|
+
let imgWidth = 0;
|
|
34
|
+
let imgHeight = 0;
|
|
35
|
+
for(let attempt = 1; attempt <= maxRetries; attempt++)try {
|
|
36
|
+
screenshotBase64 = await interfaceInstance.screenshotBase64();
|
|
37
|
+
screenshotCapturedAt = Date.now();
|
|
38
|
+
assert(screenshotBase64, 'screenshotBase64 is required');
|
|
39
|
+
debug('will get screenshot dimensions');
|
|
40
|
+
const dimensions = await imageInfoOfBase64(screenshotBase64);
|
|
41
|
+
imgWidth = dimensions.width;
|
|
42
|
+
imgHeight = dimensions.height;
|
|
43
|
+
if (!Number.isFinite(imgWidth) || !Number.isFinite(imgHeight)) throw new Error(`Invalid screenshot dimensions: width and height must be finite numbers. Received width: ${imgWidth}, height: ${imgHeight}`);
|
|
44
|
+
if (imgWidth <= 0 || imgHeight <= 0) throw new Error(`Invalid screenshot dimensions: width and height must be positive numbers. Received width: ${imgWidth}, height: ${imgHeight}`);
|
|
45
|
+
debug('screenshot dimensions', imgWidth, 'x', imgHeight);
|
|
46
|
+
break;
|
|
47
|
+
} catch (error) {
|
|
48
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
49
|
+
debug(`Screenshot capture/decode failed (attempt ${attempt}/${maxRetries}): ${lastError.message}`);
|
|
50
|
+
if (attempt === maxRetries) throw new Error(`Failed to capture valid screenshot after ${maxRetries} attempts: ${lastError.message}`);
|
|
51
|
+
await new Promise((resolve)=>setTimeout(resolve, 500));
|
|
52
|
+
}
|
|
53
|
+
if (!screenshotBase64) throw new Error('Screenshot data is null after retry loop');
|
|
37
54
|
const logicalIsPortrait = logicalWidth < logicalHeight;
|
|
38
55
|
const screenshotIsPortrait = imgWidth < imgHeight;
|
|
39
56
|
let finalLogicalWidth = logicalWidth;
|
|
@@ -123,7 +140,7 @@ async function matchElementFromCache(context, cacheEntry, cachePrompt, cacheable
|
|
|
123
140
|
return;
|
|
124
141
|
}
|
|
125
142
|
}
|
|
126
|
-
const getMidsceneVersion = ()=>"8.0.
|
|
143
|
+
const getMidsceneVersion = ()=>"8.0.3";
|
|
127
144
|
const parsePrompt = (prompt)=>{
|
|
128
145
|
if ('string' == typeof prompt) return {
|
|
129
146
|
textPrompt: prompt,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent/utils.mjs","sources":["../../../src/agent/utils.ts"],"sourcesContent":["import type { TMultimodalPrompt, TUserPrompt } from '@/common';\nimport type { AbstractInterface } from '@/device';\nimport { ScreenshotItem } from '@/screenshot-item';\nimport type {\n ElementCacheFeature,\n LocateResultElement,\n PlanningLocateParam,\n Rect,\n UIContext,\n} from '@/types';\nimport { uploadTestInfoToServer } from '@/utils';\nimport type { TModelFamily } from '@aiscene/shared/env';\nimport {\n MIDSCENE_REPORT_QUIET,\n MIDSCENE_REPORT_TAG_NAME,\n globalConfigManager,\n} from '@aiscene/shared/env';\nimport { generateElementByRect } from '@aiscene/shared/extractor';\nimport { imageInfoOfBase64, resizeImgBase64 } from '@aiscene/shared/img';\nimport { getDebug } from '@aiscene/shared/logger';\nimport { _keyDefinitions } from '@aiscene/shared/us-keyboard-layout';\nimport { assert, logMsg, uuid } from '@aiscene/shared/utils';\nimport dayjs from 'dayjs';\nimport type { TaskCache } from './task-cache';\nimport { debug as cacheDebug } from './task-cache';\n\nexport async function commonContextParser(\n interfaceInstance: AbstractInterface,\n _opt: {\n uploadServerUrl?: string;\n screenshotShrinkFactor?: number;\n modelFamily?: TModelFamily;\n },\n): Promise<UIContext> {\n const debug = getDebug('commonContextParser');\n\n assert(interfaceInstance, 'interfaceInstance is required');\n\n debug('Getting interface description');\n const description = interfaceInstance.describe?.() || '';\n debug('Interface description end');\n\n debug('Uploading test info to server');\n uploadTestInfoToServer({\n testUrl: description,\n serverUrl: _opt.uploadServerUrl,\n });\n debug('UploadTestInfoToServer end');\n\n debug('will get size');\n const interfaceSize = await interfaceInstance.size();\n const { width: logicalWidth, height: logicalHeight } = interfaceSize;\n\n if ((interfaceSize as unknown as { dpr: number }).dpr) {\n console.warn(\n 'Warning: return value of interface.size() include a dpr property, which is not expected and ignored. ',\n );\n }\n\n if (!Number.isFinite(logicalWidth) || !Number.isFinite(logicalHeight)) {\n throw new Error(\n `Invalid interface size: width and height must be finite numbers. Received width: ${logicalWidth}, height: ${logicalHeight}`,\n );\n }\n\n if (logicalWidth <= 0 || logicalHeight <= 0) {\n throw new Error(\n `Invalid interface size: width and height must be positive numbers. Received width: ${logicalWidth}, height: ${logicalHeight}`,\n );\n }\n\n debug(`size: ${logicalWidth}x${logicalHeight}`);\n\n const screenshotBase64 = await interfaceInstance.screenshotBase64();\n const screenshotCapturedAt = Date.now();\n assert(screenshotBase64!, 'screenshotBase64 is required');\n\n // Get physical screenshot dimensions\n debug('will get screenshot dimensions');\n const { width: imgWidth, height: imgHeight } =\n await imageInfoOfBase64(screenshotBase64);\n\n if (!Number.isFinite(imgWidth) || !Number.isFinite(imgHeight)) {\n throw new Error(\n `Invalid screenshot dimensions: width and height must be finite numbers. Received width: ${imgWidth}, height: ${imgHeight}`,\n );\n }\n if (imgWidth <= 0 || imgHeight <= 0) {\n throw new Error(\n `Invalid screenshot dimensions: width and height must be positive numbers. Received width: ${imgWidth}, height: ${imgHeight}`,\n );\n }\n debug('screenshot dimensions', imgWidth, 'x', imgHeight);\n\n // Detect orientation mismatch between logical size and screenshot.\n // Some devices (e.g. OPPO) report wrong orientation via ADB, causing\n // size() to return portrait dimensions even when the device is landscape.\n // We detect this by comparing aspect ratios and swap if they disagree.\n const logicalIsPortrait = logicalWidth < logicalHeight;\n const screenshotIsPortrait = imgWidth < imgHeight;\n let finalLogicalWidth = logicalWidth;\n let finalLogicalHeight = logicalHeight;\n if (logicalIsPortrait !== screenshotIsPortrait) {\n debug(\n `Orientation mismatch detected: logical size ${logicalWidth}x${logicalHeight} (${logicalIsPortrait ? 'portrait' : 'landscape'}) vs screenshot ${imgWidth}x${imgHeight} (${screenshotIsPortrait ? 'portrait' : 'landscape'}). Swapping logical dimensions.`,\n );\n finalLogicalWidth = logicalHeight;\n finalLogicalHeight = logicalWidth;\n }\n\n const userShrinkFactor = _opt.screenshotShrinkFactor ?? 1;\n\n if (!Number.isFinite(userShrinkFactor) || userShrinkFactor < 1) {\n throw new Error(\n `Invalid screenshotShrinkFactor: must be a finite number >= 1. Received: ${userShrinkFactor}`,\n );\n }\n\n const dpr = imgWidth / finalLogicalWidth;\n\n debug('calculated dpr:', dpr);\n\n const shrunkShotToLogicalRatio = dpr / userShrinkFactor;\n\n debug('shrunkShotToLogicalRatio', shrunkShotToLogicalRatio);\n\n if (userShrinkFactor !== 1) {\n const targetWidth = Math.round(imgWidth / userShrinkFactor);\n const targetHeight = Math.round(imgHeight / userShrinkFactor);\n\n debug(\n `Applying screenshot shrink factor: ${userShrinkFactor} (physical: ${imgWidth}x${imgHeight} -> target: ${targetWidth}x${targetHeight})`,\n );\n\n const resizedBase64 = await resizeImgBase64(screenshotBase64, {\n width: targetWidth,\n height: targetHeight,\n });\n return {\n shotSize: {\n width: targetWidth,\n height: targetHeight,\n },\n deprecatedDpr: dpr,\n screenshot: ScreenshotItem.create(resizedBase64, screenshotCapturedAt),\n shrunkShotToLogicalRatio,\n };\n }\n\n return {\n shotSize: {\n width: imgWidth,\n height: imgHeight,\n },\n deprecatedDpr: dpr,\n screenshot: ScreenshotItem.create(screenshotBase64, screenshotCapturedAt),\n shrunkShotToLogicalRatio,\n };\n}\n\nexport function getReportFileName(tag = 'web') {\n const reportTagName = globalConfigManager.getEnvConfigValue(\n MIDSCENE_REPORT_TAG_NAME,\n );\n const dateTimeInFileName = dayjs().format('YYYY-MM-DD_HH-mm-ss');\n // ensure uniqueness at the same time\n const uniqueId = uuid().substring(0, 8);\n return `${reportTagName || tag}-${dateTimeInFileName}-${uniqueId}`;\n}\n\nexport function printReportMsg(filepath: string) {\n if (globalConfigManager.getEnvConfigInBoolean(MIDSCENE_REPORT_QUIET)) {\n return;\n }\n logMsg(`Midscene - report file updated: ${filepath}`);\n}\n\nexport function ifPlanLocateParamIsBbox(\n planLocateParam: PlanningLocateParam,\n): boolean {\n return !!(\n planLocateParam.bbox &&\n Array.isArray(planLocateParam.bbox) &&\n planLocateParam.bbox.length === 4\n );\n}\n\nexport function matchElementFromPlan(\n planLocateParam: PlanningLocateParam,\n): LocateResultElement | undefined {\n if (!planLocateParam) {\n return undefined;\n }\n\n if (planLocateParam.bbox) {\n // Convert bbox [x1, y1, x2, y2] to rect {left, top, width, height}\n const rect = {\n left: planLocateParam.bbox[0],\n top: planLocateParam.bbox[1],\n width: planLocateParam.bbox[2] - planLocateParam.bbox[0] + 1,\n height: planLocateParam.bbox[3] - planLocateParam.bbox[1] + 1,\n };\n\n const element = generateElementByRect(\n rect,\n typeof planLocateParam.prompt === 'string'\n ? planLocateParam.prompt\n : planLocateParam.prompt?.prompt || '',\n );\n return element;\n }\n\n return undefined;\n}\n\nexport async function matchElementFromCache(\n context: {\n taskCache?: TaskCache;\n interfaceInstance: AbstractInterface;\n },\n cacheEntry: ElementCacheFeature | undefined,\n cachePrompt: TUserPrompt,\n cacheable: boolean | undefined,\n): Promise<LocateResultElement | undefined> {\n if (!cacheEntry) {\n return undefined;\n }\n\n if (cacheable === false) {\n cacheDebug('cache disabled for prompt: %s', cachePrompt);\n return undefined;\n }\n\n if (!context.taskCache?.isCacheResultUsed) {\n return undefined;\n }\n\n if (!context.interfaceInstance.rectMatchesCacheFeature) {\n cacheDebug(\n 'interface does not implement rectMatchesCacheFeature, skip cache',\n );\n return undefined;\n }\n\n try {\n const rect =\n await context.interfaceInstance.rectMatchesCacheFeature(cacheEntry);\n const element: LocateResultElement = {\n center: [\n Math.round(rect.left + rect.width / 2),\n Math.round(rect.top + rect.height / 2),\n ],\n rect,\n description:\n typeof cachePrompt === 'string'\n ? cachePrompt\n : cachePrompt.prompt || '',\n };\n\n cacheDebug('cache hit, prompt: %s', cachePrompt);\n return element;\n } catch (error) {\n cacheDebug('rectMatchesCacheFeature error: %s', error);\n return undefined;\n }\n}\n\ndeclare const __VERSION__: string | undefined;\n\nexport const getMidsceneVersion = (): string => {\n if (typeof __VERSION__ !== 'undefined') {\n return __VERSION__;\n } else if (\n process.env.__VERSION__ &&\n process.env.__VERSION__ !== 'undefined'\n ) {\n return process.env.__VERSION__;\n }\n throw new Error('__VERSION__ inject failed during build');\n};\n\nexport const parsePrompt = (\n prompt: TUserPrompt,\n): {\n textPrompt: string;\n multimodalPrompt?: TMultimodalPrompt;\n} => {\n if (typeof prompt === 'string') {\n return {\n textPrompt: prompt,\n multimodalPrompt: undefined,\n };\n }\n return {\n textPrompt: prompt.prompt,\n multimodalPrompt: prompt.images\n ? {\n images: prompt.images,\n convertHttpImage2Base64: !!prompt.convertHttpImage2Base64,\n }\n : undefined,\n };\n};\n\nexport const transformLogicalElementToScreenshot = (\n element: LocateResultElement,\n shrunkShotToLogicalRatio: number,\n): LocateResultElement => {\n if (shrunkShotToLogicalRatio === 1) {\n return element;\n }\n\n return {\n ...element,\n center: [\n Math.round(element.center[0] * shrunkShotToLogicalRatio),\n Math.round(element.center[1] * shrunkShotToLogicalRatio),\n ],\n rect: {\n ...element.rect,\n left: Math.round(element.rect.left * shrunkShotToLogicalRatio),\n top: Math.round(element.rect.top * shrunkShotToLogicalRatio),\n width: Math.round(element.rect.width * shrunkShotToLogicalRatio),\n height: Math.round(element.rect.height * shrunkShotToLogicalRatio),\n },\n };\n};\n\nexport const transformLogicalRectToScreenshotRect = (\n rect: Rect,\n shrunkShotToLogicalRatio: number,\n): Rect => {\n if (shrunkShotToLogicalRatio === 1) {\n return rect;\n }\n\n return {\n ...rect,\n left: Math.round(rect.left * shrunkShotToLogicalRatio),\n top: Math.round(rect.top * shrunkShotToLogicalRatio),\n width: Math.round(rect.width * shrunkShotToLogicalRatio),\n height: Math.round(rect.height * shrunkShotToLogicalRatio),\n };\n};\n"],"names":["commonContextParser","interfaceInstance","_opt","debug","getDebug","assert","description","uploadTestInfoToServer","interfaceSize","logicalWidth","logicalHeight","console","Number","Error","screenshotBase64","screenshotCapturedAt","Date","imgWidth","imgHeight","imageInfoOfBase64","logicalIsPortrait","screenshotIsPortrait","finalLogicalWidth","userShrinkFactor","dpr","shrunkShotToLogicalRatio","targetWidth","Math","targetHeight","resizedBase64","resizeImgBase64","ScreenshotItem","getReportFileName","tag","reportTagName","globalConfigManager","MIDSCENE_REPORT_TAG_NAME","dateTimeInFileName","dayjs","uniqueId","uuid","printReportMsg","filepath","MIDSCENE_REPORT_QUIET","logMsg","ifPlanLocateParamIsBbox","planLocateParam","Array","matchElementFromPlan","rect","element","generateElementByRect","matchElementFromCache","context","cacheEntry","cachePrompt","cacheable","cacheDebug","error","getMidsceneVersion","__VERSION__","parsePrompt","prompt","undefined","transformLogicalElementToScreenshot","transformLogicalRectToScreenshotRect"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"agent/utils.mjs","sources":["../../../src/agent/utils.ts"],"sourcesContent":["import type { TMultimodalPrompt, TUserPrompt } from '@/common';\nimport type { AbstractInterface } from '@/device';\nimport { ScreenshotItem } from '@/screenshot-item';\nimport type {\n ElementCacheFeature,\n LocateResultElement,\n PlanningLocateParam,\n Rect,\n UIContext,\n} from '@/types';\nimport { uploadTestInfoToServer } from '@/utils';\nimport type { TModelFamily } from '@aiscene/shared/env';\nimport {\n MIDSCENE_REPORT_QUIET,\n MIDSCENE_REPORT_TAG_NAME,\n globalConfigManager,\n} from '@aiscene/shared/env';\nimport { generateElementByRect } from '@aiscene/shared/extractor';\nimport { imageInfoOfBase64, resizeImgBase64 } from '@aiscene/shared/img';\nimport { getDebug } from '@aiscene/shared/logger';\nimport { _keyDefinitions } from '@aiscene/shared/us-keyboard-layout';\nimport { assert, logMsg, uuid } from '@aiscene/shared/utils';\nimport dayjs from 'dayjs';\nimport type { TaskCache } from './task-cache';\nimport { debug as cacheDebug } from './task-cache';\n\nexport async function commonContextParser(\n interfaceInstance: AbstractInterface,\n _opt: {\n uploadServerUrl?: string;\n screenshotShrinkFactor?: number;\n modelFamily?: TModelFamily;\n },\n): Promise<UIContext> {\n const debug = getDebug('commonContextParser');\n\n assert(interfaceInstance, 'interfaceInstance is required');\n\n debug('Getting interface description');\n const description = interfaceInstance.describe?.() || '';\n debug('Interface description end');\n\n debug('Uploading test info to server');\n uploadTestInfoToServer({\n testUrl: description,\n serverUrl: _opt.uploadServerUrl,\n });\n debug('UploadTestInfoToServer end');\n\n debug('will get size');\n const interfaceSize = await interfaceInstance.size();\n const { width: logicalWidth, height: logicalHeight } = interfaceSize;\n\n if ((interfaceSize as unknown as { dpr: number }).dpr) {\n console.warn(\n 'Warning: return value of interface.size() include a dpr property, which is not expected and ignored. ',\n );\n }\n\n if (!Number.isFinite(logicalWidth) || !Number.isFinite(logicalHeight)) {\n throw new Error(\n `Invalid interface size: width and height must be finite numbers. Received width: ${logicalWidth}, height: ${logicalHeight}`,\n );\n }\n\n if (logicalWidth <= 0 || logicalHeight <= 0) {\n throw new Error(\n `Invalid interface size: width and height must be positive numbers. Received width: ${logicalWidth}, height: ${logicalHeight}`,\n );\n }\n\n debug(`size: ${logicalWidth}x${logicalHeight}`);\n\n // Retry logic for screenshot capture/decoding\n const maxRetries = 3;\n let lastError: Error | null = null;\n let screenshotBase64: string | null = null;\n let screenshotCapturedAt = 0;\n let imgWidth: number = 0;\n let imgHeight: number = 0;\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n try {\n screenshotBase64 = await interfaceInstance.screenshotBase64();\n screenshotCapturedAt = Date.now();\n assert(screenshotBase64!, 'screenshotBase64 is required');\n\n // Get physical screenshot dimensions\n debug('will get screenshot dimensions');\n const dimensions = await imageInfoOfBase64(screenshotBase64);\n imgWidth = dimensions.width;\n imgHeight = dimensions.height;\n\n // Validate dimensions\n if (!Number.isFinite(imgWidth) || !Number.isFinite(imgHeight)) {\n throw new Error(\n `Invalid screenshot dimensions: width and height must be finite numbers. Received width: ${imgWidth}, height: ${imgHeight}`,\n );\n }\n if (imgWidth <= 0 || imgHeight <= 0) {\n throw new Error(\n `Invalid screenshot dimensions: width and height must be positive numbers. Received width: ${imgWidth}, height: ${imgHeight}`,\n );\n }\n\n // If we get here, screenshot is valid\n debug('screenshot dimensions', imgWidth, 'x', imgHeight);\n break;\n } catch (error) {\n lastError =\n error instanceof Error ? error : new Error(String(error));\n debug(\n `Screenshot capture/decode failed (attempt ${attempt}/${maxRetries}): ${lastError.message}`,\n );\n\n if (attempt === maxRetries) {\n throw new Error(\n `Failed to capture valid screenshot after ${maxRetries} attempts: ${lastError.message}`,\n );\n }\n\n // Wait before retrying\n await new Promise((resolve) => setTimeout(resolve, 500));\n }\n }\n\n // This should never be null if we got past the retry loop\n if (!screenshotBase64) {\n throw new Error('Screenshot data is null after retry loop');\n }\n\n // Detect orientation mismatch between logical size and screenshot.\n // Some devices (e.g. OPPO) report wrong orientation via ADB, causing\n // size() to return portrait dimensions even when the device is landscape.\n // We detect this by comparing aspect ratios and swap if they disagree.\n const logicalIsPortrait = logicalWidth < logicalHeight;\n const screenshotIsPortrait = imgWidth < imgHeight;\n let finalLogicalWidth = logicalWidth;\n let finalLogicalHeight = logicalHeight;\n if (logicalIsPortrait !== screenshotIsPortrait) {\n debug(\n `Orientation mismatch detected: logical size ${logicalWidth}x${logicalHeight} (${logicalIsPortrait ? 'portrait' : 'landscape'}) vs screenshot ${imgWidth}x${imgHeight} (${screenshotIsPortrait ? 'portrait' : 'landscape'}). Swapping logical dimensions.`,\n );\n finalLogicalWidth = logicalHeight;\n finalLogicalHeight = logicalWidth;\n }\n\n const userShrinkFactor = _opt.screenshotShrinkFactor ?? 1;\n\n if (!Number.isFinite(userShrinkFactor) || userShrinkFactor < 1) {\n throw new Error(\n `Invalid screenshotShrinkFactor: must be a finite number >= 1. Received: ${userShrinkFactor}`,\n );\n }\n\n const dpr = imgWidth / finalLogicalWidth;\n\n debug('calculated dpr:', dpr);\n\n const shrunkShotToLogicalRatio = dpr / userShrinkFactor;\n\n debug('shrunkShotToLogicalRatio', shrunkShotToLogicalRatio);\n\n if (userShrinkFactor !== 1) {\n const targetWidth = Math.round(imgWidth / userShrinkFactor);\n const targetHeight = Math.round(imgHeight / userShrinkFactor);\n\n debug(\n `Applying screenshot shrink factor: ${userShrinkFactor} (physical: ${imgWidth}x${imgHeight} -> target: ${targetWidth}x${targetHeight})`,\n );\n\n const resizedBase64 = await resizeImgBase64(screenshotBase64, {\n width: targetWidth,\n height: targetHeight,\n });\n return {\n shotSize: {\n width: targetWidth,\n height: targetHeight,\n },\n deprecatedDpr: dpr,\n screenshot: ScreenshotItem.create(resizedBase64, screenshotCapturedAt),\n shrunkShotToLogicalRatio,\n };\n }\n\n return {\n shotSize: {\n width: imgWidth,\n height: imgHeight,\n },\n deprecatedDpr: dpr,\n screenshot: ScreenshotItem.create(screenshotBase64, screenshotCapturedAt),\n shrunkShotToLogicalRatio,\n };\n}\n\nexport function getReportFileName(tag = 'web') {\n const reportTagName = globalConfigManager.getEnvConfigValue(\n MIDSCENE_REPORT_TAG_NAME,\n );\n const dateTimeInFileName = dayjs().format('YYYY-MM-DD_HH-mm-ss');\n // ensure uniqueness at the same time\n const uniqueId = uuid().substring(0, 8);\n return `${reportTagName || tag}-${dateTimeInFileName}-${uniqueId}`;\n}\n\nexport function printReportMsg(filepath: string) {\n if (globalConfigManager.getEnvConfigInBoolean(MIDSCENE_REPORT_QUIET)) {\n return;\n }\n logMsg(`Midscene - report file updated: ${filepath}`);\n}\n\nexport function ifPlanLocateParamIsBbox(\n planLocateParam: PlanningLocateParam,\n): boolean {\n return !!(\n planLocateParam.bbox &&\n Array.isArray(planLocateParam.bbox) &&\n planLocateParam.bbox.length === 4\n );\n}\n\nexport function matchElementFromPlan(\n planLocateParam: PlanningLocateParam,\n): LocateResultElement | undefined {\n if (!planLocateParam) {\n return undefined;\n }\n\n if (planLocateParam.bbox) {\n // Convert bbox [x1, y1, x2, y2] to rect {left, top, width, height}\n const rect = {\n left: planLocateParam.bbox[0],\n top: planLocateParam.bbox[1],\n width: planLocateParam.bbox[2] - planLocateParam.bbox[0] + 1,\n height: planLocateParam.bbox[3] - planLocateParam.bbox[1] + 1,\n };\n\n const element = generateElementByRect(\n rect,\n typeof planLocateParam.prompt === 'string'\n ? planLocateParam.prompt\n : planLocateParam.prompt?.prompt || '',\n );\n return element;\n }\n\n return undefined;\n}\n\nexport async function matchElementFromCache(\n context: {\n taskCache?: TaskCache;\n interfaceInstance: AbstractInterface;\n },\n cacheEntry: ElementCacheFeature | undefined,\n cachePrompt: TUserPrompt,\n cacheable: boolean | undefined,\n): Promise<LocateResultElement | undefined> {\n if (!cacheEntry) {\n return undefined;\n }\n\n if (cacheable === false) {\n cacheDebug('cache disabled for prompt: %s', cachePrompt);\n return undefined;\n }\n\n if (!context.taskCache?.isCacheResultUsed) {\n return undefined;\n }\n\n if (!context.interfaceInstance.rectMatchesCacheFeature) {\n cacheDebug(\n 'interface does not implement rectMatchesCacheFeature, skip cache',\n );\n return undefined;\n }\n\n try {\n const rect =\n await context.interfaceInstance.rectMatchesCacheFeature(cacheEntry);\n const element: LocateResultElement = {\n center: [\n Math.round(rect.left + rect.width / 2),\n Math.round(rect.top + rect.height / 2),\n ],\n rect,\n description:\n typeof cachePrompt === 'string'\n ? cachePrompt\n : cachePrompt.prompt || '',\n };\n\n cacheDebug('cache hit, prompt: %s', cachePrompt);\n return element;\n } catch (error) {\n cacheDebug('rectMatchesCacheFeature error: %s', error);\n return undefined;\n }\n}\n\ndeclare const __VERSION__: string | undefined;\n\nexport const getMidsceneVersion = (): string => {\n if (typeof __VERSION__ !== 'undefined') {\n return __VERSION__;\n } else if (\n process.env.__VERSION__ &&\n process.env.__VERSION__ !== 'undefined'\n ) {\n return process.env.__VERSION__;\n }\n throw new Error('__VERSION__ inject failed during build');\n};\n\nexport const parsePrompt = (\n prompt: TUserPrompt,\n): {\n textPrompt: string;\n multimodalPrompt?: TMultimodalPrompt;\n} => {\n if (typeof prompt === 'string') {\n return {\n textPrompt: prompt,\n multimodalPrompt: undefined,\n };\n }\n return {\n textPrompt: prompt.prompt,\n multimodalPrompt: prompt.images\n ? {\n images: prompt.images,\n convertHttpImage2Base64: !!prompt.convertHttpImage2Base64,\n }\n : undefined,\n };\n};\n\nexport const transformLogicalElementToScreenshot = (\n element: LocateResultElement,\n shrunkShotToLogicalRatio: number,\n): LocateResultElement => {\n if (shrunkShotToLogicalRatio === 1) {\n return element;\n }\n\n return {\n ...element,\n center: [\n Math.round(element.center[0] * shrunkShotToLogicalRatio),\n Math.round(element.center[1] * shrunkShotToLogicalRatio),\n ],\n rect: {\n ...element.rect,\n left: Math.round(element.rect.left * shrunkShotToLogicalRatio),\n top: Math.round(element.rect.top * shrunkShotToLogicalRatio),\n width: Math.round(element.rect.width * shrunkShotToLogicalRatio),\n height: Math.round(element.rect.height * shrunkShotToLogicalRatio),\n },\n };\n};\n\nexport const transformLogicalRectToScreenshotRect = (\n rect: Rect,\n shrunkShotToLogicalRatio: number,\n): Rect => {\n if (shrunkShotToLogicalRatio === 1) {\n return rect;\n }\n\n return {\n ...rect,\n left: Math.round(rect.left * shrunkShotToLogicalRatio),\n top: Math.round(rect.top * shrunkShotToLogicalRatio),\n width: Math.round(rect.width * shrunkShotToLogicalRatio),\n height: Math.round(rect.height * shrunkShotToLogicalRatio),\n };\n};\n"],"names":["commonContextParser","interfaceInstance","_opt","debug","getDebug","assert","description","uploadTestInfoToServer","interfaceSize","logicalWidth","logicalHeight","console","Number","Error","maxRetries","lastError","screenshotBase64","screenshotCapturedAt","imgWidth","imgHeight","attempt","Date","dimensions","imageInfoOfBase64","error","String","Promise","resolve","setTimeout","logicalIsPortrait","screenshotIsPortrait","finalLogicalWidth","userShrinkFactor","dpr","shrunkShotToLogicalRatio","targetWidth","Math","targetHeight","resizedBase64","resizeImgBase64","ScreenshotItem","getReportFileName","tag","reportTagName","globalConfigManager","MIDSCENE_REPORT_TAG_NAME","dateTimeInFileName","dayjs","uniqueId","uuid","printReportMsg","filepath","MIDSCENE_REPORT_QUIET","logMsg","ifPlanLocateParamIsBbox","planLocateParam","Array","matchElementFromPlan","rect","element","generateElementByRect","matchElementFromCache","context","cacheEntry","cachePrompt","cacheable","cacheDebug","getMidsceneVersion","__VERSION__","parsePrompt","prompt","undefined","transformLogicalElementToScreenshot","transformLogicalRectToScreenshotRect"],"mappings":"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"}
|
package/dist/es/utils.mjs
CHANGED
|
@@ -175,7 +175,7 @@ function stringifyDumpData(data, indents) {
|
|
|
175
175
|
return JSON.stringify(data, replacerForPageObject, indents);
|
|
176
176
|
}
|
|
177
177
|
function getVersion() {
|
|
178
|
-
return "8.0.
|
|
178
|
+
return "8.0.3";
|
|
179
179
|
}
|
|
180
180
|
function debugLog(...message) {
|
|
181
181
|
const debugMode = process.env[MIDSCENE_DEBUG_MODE];
|
package/dist/lib/agent/utils.js
CHANGED
|
@@ -73,14 +73,31 @@ async function commonContextParser(interfaceInstance, _opt) {
|
|
|
73
73
|
if (!Number.isFinite(logicalWidth) || !Number.isFinite(logicalHeight)) throw new Error(`Invalid interface size: width and height must be finite numbers. Received width: ${logicalWidth}, height: ${logicalHeight}`);
|
|
74
74
|
if (logicalWidth <= 0 || logicalHeight <= 0) throw new Error(`Invalid interface size: width and height must be positive numbers. Received width: ${logicalWidth}, height: ${logicalHeight}`);
|
|
75
75
|
debug(`size: ${logicalWidth}x${logicalHeight}`);
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
76
|
+
const maxRetries = 3;
|
|
77
|
+
let lastError = null;
|
|
78
|
+
let screenshotBase64 = null;
|
|
79
|
+
let screenshotCapturedAt = 0;
|
|
80
|
+
let imgWidth = 0;
|
|
81
|
+
let imgHeight = 0;
|
|
82
|
+
for(let attempt = 1; attempt <= maxRetries; attempt++)try {
|
|
83
|
+
screenshotBase64 = await interfaceInstance.screenshotBase64();
|
|
84
|
+
screenshotCapturedAt = Date.now();
|
|
85
|
+
(0, utils_namespaceObject.assert)(screenshotBase64, 'screenshotBase64 is required');
|
|
86
|
+
debug('will get screenshot dimensions');
|
|
87
|
+
const dimensions = await (0, img_namespaceObject.imageInfoOfBase64)(screenshotBase64);
|
|
88
|
+
imgWidth = dimensions.width;
|
|
89
|
+
imgHeight = dimensions.height;
|
|
90
|
+
if (!Number.isFinite(imgWidth) || !Number.isFinite(imgHeight)) throw new Error(`Invalid screenshot dimensions: width and height must be finite numbers. Received width: ${imgWidth}, height: ${imgHeight}`);
|
|
91
|
+
if (imgWidth <= 0 || imgHeight <= 0) throw new Error(`Invalid screenshot dimensions: width and height must be positive numbers. Received width: ${imgWidth}, height: ${imgHeight}`);
|
|
92
|
+
debug('screenshot dimensions', imgWidth, 'x', imgHeight);
|
|
93
|
+
break;
|
|
94
|
+
} catch (error) {
|
|
95
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
96
|
+
debug(`Screenshot capture/decode failed (attempt ${attempt}/${maxRetries}): ${lastError.message}`);
|
|
97
|
+
if (attempt === maxRetries) throw new Error(`Failed to capture valid screenshot after ${maxRetries} attempts: ${lastError.message}`);
|
|
98
|
+
await new Promise((resolve)=>setTimeout(resolve, 500));
|
|
99
|
+
}
|
|
100
|
+
if (!screenshotBase64) throw new Error('Screenshot data is null after retry loop');
|
|
84
101
|
const logicalIsPortrait = logicalWidth < logicalHeight;
|
|
85
102
|
const screenshotIsPortrait = imgWidth < imgHeight;
|
|
86
103
|
let finalLogicalWidth = logicalWidth;
|
|
@@ -170,7 +187,7 @@ async function matchElementFromCache(context, cacheEntry, cachePrompt, cacheable
|
|
|
170
187
|
return;
|
|
171
188
|
}
|
|
172
189
|
}
|
|
173
|
-
const getMidsceneVersion = ()=>"8.0.
|
|
190
|
+
const getMidsceneVersion = ()=>"8.0.3";
|
|
174
191
|
const parsePrompt = (prompt)=>{
|
|
175
192
|
if ('string' == typeof prompt) return {
|
|
176
193
|
textPrompt: prompt,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent/utils.js","sources":["webpack/runtime/compat_get_default_export","webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/agent/utils.ts"],"sourcesContent":["// getDefaultExport function for compatibility with non-ESM modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};\n","__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import type { TMultimodalPrompt, TUserPrompt } from '@/common';\nimport type { AbstractInterface } from '@/device';\nimport { ScreenshotItem } from '@/screenshot-item';\nimport type {\n ElementCacheFeature,\n LocateResultElement,\n PlanningLocateParam,\n Rect,\n UIContext,\n} from '@/types';\nimport { uploadTestInfoToServer } from '@/utils';\nimport type { TModelFamily } from '@aiscene/shared/env';\nimport {\n MIDSCENE_REPORT_QUIET,\n MIDSCENE_REPORT_TAG_NAME,\n globalConfigManager,\n} from '@aiscene/shared/env';\nimport { generateElementByRect } from '@aiscene/shared/extractor';\nimport { imageInfoOfBase64, resizeImgBase64 } from '@aiscene/shared/img';\nimport { getDebug } from '@aiscene/shared/logger';\nimport { _keyDefinitions } from '@aiscene/shared/us-keyboard-layout';\nimport { assert, logMsg, uuid } from '@aiscene/shared/utils';\nimport dayjs from 'dayjs';\nimport type { TaskCache } from './task-cache';\nimport { debug as cacheDebug } from './task-cache';\n\nexport async function commonContextParser(\n interfaceInstance: AbstractInterface,\n _opt: {\n uploadServerUrl?: string;\n screenshotShrinkFactor?: number;\n modelFamily?: TModelFamily;\n },\n): Promise<UIContext> {\n const debug = getDebug('commonContextParser');\n\n assert(interfaceInstance, 'interfaceInstance is required');\n\n debug('Getting interface description');\n const description = interfaceInstance.describe?.() || '';\n debug('Interface description end');\n\n debug('Uploading test info to server');\n uploadTestInfoToServer({\n testUrl: description,\n serverUrl: _opt.uploadServerUrl,\n });\n debug('UploadTestInfoToServer end');\n\n debug('will get size');\n const interfaceSize = await interfaceInstance.size();\n const { width: logicalWidth, height: logicalHeight } = interfaceSize;\n\n if ((interfaceSize as unknown as { dpr: number }).dpr) {\n console.warn(\n 'Warning: return value of interface.size() include a dpr property, which is not expected and ignored. ',\n );\n }\n\n if (!Number.isFinite(logicalWidth) || !Number.isFinite(logicalHeight)) {\n throw new Error(\n `Invalid interface size: width and height must be finite numbers. Received width: ${logicalWidth}, height: ${logicalHeight}`,\n );\n }\n\n if (logicalWidth <= 0 || logicalHeight <= 0) {\n throw new Error(\n `Invalid interface size: width and height must be positive numbers. Received width: ${logicalWidth}, height: ${logicalHeight}`,\n );\n }\n\n debug(`size: ${logicalWidth}x${logicalHeight}`);\n\n const screenshotBase64 = await interfaceInstance.screenshotBase64();\n const screenshotCapturedAt = Date.now();\n assert(screenshotBase64!, 'screenshotBase64 is required');\n\n // Get physical screenshot dimensions\n debug('will get screenshot dimensions');\n const { width: imgWidth, height: imgHeight } =\n await imageInfoOfBase64(screenshotBase64);\n\n if (!Number.isFinite(imgWidth) || !Number.isFinite(imgHeight)) {\n throw new Error(\n `Invalid screenshot dimensions: width and height must be finite numbers. Received width: ${imgWidth}, height: ${imgHeight}`,\n );\n }\n if (imgWidth <= 0 || imgHeight <= 0) {\n throw new Error(\n `Invalid screenshot dimensions: width and height must be positive numbers. Received width: ${imgWidth}, height: ${imgHeight}`,\n );\n }\n debug('screenshot dimensions', imgWidth, 'x', imgHeight);\n\n // Detect orientation mismatch between logical size and screenshot.\n // Some devices (e.g. OPPO) report wrong orientation via ADB, causing\n // size() to return portrait dimensions even when the device is landscape.\n // We detect this by comparing aspect ratios and swap if they disagree.\n const logicalIsPortrait = logicalWidth < logicalHeight;\n const screenshotIsPortrait = imgWidth < imgHeight;\n let finalLogicalWidth = logicalWidth;\n let finalLogicalHeight = logicalHeight;\n if (logicalIsPortrait !== screenshotIsPortrait) {\n debug(\n `Orientation mismatch detected: logical size ${logicalWidth}x${logicalHeight} (${logicalIsPortrait ? 'portrait' : 'landscape'}) vs screenshot ${imgWidth}x${imgHeight} (${screenshotIsPortrait ? 'portrait' : 'landscape'}). Swapping logical dimensions.`,\n );\n finalLogicalWidth = logicalHeight;\n finalLogicalHeight = logicalWidth;\n }\n\n const userShrinkFactor = _opt.screenshotShrinkFactor ?? 1;\n\n if (!Number.isFinite(userShrinkFactor) || userShrinkFactor < 1) {\n throw new Error(\n `Invalid screenshotShrinkFactor: must be a finite number >= 1. Received: ${userShrinkFactor}`,\n );\n }\n\n const dpr = imgWidth / finalLogicalWidth;\n\n debug('calculated dpr:', dpr);\n\n const shrunkShotToLogicalRatio = dpr / userShrinkFactor;\n\n debug('shrunkShotToLogicalRatio', shrunkShotToLogicalRatio);\n\n if (userShrinkFactor !== 1) {\n const targetWidth = Math.round(imgWidth / userShrinkFactor);\n const targetHeight = Math.round(imgHeight / userShrinkFactor);\n\n debug(\n `Applying screenshot shrink factor: ${userShrinkFactor} (physical: ${imgWidth}x${imgHeight} -> target: ${targetWidth}x${targetHeight})`,\n );\n\n const resizedBase64 = await resizeImgBase64(screenshotBase64, {\n width: targetWidth,\n height: targetHeight,\n });\n return {\n shotSize: {\n width: targetWidth,\n height: targetHeight,\n },\n deprecatedDpr: dpr,\n screenshot: ScreenshotItem.create(resizedBase64, screenshotCapturedAt),\n shrunkShotToLogicalRatio,\n };\n }\n\n return {\n shotSize: {\n width: imgWidth,\n height: imgHeight,\n },\n deprecatedDpr: dpr,\n screenshot: ScreenshotItem.create(screenshotBase64, screenshotCapturedAt),\n shrunkShotToLogicalRatio,\n };\n}\n\nexport function getReportFileName(tag = 'web') {\n const reportTagName = globalConfigManager.getEnvConfigValue(\n MIDSCENE_REPORT_TAG_NAME,\n );\n const dateTimeInFileName = dayjs().format('YYYY-MM-DD_HH-mm-ss');\n // ensure uniqueness at the same time\n const uniqueId = uuid().substring(0, 8);\n return `${reportTagName || tag}-${dateTimeInFileName}-${uniqueId}`;\n}\n\nexport function printReportMsg(filepath: string) {\n if (globalConfigManager.getEnvConfigInBoolean(MIDSCENE_REPORT_QUIET)) {\n return;\n }\n logMsg(`Midscene - report file updated: ${filepath}`);\n}\n\nexport function ifPlanLocateParamIsBbox(\n planLocateParam: PlanningLocateParam,\n): boolean {\n return !!(\n planLocateParam.bbox &&\n Array.isArray(planLocateParam.bbox) &&\n planLocateParam.bbox.length === 4\n );\n}\n\nexport function matchElementFromPlan(\n planLocateParam: PlanningLocateParam,\n): LocateResultElement | undefined {\n if (!planLocateParam) {\n return undefined;\n }\n\n if (planLocateParam.bbox) {\n // Convert bbox [x1, y1, x2, y2] to rect {left, top, width, height}\n const rect = {\n left: planLocateParam.bbox[0],\n top: planLocateParam.bbox[1],\n width: planLocateParam.bbox[2] - planLocateParam.bbox[0] + 1,\n height: planLocateParam.bbox[3] - planLocateParam.bbox[1] + 1,\n };\n\n const element = generateElementByRect(\n rect,\n typeof planLocateParam.prompt === 'string'\n ? planLocateParam.prompt\n : planLocateParam.prompt?.prompt || '',\n );\n return element;\n }\n\n return undefined;\n}\n\nexport async function matchElementFromCache(\n context: {\n taskCache?: TaskCache;\n interfaceInstance: AbstractInterface;\n },\n cacheEntry: ElementCacheFeature | undefined,\n cachePrompt: TUserPrompt,\n cacheable: boolean | undefined,\n): Promise<LocateResultElement | undefined> {\n if (!cacheEntry) {\n return undefined;\n }\n\n if (cacheable === false) {\n cacheDebug('cache disabled for prompt: %s', cachePrompt);\n return undefined;\n }\n\n if (!context.taskCache?.isCacheResultUsed) {\n return undefined;\n }\n\n if (!context.interfaceInstance.rectMatchesCacheFeature) {\n cacheDebug(\n 'interface does not implement rectMatchesCacheFeature, skip cache',\n );\n return undefined;\n }\n\n try {\n const rect =\n await context.interfaceInstance.rectMatchesCacheFeature(cacheEntry);\n const element: LocateResultElement = {\n center: [\n Math.round(rect.left + rect.width / 2),\n Math.round(rect.top + rect.height / 2),\n ],\n rect,\n description:\n typeof cachePrompt === 'string'\n ? cachePrompt\n : cachePrompt.prompt || '',\n };\n\n cacheDebug('cache hit, prompt: %s', cachePrompt);\n return element;\n } catch (error) {\n cacheDebug('rectMatchesCacheFeature error: %s', error);\n return undefined;\n }\n}\n\ndeclare const __VERSION__: string | undefined;\n\nexport const getMidsceneVersion = (): string => {\n if (typeof __VERSION__ !== 'undefined') {\n return __VERSION__;\n } else if (\n process.env.__VERSION__ &&\n process.env.__VERSION__ !== 'undefined'\n ) {\n return process.env.__VERSION__;\n }\n throw new Error('__VERSION__ inject failed during build');\n};\n\nexport const parsePrompt = (\n prompt: TUserPrompt,\n): {\n textPrompt: string;\n multimodalPrompt?: TMultimodalPrompt;\n} => {\n if (typeof prompt === 'string') {\n return {\n textPrompt: prompt,\n multimodalPrompt: undefined,\n };\n }\n return {\n textPrompt: prompt.prompt,\n multimodalPrompt: prompt.images\n ? {\n images: prompt.images,\n convertHttpImage2Base64: !!prompt.convertHttpImage2Base64,\n }\n : undefined,\n };\n};\n\nexport const transformLogicalElementToScreenshot = (\n element: LocateResultElement,\n shrunkShotToLogicalRatio: number,\n): LocateResultElement => {\n if (shrunkShotToLogicalRatio === 1) {\n return element;\n }\n\n return {\n ...element,\n center: [\n Math.round(element.center[0] * shrunkShotToLogicalRatio),\n Math.round(element.center[1] * shrunkShotToLogicalRatio),\n ],\n rect: {\n ...element.rect,\n left: Math.round(element.rect.left * shrunkShotToLogicalRatio),\n top: Math.round(element.rect.top * shrunkShotToLogicalRatio),\n width: Math.round(element.rect.width * shrunkShotToLogicalRatio),\n height: Math.round(element.rect.height * shrunkShotToLogicalRatio),\n },\n };\n};\n\nexport const transformLogicalRectToScreenshotRect = (\n rect: Rect,\n shrunkShotToLogicalRatio: number,\n): Rect => {\n if (shrunkShotToLogicalRatio === 1) {\n return rect;\n }\n\n return {\n ...rect,\n left: Math.round(rect.left * shrunkShotToLogicalRatio),\n top: Math.round(rect.top * shrunkShotToLogicalRatio),\n width: Math.round(rect.width * shrunkShotToLogicalRatio),\n height: Math.round(rect.height * shrunkShotToLogicalRatio),\n };\n};\n"],"names":["__webpack_require__","module","getter","definition","key","Object","obj","prop","Symbol","commonContextParser","interfaceInstance","_opt","debug","getDebug","assert","description","uploadTestInfoToServer","interfaceSize","logicalWidth","logicalHeight","console","Number","Error","screenshotBase64","screenshotCapturedAt","Date","imgWidth","imgHeight","imageInfoOfBase64","logicalIsPortrait","screenshotIsPortrait","finalLogicalWidth","userShrinkFactor","dpr","shrunkShotToLogicalRatio","targetWidth","Math","targetHeight","resizedBase64","resizeImgBase64","ScreenshotItem","getReportFileName","tag","reportTagName","globalConfigManager","MIDSCENE_REPORT_TAG_NAME","dateTimeInFileName","dayjs","uniqueId","uuid","printReportMsg","filepath","MIDSCENE_REPORT_QUIET","logMsg","ifPlanLocateParamIsBbox","planLocateParam","Array","matchElementFromPlan","rect","element","generateElementByRect","matchElementFromCache","context","cacheEntry","cachePrompt","cacheable","cacheDebug","error","getMidsceneVersion","__VERSION__","parsePrompt","prompt","undefined","transformLogicalElementToScreenshot","transformLogicalRectToScreenshotRect"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"agent/utils.js","sources":["webpack/runtime/compat_get_default_export","webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/agent/utils.ts"],"sourcesContent":["// getDefaultExport function for compatibility with non-ESM modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};\n","__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import type { TMultimodalPrompt, TUserPrompt } from '@/common';\nimport type { AbstractInterface } from '@/device';\nimport { ScreenshotItem } from '@/screenshot-item';\nimport type {\n ElementCacheFeature,\n LocateResultElement,\n PlanningLocateParam,\n Rect,\n UIContext,\n} from '@/types';\nimport { uploadTestInfoToServer } from '@/utils';\nimport type { TModelFamily } from '@aiscene/shared/env';\nimport {\n MIDSCENE_REPORT_QUIET,\n MIDSCENE_REPORT_TAG_NAME,\n globalConfigManager,\n} from '@aiscene/shared/env';\nimport { generateElementByRect } from '@aiscene/shared/extractor';\nimport { imageInfoOfBase64, resizeImgBase64 } from '@aiscene/shared/img';\nimport { getDebug } from '@aiscene/shared/logger';\nimport { _keyDefinitions } from '@aiscene/shared/us-keyboard-layout';\nimport { assert, logMsg, uuid } from '@aiscene/shared/utils';\nimport dayjs from 'dayjs';\nimport type { TaskCache } from './task-cache';\nimport { debug as cacheDebug } from './task-cache';\n\nexport async function commonContextParser(\n interfaceInstance: AbstractInterface,\n _opt: {\n uploadServerUrl?: string;\n screenshotShrinkFactor?: number;\n modelFamily?: TModelFamily;\n },\n): Promise<UIContext> {\n const debug = getDebug('commonContextParser');\n\n assert(interfaceInstance, 'interfaceInstance is required');\n\n debug('Getting interface description');\n const description = interfaceInstance.describe?.() || '';\n debug('Interface description end');\n\n debug('Uploading test info to server');\n uploadTestInfoToServer({\n testUrl: description,\n serverUrl: _opt.uploadServerUrl,\n });\n debug('UploadTestInfoToServer end');\n\n debug('will get size');\n const interfaceSize = await interfaceInstance.size();\n const { width: logicalWidth, height: logicalHeight } = interfaceSize;\n\n if ((interfaceSize as unknown as { dpr: number }).dpr) {\n console.warn(\n 'Warning: return value of interface.size() include a dpr property, which is not expected and ignored. ',\n );\n }\n\n if (!Number.isFinite(logicalWidth) || !Number.isFinite(logicalHeight)) {\n throw new Error(\n `Invalid interface size: width and height must be finite numbers. Received width: ${logicalWidth}, height: ${logicalHeight}`,\n );\n }\n\n if (logicalWidth <= 0 || logicalHeight <= 0) {\n throw new Error(\n `Invalid interface size: width and height must be positive numbers. Received width: ${logicalWidth}, height: ${logicalHeight}`,\n );\n }\n\n debug(`size: ${logicalWidth}x${logicalHeight}`);\n\n // Retry logic for screenshot capture/decoding\n const maxRetries = 3;\n let lastError: Error | null = null;\n let screenshotBase64: string | null = null;\n let screenshotCapturedAt = 0;\n let imgWidth: number = 0;\n let imgHeight: number = 0;\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n try {\n screenshotBase64 = await interfaceInstance.screenshotBase64();\n screenshotCapturedAt = Date.now();\n assert(screenshotBase64!, 'screenshotBase64 is required');\n\n // Get physical screenshot dimensions\n debug('will get screenshot dimensions');\n const dimensions = await imageInfoOfBase64(screenshotBase64);\n imgWidth = dimensions.width;\n imgHeight = dimensions.height;\n\n // Validate dimensions\n if (!Number.isFinite(imgWidth) || !Number.isFinite(imgHeight)) {\n throw new Error(\n `Invalid screenshot dimensions: width and height must be finite numbers. Received width: ${imgWidth}, height: ${imgHeight}`,\n );\n }\n if (imgWidth <= 0 || imgHeight <= 0) {\n throw new Error(\n `Invalid screenshot dimensions: width and height must be positive numbers. Received width: ${imgWidth}, height: ${imgHeight}`,\n );\n }\n\n // If we get here, screenshot is valid\n debug('screenshot dimensions', imgWidth, 'x', imgHeight);\n break;\n } catch (error) {\n lastError =\n error instanceof Error ? error : new Error(String(error));\n debug(\n `Screenshot capture/decode failed (attempt ${attempt}/${maxRetries}): ${lastError.message}`,\n );\n\n if (attempt === maxRetries) {\n throw new Error(\n `Failed to capture valid screenshot after ${maxRetries} attempts: ${lastError.message}`,\n );\n }\n\n // Wait before retrying\n await new Promise((resolve) => setTimeout(resolve, 500));\n }\n }\n\n // This should never be null if we got past the retry loop\n if (!screenshotBase64) {\n throw new Error('Screenshot data is null after retry loop');\n }\n\n // Detect orientation mismatch between logical size and screenshot.\n // Some devices (e.g. OPPO) report wrong orientation via ADB, causing\n // size() to return portrait dimensions even when the device is landscape.\n // We detect this by comparing aspect ratios and swap if they disagree.\n const logicalIsPortrait = logicalWidth < logicalHeight;\n const screenshotIsPortrait = imgWidth < imgHeight;\n let finalLogicalWidth = logicalWidth;\n let finalLogicalHeight = logicalHeight;\n if (logicalIsPortrait !== screenshotIsPortrait) {\n debug(\n `Orientation mismatch detected: logical size ${logicalWidth}x${logicalHeight} (${logicalIsPortrait ? 'portrait' : 'landscape'}) vs screenshot ${imgWidth}x${imgHeight} (${screenshotIsPortrait ? 'portrait' : 'landscape'}). Swapping logical dimensions.`,\n );\n finalLogicalWidth = logicalHeight;\n finalLogicalHeight = logicalWidth;\n }\n\n const userShrinkFactor = _opt.screenshotShrinkFactor ?? 1;\n\n if (!Number.isFinite(userShrinkFactor) || userShrinkFactor < 1) {\n throw new Error(\n `Invalid screenshotShrinkFactor: must be a finite number >= 1. Received: ${userShrinkFactor}`,\n );\n }\n\n const dpr = imgWidth / finalLogicalWidth;\n\n debug('calculated dpr:', dpr);\n\n const shrunkShotToLogicalRatio = dpr / userShrinkFactor;\n\n debug('shrunkShotToLogicalRatio', shrunkShotToLogicalRatio);\n\n if (userShrinkFactor !== 1) {\n const targetWidth = Math.round(imgWidth / userShrinkFactor);\n const targetHeight = Math.round(imgHeight / userShrinkFactor);\n\n debug(\n `Applying screenshot shrink factor: ${userShrinkFactor} (physical: ${imgWidth}x${imgHeight} -> target: ${targetWidth}x${targetHeight})`,\n );\n\n const resizedBase64 = await resizeImgBase64(screenshotBase64, {\n width: targetWidth,\n height: targetHeight,\n });\n return {\n shotSize: {\n width: targetWidth,\n height: targetHeight,\n },\n deprecatedDpr: dpr,\n screenshot: ScreenshotItem.create(resizedBase64, screenshotCapturedAt),\n shrunkShotToLogicalRatio,\n };\n }\n\n return {\n shotSize: {\n width: imgWidth,\n height: imgHeight,\n },\n deprecatedDpr: dpr,\n screenshot: ScreenshotItem.create(screenshotBase64, screenshotCapturedAt),\n shrunkShotToLogicalRatio,\n };\n}\n\nexport function getReportFileName(tag = 'web') {\n const reportTagName = globalConfigManager.getEnvConfigValue(\n MIDSCENE_REPORT_TAG_NAME,\n );\n const dateTimeInFileName = dayjs().format('YYYY-MM-DD_HH-mm-ss');\n // ensure uniqueness at the same time\n const uniqueId = uuid().substring(0, 8);\n return `${reportTagName || tag}-${dateTimeInFileName}-${uniqueId}`;\n}\n\nexport function printReportMsg(filepath: string) {\n if (globalConfigManager.getEnvConfigInBoolean(MIDSCENE_REPORT_QUIET)) {\n return;\n }\n logMsg(`Midscene - report file updated: ${filepath}`);\n}\n\nexport function ifPlanLocateParamIsBbox(\n planLocateParam: PlanningLocateParam,\n): boolean {\n return !!(\n planLocateParam.bbox &&\n Array.isArray(planLocateParam.bbox) &&\n planLocateParam.bbox.length === 4\n );\n}\n\nexport function matchElementFromPlan(\n planLocateParam: PlanningLocateParam,\n): LocateResultElement | undefined {\n if (!planLocateParam) {\n return undefined;\n }\n\n if (planLocateParam.bbox) {\n // Convert bbox [x1, y1, x2, y2] to rect {left, top, width, height}\n const rect = {\n left: planLocateParam.bbox[0],\n top: planLocateParam.bbox[1],\n width: planLocateParam.bbox[2] - planLocateParam.bbox[0] + 1,\n height: planLocateParam.bbox[3] - planLocateParam.bbox[1] + 1,\n };\n\n const element = generateElementByRect(\n rect,\n typeof planLocateParam.prompt === 'string'\n ? planLocateParam.prompt\n : planLocateParam.prompt?.prompt || '',\n );\n return element;\n }\n\n return undefined;\n}\n\nexport async function matchElementFromCache(\n context: {\n taskCache?: TaskCache;\n interfaceInstance: AbstractInterface;\n },\n cacheEntry: ElementCacheFeature | undefined,\n cachePrompt: TUserPrompt,\n cacheable: boolean | undefined,\n): Promise<LocateResultElement | undefined> {\n if (!cacheEntry) {\n return undefined;\n }\n\n if (cacheable === false) {\n cacheDebug('cache disabled for prompt: %s', cachePrompt);\n return undefined;\n }\n\n if (!context.taskCache?.isCacheResultUsed) {\n return undefined;\n }\n\n if (!context.interfaceInstance.rectMatchesCacheFeature) {\n cacheDebug(\n 'interface does not implement rectMatchesCacheFeature, skip cache',\n );\n return undefined;\n }\n\n try {\n const rect =\n await context.interfaceInstance.rectMatchesCacheFeature(cacheEntry);\n const element: LocateResultElement = {\n center: [\n Math.round(rect.left + rect.width / 2),\n Math.round(rect.top + rect.height / 2),\n ],\n rect,\n description:\n typeof cachePrompt === 'string'\n ? cachePrompt\n : cachePrompt.prompt || '',\n };\n\n cacheDebug('cache hit, prompt: %s', cachePrompt);\n return element;\n } catch (error) {\n cacheDebug('rectMatchesCacheFeature error: %s', error);\n return undefined;\n }\n}\n\ndeclare const __VERSION__: string | undefined;\n\nexport const getMidsceneVersion = (): string => {\n if (typeof __VERSION__ !== 'undefined') {\n return __VERSION__;\n } else if (\n process.env.__VERSION__ &&\n process.env.__VERSION__ !== 'undefined'\n ) {\n return process.env.__VERSION__;\n }\n throw new Error('__VERSION__ inject failed during build');\n};\n\nexport const parsePrompt = (\n prompt: TUserPrompt,\n): {\n textPrompt: string;\n multimodalPrompt?: TMultimodalPrompt;\n} => {\n if (typeof prompt === 'string') {\n return {\n textPrompt: prompt,\n multimodalPrompt: undefined,\n };\n }\n return {\n textPrompt: prompt.prompt,\n multimodalPrompt: prompt.images\n ? {\n images: prompt.images,\n convertHttpImage2Base64: !!prompt.convertHttpImage2Base64,\n }\n : undefined,\n };\n};\n\nexport const transformLogicalElementToScreenshot = (\n element: LocateResultElement,\n shrunkShotToLogicalRatio: number,\n): LocateResultElement => {\n if (shrunkShotToLogicalRatio === 1) {\n return element;\n }\n\n return {\n ...element,\n center: [\n Math.round(element.center[0] * shrunkShotToLogicalRatio),\n Math.round(element.center[1] * shrunkShotToLogicalRatio),\n ],\n rect: {\n ...element.rect,\n left: Math.round(element.rect.left * shrunkShotToLogicalRatio),\n top: Math.round(element.rect.top * shrunkShotToLogicalRatio),\n width: Math.round(element.rect.width * shrunkShotToLogicalRatio),\n height: Math.round(element.rect.height * shrunkShotToLogicalRatio),\n },\n };\n};\n\nexport const transformLogicalRectToScreenshotRect = (\n rect: Rect,\n shrunkShotToLogicalRatio: number,\n): Rect => {\n if (shrunkShotToLogicalRatio === 1) {\n return rect;\n }\n\n return {\n ...rect,\n left: Math.round(rect.left * shrunkShotToLogicalRatio),\n top: Math.round(rect.top * shrunkShotToLogicalRatio),\n width: Math.round(rect.width * shrunkShotToLogicalRatio),\n height: Math.round(rect.height * shrunkShotToLogicalRatio),\n };\n};\n"],"names":["__webpack_require__","module","getter","definition","key","Object","obj","prop","Symbol","commonContextParser","interfaceInstance","_opt","debug","getDebug","assert","description","uploadTestInfoToServer","interfaceSize","logicalWidth","logicalHeight","console","Number","Error","maxRetries","lastError","screenshotBase64","screenshotCapturedAt","imgWidth","imgHeight","attempt","Date","dimensions","imageInfoOfBase64","error","String","Promise","resolve","setTimeout","logicalIsPortrait","screenshotIsPortrait","finalLogicalWidth","userShrinkFactor","dpr","shrunkShotToLogicalRatio","targetWidth","Math","targetHeight","resizedBase64","resizeImgBase64","ScreenshotItem","getReportFileName","tag","reportTagName","globalConfigManager","MIDSCENE_REPORT_TAG_NAME","dateTimeInFileName","dayjs","uniqueId","uuid","printReportMsg","filepath","MIDSCENE_REPORT_QUIET","logMsg","ifPlanLocateParamIsBbox","planLocateParam","Array","matchElementFromPlan","rect","element","generateElementByRect","matchElementFromCache","context","cacheEntry","cachePrompt","cacheable","cacheDebug","getMidsceneVersion","__VERSION__","parsePrompt","prompt","undefined","transformLogicalElementToScreenshot","transformLogicalRectToScreenshotRect"],"mappings":"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"}
|
package/dist/lib/types.js
CHANGED
|
@@ -6,7 +6,7 @@ var __webpack_modules__ = {
|
|
|
6
6
|
"./dump/screenshot-store" (module) {
|
|
7
7
|
module.exports = require("./dump/screenshot-store.js");
|
|
8
8
|
},
|
|
9
|
-
"
|
|
9
|
+
"@/screenshot-item" (module) {
|
|
10
10
|
module.exports = require("./screenshot-item.js");
|
|
11
11
|
},
|
|
12
12
|
"./yaml" (module) {
|
|
@@ -73,16 +73,16 @@ var __webpack_exports__ = {};
|
|
|
73
73
|
var node_path__rspack_import_1 = __webpack_require__("node:path");
|
|
74
74
|
var _dump_screenshot_restoration__rspack_import_2 = __webpack_require__("./dump/screenshot-restoration");
|
|
75
75
|
var _dump_screenshot_store__rspack_import_3 = __webpack_require__("./dump/screenshot-store");
|
|
76
|
-
var _screenshot_item__rspack_import_4 = __webpack_require__("
|
|
76
|
+
var _screenshot_item__rspack_import_4 = __webpack_require__("@/screenshot-item");
|
|
77
77
|
var _yaml__rspack_import_5 = __webpack_require__("./yaml");
|
|
78
78
|
var __rspack_reexport = {};
|
|
79
79
|
for(const __rspack_import_key in _yaml__rspack_import_5)if ([
|
|
80
80
|
"UIContext",
|
|
81
|
-
"
|
|
81
|
+
"ServiceError",
|
|
82
82
|
"default",
|
|
83
83
|
"ReportActionDump",
|
|
84
|
-
"
|
|
85
|
-
"
|
|
84
|
+
"GroupedActionDump",
|
|
85
|
+
"ExecutionDump"
|
|
86
86
|
].indexOf(__rspack_import_key) < 0) __rspack_reexport[__rspack_import_key] = ()=>_yaml__rspack_import_5[__rspack_import_key];
|
|
87
87
|
__webpack_require__.d(__webpack_exports__, __rspack_reexport);
|
|
88
88
|
function _define_property(obj, key, value) {
|
package/dist/lib/utils.js
CHANGED
|
@@ -219,7 +219,7 @@ function stringifyDumpData(data, indents) {
|
|
|
219
219
|
return JSON.stringify(data, replacerForPageObject, indents);
|
|
220
220
|
}
|
|
221
221
|
function getVersion() {
|
|
222
|
-
return "8.0.
|
|
222
|
+
return "8.0.3";
|
|
223
223
|
}
|
|
224
224
|
function debugLog(...message) {
|
|
225
225
|
const debugMode = process.env[env_namespaceObject.MIDSCENE_DEBUG_MODE];
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiscene/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": "8.0.
|
|
4
|
+
"version": "8.0.3",
|
|
5
5
|
"repository": "https://github.com/web-infra-dev/midscene",
|
|
6
6
|
"homepage": "https://midscenejs.com/",
|
|
7
7
|
"main": "./dist/lib/index.js",
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"test:parse-action": "npm run test:ai -- tests/ai/parse-action.test.ts"
|
|
79
79
|
},
|
|
80
80
|
"dependencies": {
|
|
81
|
-
"@aiscene/shared": "^8.0.
|
|
81
|
+
"@aiscene/shared": "^8.0.2",
|
|
82
82
|
"@ui-tars/action-parser": "1.2.3",
|
|
83
83
|
"dayjs": "^1.11.11",
|
|
84
84
|
"dotenv": "^16.4.5",
|
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
import type { TUserPrompt } from '../ai-model/index';
|
|
2
|
-
import Service from '../service/index';
|
|
3
|
-
import { type ActionParam, type ActionReturn, type AgentAssertOpt, type AgentDescribeElementAtPointResult, type AgentOpt, type AgentWaitForOpt, type DeepThinkOption, type DeviceAction, ExecutionDump, type LocateOption, type LocateValidatorResult, type LocatorValidatorOption, type OnTaskStartTip, ReportActionDump, type ScrollParam, type ServiceAction, type ServiceExtractOption, type ServiceExtractParam, type UIContext } from '../types';
|
|
4
|
-
import type { AbstractInterface } from '../device';
|
|
5
|
-
import type { TaskRunner } from '../task-runner';
|
|
6
|
-
import { ModelConfigManager } from '@aiscene/shared/env';
|
|
7
|
-
import { TaskCache } from './task-cache';
|
|
8
|
-
import { TaskExecutor } from './tasks';
|
|
9
|
-
export type AiActOptions = {
|
|
10
|
-
cacheable?: boolean;
|
|
11
|
-
fileChooserAccept?: string | string[];
|
|
12
|
-
deepThink?: DeepThinkOption;
|
|
13
|
-
deepLocate?: boolean;
|
|
14
|
-
abortSignal?: AbortSignal;
|
|
15
|
-
};
|
|
16
|
-
export declare class Agent<InterfaceType extends AbstractInterface = AbstractInterface> {
|
|
17
|
-
interface: InterfaceType;
|
|
18
|
-
service: Service;
|
|
19
|
-
dump: ReportActionDump;
|
|
20
|
-
reportFile?: string | null;
|
|
21
|
-
reportFileName?: string;
|
|
22
|
-
taskExecutor: TaskExecutor;
|
|
23
|
-
opts: AgentOpt;
|
|
24
|
-
/**
|
|
25
|
-
* If true, the agent will not perform any actions
|
|
26
|
-
*/
|
|
27
|
-
dryMode: boolean;
|
|
28
|
-
onTaskStartTip?: OnTaskStartTip;
|
|
29
|
-
taskCache?: TaskCache;
|
|
30
|
-
private dumpUpdateListeners;
|
|
31
|
-
get onDumpUpdate(): ((dump: string, executionDump?: ExecutionDump) => void) | undefined;
|
|
32
|
-
set onDumpUpdate(callback: ((dump: string, executionDump?: ExecutionDump) => void) | undefined);
|
|
33
|
-
destroyed: boolean;
|
|
34
|
-
modelConfigManager: ModelConfigManager;
|
|
35
|
-
/**
|
|
36
|
-
* Frozen page context for consistent AI operations
|
|
37
|
-
*/
|
|
38
|
-
private frozenUIContext?;
|
|
39
|
-
private get aiActContext();
|
|
40
|
-
/**
|
|
41
|
-
* Flag to track if VL model warning has been shown
|
|
42
|
-
*/
|
|
43
|
-
private hasWarnedNonVLModel;
|
|
44
|
-
private executionDumpIndexByRunner;
|
|
45
|
-
private fullActionSpace;
|
|
46
|
-
private reportGenerator;
|
|
47
|
-
get page(): InterfaceType;
|
|
48
|
-
/**
|
|
49
|
-
* Ensures VL model warning is shown once when needed
|
|
50
|
-
*/
|
|
51
|
-
private ensureVLModelWarning;
|
|
52
|
-
private resolveReplanningCycleLimit;
|
|
53
|
-
constructor(interfaceInstance: InterfaceType, opts?: AgentOpt);
|
|
54
|
-
getActionSpace(): Promise<DeviceAction[]>;
|
|
55
|
-
private static readonly CONTEXT_RETRY_MAX;
|
|
56
|
-
private static readonly CONTEXT_RETRY_DELAY_MS;
|
|
57
|
-
/**
|
|
58
|
-
* Override in subclasses to indicate which errors are transient and should
|
|
59
|
-
* trigger an automatic retry when building the UI context.
|
|
60
|
-
* Returns `false` by default (no retry).
|
|
61
|
-
*/
|
|
62
|
-
protected isRetryableContextError(_error: unknown): boolean;
|
|
63
|
-
getUIContext(action?: ServiceAction): Promise<UIContext>;
|
|
64
|
-
_snapshotContext(): Promise<UIContext>;
|
|
65
|
-
/**
|
|
66
|
-
* @deprecated Use {@link setAIActContext} instead.
|
|
67
|
-
*/
|
|
68
|
-
setAIActionContext(prompt: string): Promise<void>;
|
|
69
|
-
setAIActContext(prompt: string): Promise<void>;
|
|
70
|
-
resetDump(): ReportActionDump;
|
|
71
|
-
appendExecutionDump(execution: ExecutionDump, runner?: TaskRunner): void;
|
|
72
|
-
dumpDataString(opt?: {
|
|
73
|
-
inlineScreenshots?: boolean;
|
|
74
|
-
}): string;
|
|
75
|
-
reportHTMLString(opt?: {
|
|
76
|
-
inlineScreenshots?: boolean;
|
|
77
|
-
}): string;
|
|
78
|
-
private lastExecutionDump?;
|
|
79
|
-
writeOutActionDumps(executionDump?: ExecutionDump): void;
|
|
80
|
-
private getReportMeta;
|
|
81
|
-
private callbackOnTaskStartTip;
|
|
82
|
-
wrapActionInActionSpace<T extends DeviceAction>(name: string): (param: ActionParam<T>) => Promise<ActionReturn<T>>;
|
|
83
|
-
callActionInActionSpace<T = any>(type: string, opt?: T): Promise<any>;
|
|
84
|
-
aiTap(locatePrompt: TUserPrompt, opt?: LocateOption & {
|
|
85
|
-
fileChooserAccept?: string | string[];
|
|
86
|
-
}): Promise<any>;
|
|
87
|
-
aiRightClick(locatePrompt: TUserPrompt, opt?: LocateOption): Promise<any>;
|
|
88
|
-
aiDoubleClick(locatePrompt: TUserPrompt, opt?: LocateOption): Promise<any>;
|
|
89
|
-
aiHover(locatePrompt: TUserPrompt, opt?: LocateOption): Promise<any>;
|
|
90
|
-
aiInput(locatePrompt: TUserPrompt, opt: LocateOption & {
|
|
91
|
-
value: string | number;
|
|
92
|
-
} & {
|
|
93
|
-
autoDismissKeyboard?: boolean;
|
|
94
|
-
} & {
|
|
95
|
-
mode?: 'replace' | 'clear' | 'typeOnly' | 'append';
|
|
96
|
-
}): Promise<any>;
|
|
97
|
-
/**
|
|
98
|
-
* @deprecated Use aiInput(locatePrompt, opt) instead where opt contains the value
|
|
99
|
-
*/
|
|
100
|
-
aiInput(value: string | number, locatePrompt: TUserPrompt, opt?: LocateOption & {
|
|
101
|
-
autoDismissKeyboard?: boolean;
|
|
102
|
-
} & {
|
|
103
|
-
mode?: 'replace' | 'clear' | 'typeOnly' | 'append';
|
|
104
|
-
}): Promise<any>;
|
|
105
|
-
aiKeyboardPress(locatePrompt: TUserPrompt, opt: LocateOption & {
|
|
106
|
-
keyName: string;
|
|
107
|
-
}): Promise<any>;
|
|
108
|
-
/**
|
|
109
|
-
* @deprecated Use aiKeyboardPress(locatePrompt, opt) instead where opt contains the keyName
|
|
110
|
-
*/
|
|
111
|
-
aiKeyboardPress(keyName: string, locatePrompt?: TUserPrompt, opt?: LocateOption): Promise<any>;
|
|
112
|
-
aiScroll(locatePrompt: TUserPrompt | undefined, opt: LocateOption & ScrollParam): Promise<any>;
|
|
113
|
-
/**
|
|
114
|
-
* @deprecated Use aiScroll(locatePrompt, opt) instead where opt contains the scroll parameters
|
|
115
|
-
*/
|
|
116
|
-
aiScroll(scrollParam: ScrollParam, locatePrompt?: TUserPrompt, opt?: LocateOption): Promise<any>;
|
|
117
|
-
aiPinch(locatePrompt: TUserPrompt | undefined, opt: LocateOption & {
|
|
118
|
-
direction: 'in' | 'out';
|
|
119
|
-
distance?: number;
|
|
120
|
-
duration?: number;
|
|
121
|
-
}): Promise<any>;
|
|
122
|
-
aiAct(taskPrompt: string, opt?: AiActOptions): Promise<string | undefined>;
|
|
123
|
-
/**
|
|
124
|
-
* @deprecated Use {@link Agent.aiAct} instead.
|
|
125
|
-
*/
|
|
126
|
-
aiAction(taskPrompt: string, opt?: AiActOptions): Promise<string | undefined>;
|
|
127
|
-
aiQuery<ReturnType = any>(demand: ServiceExtractParam, opt?: ServiceExtractOption): Promise<ReturnType>;
|
|
128
|
-
aiBoolean(prompt: TUserPrompt, opt?: ServiceExtractOption): Promise<boolean>;
|
|
129
|
-
aiNumber(prompt: TUserPrompt, opt?: ServiceExtractOption): Promise<number>;
|
|
130
|
-
aiString(prompt: TUserPrompt, opt?: ServiceExtractOption): Promise<string>;
|
|
131
|
-
aiAsk(prompt: TUserPrompt, opt?: ServiceExtractOption): Promise<string>;
|
|
132
|
-
describeElementAtPoint(center: [number, number], opt?: {
|
|
133
|
-
verifyPrompt?: boolean;
|
|
134
|
-
retryLimit?: number;
|
|
135
|
-
deepLocate?: boolean;
|
|
136
|
-
} & LocatorValidatorOption): Promise<AgentDescribeElementAtPointResult>;
|
|
137
|
-
verifyLocator(prompt: string, locateOpt: LocateOption | undefined, expectCenter: [number, number], verifyLocateOption?: LocatorValidatorOption): Promise<LocateValidatorResult>;
|
|
138
|
-
/**
|
|
139
|
-
* Locate an element and return both its center point and an approximate rect.
|
|
140
|
-
*
|
|
141
|
-
* - In most locate flows, `rect` represents the matched element boundary.
|
|
142
|
-
* - Some models only support point grounding instead of boundary grounding.
|
|
143
|
-
* In those cases (for example, AutoGLM), `rect` falls back to a small 8x8
|
|
144
|
-
* box centered on the located point.
|
|
145
|
-
*
|
|
146
|
-
* Because `rect` may vary with the underlying model capability, avoid relying
|
|
147
|
-
* on it too heavily for strict boundary semantics. If you need a stable click
|
|
148
|
-
* target, prefer `center`.
|
|
149
|
-
*/
|
|
150
|
-
aiLocate(prompt: TUserPrompt, opt?: LocateOption): Promise<Pick<LocateResultElement, "rect" | "center">>;
|
|
151
|
-
aiAssert(assertion: TUserPrompt, msg?: string, opt?: AgentAssertOpt & ServiceExtractOption): Promise<{
|
|
152
|
-
pass: boolean;
|
|
153
|
-
thought: string | undefined;
|
|
154
|
-
message: string | undefined;
|
|
155
|
-
} | undefined>;
|
|
156
|
-
aiWaitFor(assertion: TUserPrompt, opt?: AgentWaitForOpt): Promise<void>;
|
|
157
|
-
ai(...args: Parameters<typeof this.aiAct>): Promise<string | undefined>;
|
|
158
|
-
runYaml(yamlScriptContent: string): Promise<{
|
|
159
|
-
result: Record<string, any>;
|
|
160
|
-
}>;
|
|
161
|
-
evaluateJavaScript(script: string): Promise<any>;
|
|
162
|
-
/**
|
|
163
|
-
* Add a dump update listener
|
|
164
|
-
* @param listener Listener function
|
|
165
|
-
* @returns A remove function that can be called to remove this listener
|
|
166
|
-
*/
|
|
167
|
-
addDumpUpdateListener(listener: (dump: string, executionDump?: ExecutionDump) => void): () => void;
|
|
168
|
-
/**
|
|
169
|
-
* Remove a dump update listener
|
|
170
|
-
* @param listener The listener function to remove
|
|
171
|
-
*/
|
|
172
|
-
removeDumpUpdateListener(listener: (dump: string, executionDump?: ExecutionDump) => void): void;
|
|
173
|
-
/**
|
|
174
|
-
* Clear all dump update listeners
|
|
175
|
-
*/
|
|
176
|
-
clearDumpUpdateListeners(): void;
|
|
177
|
-
destroy(): Promise<void>;
|
|
178
|
-
recordToReport(title?: string, opt?: {
|
|
179
|
-
content: string;
|
|
180
|
-
}): Promise<void>;
|
|
181
|
-
/**
|
|
182
|
-
* @deprecated Use {@link Agent.recordToReport} instead.
|
|
183
|
-
*/
|
|
184
|
-
logScreenshot(title?: string, opt?: {
|
|
185
|
-
content: string;
|
|
186
|
-
}): Promise<void>;
|
|
187
|
-
_unstableLogContent(): {
|
|
188
|
-
groupName: string;
|
|
189
|
-
groupDescription: string | undefined;
|
|
190
|
-
executions: ExecutionDump[];
|
|
191
|
-
};
|
|
192
|
-
/**
|
|
193
|
-
* Freezes the current page context to be reused in subsequent AI operations
|
|
194
|
-
* This avoids recalculating page context for each operation
|
|
195
|
-
*/
|
|
196
|
-
freezePageContext(): Promise<void>;
|
|
197
|
-
/**
|
|
198
|
-
* Unfreezes the page context, allowing AI operations to calculate context dynamically
|
|
199
|
-
*/
|
|
200
|
-
unfreezePageContext(): Promise<void>;
|
|
201
|
-
/**
|
|
202
|
-
* Process cache configuration and return normalized cache settings
|
|
203
|
-
*/
|
|
204
|
-
private processCacheConfig;
|
|
205
|
-
private normalizeFilePaths;
|
|
206
|
-
private normalizeFileInput;
|
|
207
|
-
/**
|
|
208
|
-
* Manually flush cache to file
|
|
209
|
-
* @param options - Optional configuration
|
|
210
|
-
* @param options.cleanUnused - If true, removes unused cache records before flushing
|
|
211
|
-
*/
|
|
212
|
-
flushCache(options?: {
|
|
213
|
-
cleanUnused?: boolean;
|
|
214
|
-
}): Promise<void>;
|
|
215
|
-
}
|
|
216
|
-
export declare const createAgent: (interfaceInstance: AbstractInterface, opts?: AgentOpt) => Agent<AbstractInterface>;
|
|
File without changes
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { type TaskExecutionError, TaskRunner } from '../task-runner';
|
|
2
|
-
import type { ExecutionTaskApply, ExecutionTaskProgressOptions, UIContext } from '../types';
|
|
3
|
-
type ExecutionSessionOptions = ExecutionTaskProgressOptions & {
|
|
4
|
-
tasks?: ExecutionTaskApply[];
|
|
5
|
-
onTaskUpdate?: (runner: TaskRunner, error?: TaskExecutionError) => Promise<void> | void;
|
|
6
|
-
};
|
|
7
|
-
/**
|
|
8
|
-
* Thin wrapper around {@link TaskRunner} that represents a single linear execution run.
|
|
9
|
-
*/
|
|
10
|
-
export declare class ExecutionSession {
|
|
11
|
-
private readonly runner;
|
|
12
|
-
constructor(name: string, contextProvider: () => Promise<UIContext>, options?: ExecutionSessionOptions);
|
|
13
|
-
append(tasks: ExecutionTaskApply[] | ExecutionTaskApply, options?: {
|
|
14
|
-
allowWhenError?: boolean;
|
|
15
|
-
}): Promise<void>;
|
|
16
|
-
appendAndRun(tasks: ExecutionTaskApply[] | ExecutionTaskApply, options?: {
|
|
17
|
-
allowWhenError?: boolean;
|
|
18
|
-
}): Promise<{
|
|
19
|
-
output: any;
|
|
20
|
-
thought?: string;
|
|
21
|
-
} | undefined>;
|
|
22
|
-
run(options?: {
|
|
23
|
-
allowWhenError?: boolean;
|
|
24
|
-
}): Promise<{
|
|
25
|
-
output: any;
|
|
26
|
-
thought?: string;
|
|
27
|
-
} | undefined>;
|
|
28
|
-
isInErrorState(): boolean;
|
|
29
|
-
latestErrorTask(): import("../types").ExecutionTask | null;
|
|
30
|
-
appendErrorPlan(errorMsg: string): Promise<{
|
|
31
|
-
output: undefined;
|
|
32
|
-
runner: TaskRunner;
|
|
33
|
-
}>;
|
|
34
|
-
getRunner(): TaskRunner;
|
|
35
|
-
}
|
|
36
|
-
export {};
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export { Agent, createAgent } from './agent';
|
|
2
|
-
export { commonContextParser } from './utils';
|
|
3
|
-
export { getReportFileName, printReportMsg, } from './utils';
|
|
4
|
-
export { extractInsightParam, locateParamStr, paramStr, taskTitleStr, typeStr, } from './ui-utils';
|
|
5
|
-
export { type LocateCache, type PlanningCache, TaskCache } from './task-cache';
|
|
6
|
-
export { cacheFileExt } from './task-cache';
|
|
7
|
-
export { TaskExecutor } from './tasks';
|
|
8
|
-
export type { AgentOpt } from '../types';
|
|
9
|
-
export type { AiActOptions } from './agent';
|