@midscene/core 0.30.1 → 0.30.2-beta-20250930144216.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/agent/agent.mjs +48 -6
- package/dist/es/agent/agent.mjs.map +1 -1
- package/dist/es/agent/utils.mjs +2 -11
- package/dist/es/agent/utils.mjs.map +1 -1
- package/dist/es/types.mjs.map +1 -1
- package/dist/es/utils.mjs +2 -2
- package/dist/lib/agent/agent.js +48 -6
- package/dist/lib/agent/agent.js.map +1 -1
- package/dist/lib/agent/utils.js +2 -11
- package/dist/lib/agent/utils.js.map +1 -1
- package/dist/lib/types.js.map +1 -1
- package/dist/lib/utils.js +2 -2
- package/dist/types/agent/agent.d.ts +13 -1
- package/dist/types/types.d.ts +1 -0
- package/package.json +3 -3
package/dist/es/agent/agent.mjs
CHANGED
|
@@ -3,6 +3,7 @@ import js_yaml from "js-yaml";
|
|
|
3
3
|
import { groupedActionDumpFileExt, reportHTMLContent, stringifyDumpData, writeLogFile } from "../utils.mjs";
|
|
4
4
|
import { ScriptPlayer, buildDetailedLocateParam, parseYamlScript } from "../yaml/index.mjs";
|
|
5
5
|
import { MIDSCENE_CACHE, ModelConfigManager, globalConfigManager, globalModelConfigManager } from "@midscene/shared/env";
|
|
6
|
+
import { imageInfoOfBase64, resizeImgBase64 } from "@midscene/shared/img";
|
|
6
7
|
import { getDebug } from "@midscene/shared/logger";
|
|
7
8
|
import { assert } from "@midscene/shared/utils";
|
|
8
9
|
import { TaskCache } from "./task-cache.mjs";
|
|
@@ -50,6 +51,26 @@ class Agent {
|
|
|
50
51
|
this.hasWarnedNonVLModel = true;
|
|
51
52
|
}
|
|
52
53
|
}
|
|
54
|
+
async getScreenshotScale(context) {
|
|
55
|
+
if (void 0 !== this.screenshotScale) return this.screenshotScale;
|
|
56
|
+
if (!this.screenshotScalePromise) this.screenshotScalePromise = (async ()=>{
|
|
57
|
+
var _context_size;
|
|
58
|
+
const pageWidth = null == (_context_size = context.size) ? void 0 : _context_size.width;
|
|
59
|
+
assert(pageWidth && pageWidth > 0, `Invalid page width when computing screenshot scale: ${pageWidth}`);
|
|
60
|
+
const { width: screenshotWidth } = await imageInfoOfBase64(context.screenshotBase64);
|
|
61
|
+
assert(Number.isFinite(screenshotWidth) && screenshotWidth > 0, `Invalid screenshot width when computing screenshot scale: ${screenshotWidth}`);
|
|
62
|
+
const computedScale = screenshotWidth / pageWidth;
|
|
63
|
+
assert(Number.isFinite(computedScale) && computedScale > 0, `Invalid computed screenshot scale: ${computedScale}`);
|
|
64
|
+
debug(`Computed screenshot scale ${computedScale} from screenshot width ${screenshotWidth} and page width ${pageWidth}`);
|
|
65
|
+
return computedScale;
|
|
66
|
+
})();
|
|
67
|
+
try {
|
|
68
|
+
this.screenshotScale = await this.screenshotScalePromise;
|
|
69
|
+
return this.screenshotScale;
|
|
70
|
+
} finally{
|
|
71
|
+
this.screenshotScalePromise = void 0;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
53
74
|
async getActionSpace() {
|
|
54
75
|
return this.interface.actionSpace();
|
|
55
76
|
}
|
|
@@ -59,14 +80,29 @@ class Agent {
|
|
|
59
80
|
debug('Using frozen page context for action:', action);
|
|
60
81
|
return this.frozenUIContext;
|
|
61
82
|
}
|
|
83
|
+
let context;
|
|
62
84
|
if (this.interface.getContext) {
|
|
63
85
|
debug('Using page.getContext for action:', action);
|
|
64
|
-
|
|
86
|
+
context = await this.interface.getContext();
|
|
87
|
+
} else {
|
|
88
|
+
debug('Using commonContextParser for action:', action);
|
|
89
|
+
context = await commonContextParser(this.interface, {
|
|
90
|
+
uploadServerUrl: this.modelConfigManager.getUploadTestServerUrl()
|
|
91
|
+
});
|
|
65
92
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
93
|
+
const computedScreenshotScale = await this.getScreenshotScale(context);
|
|
94
|
+
if (1 !== computedScreenshotScale) {
|
|
95
|
+
const scaleForLog = Number.parseFloat(computedScreenshotScale.toFixed(4));
|
|
96
|
+
debug(`Applying computed screenshot scale: ${scaleForLog} (resize to logical size)`);
|
|
97
|
+
const targetWidth = Math.round(context.size.width);
|
|
98
|
+
const targetHeight = Math.round(context.size.height);
|
|
99
|
+
debug(`Resizing screenshot to ${targetWidth}x${targetHeight}`);
|
|
100
|
+
context.screenshotBase64 = await resizeImgBase64(context.screenshotBase64, {
|
|
101
|
+
width: targetWidth,
|
|
102
|
+
height: targetHeight
|
|
103
|
+
});
|
|
104
|
+
} else debug(`screenshot scale=${computedScreenshotScale}`);
|
|
105
|
+
return context;
|
|
70
106
|
}
|
|
71
107
|
async _snapshotContext() {
|
|
72
108
|
return await this.getUIContext('locate');
|
|
@@ -362,10 +398,14 @@ class Agent {
|
|
|
362
398
|
const { executor, output } = await this.taskExecutor.runPlans(taskTitleStr('Locate', locateParamStr(locateParam)), plans, modelConfig);
|
|
363
399
|
await this.afterTaskRunning(executor);
|
|
364
400
|
const { element } = output;
|
|
401
|
+
const dprValue = await this.interface.size().dpr;
|
|
402
|
+
const dprEntry = dprValue ? {
|
|
403
|
+
dpr: dprValue
|
|
404
|
+
} : {};
|
|
365
405
|
return {
|
|
366
406
|
rect: null == element ? void 0 : element.rect,
|
|
367
407
|
center: null == element ? void 0 : element.center,
|
|
368
|
-
|
|
408
|
+
...dprEntry
|
|
369
409
|
};
|
|
370
410
|
}
|
|
371
411
|
async aiAssert(assertion, msg, opt) {
|
|
@@ -565,6 +605,8 @@ class Agent {
|
|
|
565
605
|
_define_property(this, "modelConfigManager", void 0);
|
|
566
606
|
_define_property(this, "frozenUIContext", void 0);
|
|
567
607
|
_define_property(this, "hasWarnedNonVLModel", false);
|
|
608
|
+
_define_property(this, "screenshotScale", void 0);
|
|
609
|
+
_define_property(this, "screenshotScalePromise", void 0);
|
|
568
610
|
this.interface = interfaceInstance;
|
|
569
611
|
this.opts = Object.assign({
|
|
570
612
|
generateReport: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent/agent.mjs","sources":["webpack://@midscene/core/./src/agent/agent.ts"],"sourcesContent":["import {\n type AgentAssertOpt,\n type AgentDescribeElementAtPointResult,\n type AgentWaitForOpt,\n type DeviceAction,\n type ExecutionDump,\n type ExecutionRecorderItem,\n type ExecutionTask,\n type ExecutionTaskLog,\n type Executor,\n type GroupedActionDump,\n Insight,\n type InsightAction,\n type InsightExtractOption,\n type InsightExtractParam,\n type LocateOption,\n type LocateResultElement,\n type LocateValidatorResult,\n type LocatorValidatorOption,\n type MidsceneYamlScript,\n type OnTaskStartTip,\n type PlanningAction,\n type Rect,\n type ScrollParam,\n type TUserPrompt,\n type UIContext,\n} from '../index';\n\nimport yaml from 'js-yaml';\n\nimport {\n groupedActionDumpFileExt,\n reportHTMLContent,\n stringifyDumpData,\n writeLogFile,\n} from '@/utils';\nimport {\n ScriptPlayer,\n buildDetailedLocateParam,\n parseYamlScript,\n} from '../yaml/index';\n\nimport type { AbstractInterface } from '@/device';\nimport type { AgentOpt, CacheConfig } from '@/types';\nimport {\n MIDSCENE_CACHE,\n ModelConfigManager,\n globalConfigManager,\n globalModelConfigManager,\n} from '@midscene/shared/env';\nimport { getDebug } from '@midscene/shared/logger';\nimport { assert } from '@midscene/shared/utils';\n// import type { AndroidDeviceInputOpt } from '../device';\nimport { TaskCache } from './task-cache';\nimport { TaskExecutor, locatePlanForLocate } from './tasks';\nimport { locateParamStr, paramStr, taskTitleStr, typeStr } from './ui-utils';\nimport {\n commonContextParser,\n getReportFileName,\n parsePrompt,\n printReportMsg,\n} from './utils';\nimport { trimContextByViewport } from './utils';\n\nconst debug = getDebug('agent');\n\nconst distanceOfTwoPoints = (p1: [number, number], p2: [number, number]) => {\n const [x1, y1] = p1;\n const [x2, y2] = p2;\n return Math.round(Math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2));\n};\n\nconst includedInRect = (point: [number, number], rect: Rect) => {\n const [x, y] = point;\n const { left, top, width, height } = rect;\n return x >= left && x <= left + width && y >= top && y <= top + height;\n};\n\nconst defaultInsightExtractOption: InsightExtractOption = {\n domIncluded: false,\n screenshotIncluded: true,\n};\n\ntype CacheStrategy = NonNullable<CacheConfig['strategy']>;\n\nconst CACHE_STRATEGIES: readonly CacheStrategy[] = ['read-only', 'read-write'];\n\nconst isValidCacheStrategy = (strategy: string): strategy is CacheStrategy =>\n CACHE_STRATEGIES.some((value) => value === strategy);\n\nconst CACHE_STRATEGY_VALUES = CACHE_STRATEGIES.map(\n (value) => `\"${value}\"`,\n).join(', ');\n\nexport class Agent<\n InterfaceType extends AbstractInterface = AbstractInterface,\n> {\n interface: InterfaceType;\n\n insight: Insight;\n\n dump: GroupedActionDump;\n\n reportFile?: string | null;\n\n reportFileName?: string;\n\n taskExecutor: TaskExecutor;\n\n opts: AgentOpt;\n\n /**\n * If true, the agent will not perform any actions\n */\n dryMode = false;\n\n onTaskStartTip?: OnTaskStartTip;\n\n taskCache?: TaskCache;\n\n onDumpUpdate?: (dump: string) => void;\n\n destroyed = false;\n\n modelConfigManager: ModelConfigManager;\n\n /**\n * Frozen page context for consistent AI operations\n */\n private frozenUIContext?: UIContext;\n\n /**\n * Flag to track if VL model warning has been shown\n */\n private hasWarnedNonVLModel = false;\n\n // @deprecated use .interface instead\n get page() {\n return this.interface;\n }\n\n /**\n * Ensures VL model warning is shown once when needed\n */\n private ensureVLModelWarning() {\n if (\n !this.hasWarnedNonVLModel &&\n this.interface.interfaceType !== 'puppeteer' &&\n this.interface.interfaceType !== 'playwright' &&\n this.interface.interfaceType !== 'static' &&\n this.interface.interfaceType !== 'chrome-extension-proxy'\n ) {\n this.modelConfigManager.throwErrorIfNonVLModel();\n this.hasWarnedNonVLModel = true;\n }\n }\n\n constructor(interfaceInstance: InterfaceType, opts?: AgentOpt) {\n this.interface = interfaceInstance;\n this.opts = Object.assign(\n {\n generateReport: true,\n autoPrintReportMsg: true,\n groupName: 'Midscene Report',\n groupDescription: '',\n },\n opts || {},\n );\n\n if (opts?.modelConfig && typeof opts?.modelConfig !== 'function') {\n throw new Error(\n `opts.modelConfig must be one of function or undefined, but got ${typeof opts?.modelConfig}`,\n );\n }\n this.modelConfigManager = opts?.modelConfig\n ? new ModelConfigManager(opts.modelConfig)\n : globalModelConfigManager;\n\n this.onTaskStartTip = this.opts.onTaskStartTip;\n\n this.insight = new Insight(async (action: InsightAction) => {\n return this.getUIContext(action);\n });\n\n // Process cache configuration\n const cacheConfig = this.processCacheConfig(opts || {});\n if (cacheConfig) {\n this.taskCache = new TaskCache(\n cacheConfig.id,\n cacheConfig.enabled,\n undefined, // cacheFilePath\n cacheConfig.readOnly,\n );\n }\n\n this.taskExecutor = new TaskExecutor(this.interface, this.insight, {\n taskCache: this.taskCache,\n onTaskStart: this.callbackOnTaskStartTip.bind(this),\n replanningCycleLimit: this.opts.replanningCycleLimit,\n });\n this.dump = this.resetDump();\n this.reportFileName =\n opts?.reportFileName ||\n getReportFileName(opts?.testId || this.interface.interfaceType || 'web');\n }\n\n async getActionSpace(): Promise<DeviceAction[]> {\n return this.interface.actionSpace();\n }\n\n async getUIContext(action?: InsightAction): Promise<UIContext> {\n // Check VL model configuration when UI context is first needed\n this.ensureVLModelWarning();\n\n // If page context is frozen, return the frozen context for all actions\n if (this.frozenUIContext) {\n debug('Using frozen page context for action:', action);\n return this.frozenUIContext;\n }\n\n if (this.interface.getContext) {\n debug('Using page.getContext for action:', action);\n return await this.interface.getContext();\n } else {\n debug('Using commonContextParser for action:', action);\n return await commonContextParser(this.interface, {\n uploadServerUrl: this.modelConfigManager.getUploadTestServerUrl(),\n });\n }\n }\n\n async _snapshotContext(): Promise<UIContext> {\n return await this.getUIContext('locate');\n }\n\n async setAIActionContext(prompt: string) {\n if (this.opts.aiActionContext) {\n console.warn(\n 'aiActionContext is already set, and it is called again, will override the previous setting',\n );\n }\n this.opts.aiActionContext = prompt;\n }\n\n resetDump() {\n this.dump = {\n groupName: this.opts.groupName!,\n groupDescription: this.opts.groupDescription,\n executions: [],\n modelBriefs: [],\n };\n\n return this.dump;\n }\n\n appendExecutionDump(execution: ExecutionDump) {\n // use trimContextByViewport to process execution\n const trimmedExecution = trimContextByViewport(execution);\n const currentDump = this.dump;\n currentDump.executions.push(trimmedExecution);\n }\n\n dumpDataString() {\n // update dump info\n this.dump.groupName = this.opts.groupName!;\n this.dump.groupDescription = this.opts.groupDescription;\n return stringifyDumpData(this.dump);\n }\n\n reportHTMLString() {\n return reportHTMLContent(this.dumpDataString());\n }\n\n writeOutActionDumps() {\n if (this.destroyed) {\n throw new Error(\n 'PageAgent has been destroyed. Cannot update report file.',\n );\n }\n const { generateReport, autoPrintReportMsg } = this.opts;\n this.reportFile = writeLogFile({\n fileName: this.reportFileName!,\n fileExt: groupedActionDumpFileExt,\n fileContent: this.dumpDataString(),\n type: 'dump',\n generateReport,\n });\n debug('writeOutActionDumps', this.reportFile);\n if (generateReport && autoPrintReportMsg && this.reportFile) {\n printReportMsg(this.reportFile);\n }\n }\n\n private async callbackOnTaskStartTip(task: ExecutionTask) {\n const param = paramStr(task);\n const tip = param ? `${typeStr(task)} - ${param}` : typeStr(task);\n\n if (this.onTaskStartTip) {\n await this.onTaskStartTip(tip);\n }\n }\n\n private async afterTaskRunning(executor: Executor, doNotThrowError = false) {\n this.appendExecutionDump(executor.dump());\n\n try {\n if (this.onDumpUpdate) {\n this.onDumpUpdate(this.dumpDataString());\n }\n } catch (error) {\n console.error('Error in onDumpUpdate', error);\n }\n\n this.writeOutActionDumps();\n\n if (executor.isInErrorState() && !doNotThrowError) {\n const errorTask = executor.latestErrorTask();\n throw new Error(`${errorTask?.errorMessage}\\n${errorTask?.errorStack}`, {\n cause: errorTask?.error,\n });\n }\n }\n\n async callActionInActionSpace<T = any>(\n type: string,\n opt?: T, // and all other action params\n ) {\n debug('callActionInActionSpace', type, ',', opt);\n\n const actionPlan: PlanningAction<T> = {\n type: type as any,\n param: (opt as any) || {},\n thought: '',\n };\n debug('actionPlan', actionPlan); // , ', in which the locateParam is', locateParam);\n\n const plans: PlanningAction[] = [actionPlan].filter(\n Boolean,\n ) as PlanningAction[];\n\n const title = taskTitleStr(\n type as any,\n locateParamStr((opt as any)?.locate || {}),\n );\n\n // assume all operation in action space is related to locating\n const modelConfig = this.modelConfigManager.getModelConfig('grounding');\n\n const { output, executor } = await this.taskExecutor.runPlans(\n title,\n plans,\n modelConfig,\n );\n await this.afterTaskRunning(executor);\n return output;\n }\n\n async aiTap(locatePrompt: TUserPrompt, opt?: LocateOption) {\n assert(locatePrompt, 'missing locate prompt for tap');\n\n const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);\n\n return this.callActionInActionSpace('Tap', {\n locate: detailedLocateParam,\n });\n }\n\n async aiRightClick(locatePrompt: TUserPrompt, opt?: LocateOption) {\n assert(locatePrompt, 'missing locate prompt for right click');\n\n const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);\n\n return this.callActionInActionSpace('RightClick', {\n locate: detailedLocateParam,\n });\n }\n\n async aiDoubleClick(locatePrompt: TUserPrompt, opt?: LocateOption) {\n assert(locatePrompt, 'missing locate prompt for double click');\n\n const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);\n\n return this.callActionInActionSpace('DoubleClick', {\n locate: detailedLocateParam,\n });\n }\n\n async aiHover(locatePrompt: TUserPrompt, opt?: LocateOption) {\n assert(locatePrompt, 'missing locate prompt for hover');\n\n const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);\n\n return this.callActionInActionSpace('Hover', {\n locate: detailedLocateParam,\n });\n }\n\n // New signature, always use locatePrompt as the first param\n async aiInput(\n locatePrompt: TUserPrompt,\n opt: LocateOption & { value: string } & { autoDismissKeyboard?: boolean },\n ): Promise<any>;\n\n // Legacy signature - deprecated\n /**\n * @deprecated Use aiInput(locatePrompt, opt) instead where opt contains the value\n */\n async aiInput(\n value: string,\n locatePrompt: TUserPrompt,\n opt?: LocateOption & { autoDismissKeyboard?: boolean }, // AndroidDeviceInputOpt &\n ): Promise<any>;\n\n // Implementation\n async aiInput(\n locatePromptOrValue: TUserPrompt | string,\n locatePromptOrOpt:\n | TUserPrompt\n | (LocateOption & { value: string } & { autoDismissKeyboard?: boolean }) // AndroidDeviceInputOpt &\n | undefined,\n optOrUndefined?: LocateOption, // AndroidDeviceInputOpt &\n ) {\n let value: string;\n let locatePrompt: TUserPrompt;\n let opt:\n | (LocateOption & { value: string } & { autoDismissKeyboard?: boolean }) // AndroidDeviceInputOpt &\n | undefined;\n\n // Check if using new signature (first param is locatePrompt, second has value)\n if (\n typeof locatePromptOrOpt === 'object' &&\n locatePromptOrOpt !== null &&\n 'value' in locatePromptOrOpt\n ) {\n // New signature: aiInput(locatePrompt, opt)\n locatePrompt = locatePromptOrValue as TUserPrompt;\n const optWithValue = locatePromptOrOpt as LocateOption & {\n // AndroidDeviceInputOpt &\n value: string;\n autoDismissKeyboard?: boolean;\n };\n value = optWithValue.value;\n opt = optWithValue;\n } else {\n // Legacy signature: aiInput(value, locatePrompt, opt)\n value = locatePromptOrValue as string;\n locatePrompt = locatePromptOrOpt as TUserPrompt;\n opt = {\n ...optOrUndefined,\n value,\n };\n }\n\n assert(\n typeof value === 'string',\n 'input value must be a string, use empty string if you want to clear the input',\n );\n assert(locatePrompt, 'missing locate prompt for input');\n\n const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);\n\n return this.callActionInActionSpace('Input', {\n ...(opt || {}),\n locate: detailedLocateParam,\n });\n }\n\n // New signature\n async aiKeyboardPress(\n locatePrompt: TUserPrompt,\n opt: LocateOption & { keyName: string },\n ): Promise<any>;\n\n // Legacy signature - deprecated\n /**\n * @deprecated Use aiKeyboardPress(locatePrompt, opt) instead where opt contains the keyName\n */\n async aiKeyboardPress(\n keyName: string,\n locatePrompt?: TUserPrompt,\n opt?: LocateOption,\n ): Promise<any>;\n\n // Implementation\n async aiKeyboardPress(\n locatePromptOrKeyName: TUserPrompt | string,\n locatePromptOrOpt:\n | TUserPrompt\n | (LocateOption & { keyName: string })\n | undefined,\n optOrUndefined?: LocateOption,\n ) {\n let keyName: string;\n let locatePrompt: TUserPrompt | undefined;\n let opt: (LocateOption & { keyName: string }) | undefined;\n\n // Check if using new signature (first param is locatePrompt, second has keyName)\n if (\n typeof locatePromptOrOpt === 'object' &&\n locatePromptOrOpt !== null &&\n 'keyName' in locatePromptOrOpt\n ) {\n // New signature: aiKeyboardPress(locatePrompt, opt)\n locatePrompt = locatePromptOrKeyName as TUserPrompt;\n opt = locatePromptOrOpt as LocateOption & {\n keyName: string;\n };\n } else {\n // Legacy signature: aiKeyboardPress(keyName, locatePrompt, opt)\n keyName = locatePromptOrKeyName as string;\n locatePrompt = locatePromptOrOpt as TUserPrompt | undefined;\n opt = {\n ...(optOrUndefined || {}),\n keyName,\n };\n }\n\n assert(opt?.keyName, 'missing keyName for keyboard press');\n\n const detailedLocateParam = locatePrompt\n ? buildDetailedLocateParam(locatePrompt, opt)\n : undefined;\n\n return this.callActionInActionSpace('KeyboardPress', {\n ...(opt || {}),\n locate: detailedLocateParam,\n });\n }\n\n // New signature\n async aiScroll(\n locatePrompt: TUserPrompt | undefined,\n opt: LocateOption & ScrollParam,\n ): Promise<any>;\n\n // Legacy signature - deprecated\n /**\n * @deprecated Use aiScroll(locatePrompt, opt) instead where opt contains the scroll parameters\n */\n async aiScroll(\n scrollParam: ScrollParam,\n locatePrompt?: TUserPrompt,\n opt?: LocateOption,\n ): Promise<any>;\n\n // Implementation\n async aiScroll(\n locatePromptOrScrollParam: TUserPrompt | ScrollParam | undefined,\n locatePromptOrOpt: TUserPrompt | (LocateOption & ScrollParam) | undefined,\n optOrUndefined?: LocateOption,\n ) {\n let scrollParam: ScrollParam;\n let locatePrompt: TUserPrompt | undefined;\n let opt: LocateOption | undefined;\n\n // Check if using new signature (first param is locatePrompt, second has scroll params)\n if (\n typeof locatePromptOrOpt === 'object' &&\n ('direction' in locatePromptOrOpt ||\n 'scrollType' in locatePromptOrOpt ||\n 'distance' in locatePromptOrOpt)\n ) {\n // New signature: aiScroll(locatePrompt, opt)\n locatePrompt = locatePromptOrScrollParam as TUserPrompt;\n opt = locatePromptOrOpt as LocateOption & ScrollParam;\n } else {\n // Legacy signature: aiScroll(scrollParam, locatePrompt, opt)\n scrollParam = locatePromptOrScrollParam as ScrollParam;\n locatePrompt = locatePromptOrOpt as TUserPrompt | undefined;\n opt = {\n ...(optOrUndefined || {}),\n ...(scrollParam || {}),\n };\n }\n\n const detailedLocateParam = buildDetailedLocateParam(\n locatePrompt || '',\n opt,\n );\n\n return this.callActionInActionSpace('Scroll', {\n ...(opt || {}),\n locate: detailedLocateParam,\n });\n }\n\n async aiAction(\n taskPrompt: string,\n opt?: {\n cacheable?: boolean;\n },\n ) {\n const modelConfig = this.modelConfigManager.getModelConfig('planning');\n\n const cacheable = opt?.cacheable;\n // if vlm-ui-tars, plan cache is not used\n const isVlmUiTars = modelConfig.vlMode === 'vlm-ui-tars';\n const matchedCache =\n isVlmUiTars || cacheable === false\n ? undefined\n : this.taskCache?.matchPlanCache(taskPrompt);\n if (matchedCache && this.taskCache?.isCacheResultUsed) {\n // log into report file\n const { executor } = await this.taskExecutor.loadYamlFlowAsPlanning(\n taskPrompt,\n matchedCache.cacheContent?.yamlWorkflow,\n );\n\n await this.afterTaskRunning(executor);\n\n debug('matched cache, will call .runYaml to run the action');\n const yaml = matchedCache.cacheContent?.yamlWorkflow;\n return this.runYaml(yaml);\n }\n\n const { output, executor } = await this.taskExecutor.action(\n taskPrompt,\n modelConfig,\n this.opts.aiActionContext,\n );\n\n // update cache\n if (this.taskCache && output?.yamlFlow && cacheable !== false) {\n const yamlContent: MidsceneYamlScript = {\n tasks: [\n {\n name: taskPrompt,\n flow: output.yamlFlow,\n },\n ],\n };\n const yamlFlowStr = yaml.dump(yamlContent);\n this.taskCache.updateOrAppendCacheRecord(\n {\n type: 'plan',\n prompt: taskPrompt,\n yamlWorkflow: yamlFlowStr,\n },\n matchedCache,\n );\n }\n\n await this.afterTaskRunning(executor);\n return output;\n }\n\n async aiQuery<ReturnType = any>(\n demand: InsightExtractParam,\n opt: InsightExtractOption = defaultInsightExtractOption,\n ): Promise<ReturnType> {\n const modelConfig = this.modelConfigManager.getModelConfig('VQA');\n const { output, executor } =\n await this.taskExecutor.createTypeQueryExecution(\n 'Query',\n demand,\n modelConfig,\n opt,\n );\n await this.afterTaskRunning(executor);\n return output as ReturnType;\n }\n\n async aiBoolean(\n prompt: TUserPrompt,\n opt: InsightExtractOption = defaultInsightExtractOption,\n ): Promise<boolean> {\n const modelConfig = this.modelConfigManager.getModelConfig('VQA');\n\n const { textPrompt, multimodalPrompt } = parsePrompt(prompt);\n const { output, executor } =\n await this.taskExecutor.createTypeQueryExecution(\n 'Boolean',\n textPrompt,\n modelConfig,\n opt,\n multimodalPrompt,\n );\n await this.afterTaskRunning(executor);\n return output as boolean;\n }\n\n async aiNumber(\n prompt: TUserPrompt,\n opt: InsightExtractOption = defaultInsightExtractOption,\n ): Promise<number> {\n const modelConfig = this.modelConfigManager.getModelConfig('VQA');\n\n const { textPrompt, multimodalPrompt } = parsePrompt(prompt);\n const { output, executor } =\n await this.taskExecutor.createTypeQueryExecution(\n 'Number',\n textPrompt,\n modelConfig,\n opt,\n multimodalPrompt,\n );\n await this.afterTaskRunning(executor);\n return output as number;\n }\n\n async aiString(\n prompt: TUserPrompt,\n opt: InsightExtractOption = defaultInsightExtractOption,\n ): Promise<string> {\n const modelConfig = this.modelConfigManager.getModelConfig('VQA');\n\n const { textPrompt, multimodalPrompt } = parsePrompt(prompt);\n const { output, executor } =\n await this.taskExecutor.createTypeQueryExecution(\n 'String',\n textPrompt,\n modelConfig,\n opt,\n multimodalPrompt,\n );\n await this.afterTaskRunning(executor);\n return output as string;\n }\n\n async aiAsk(\n prompt: TUserPrompt,\n opt: InsightExtractOption = defaultInsightExtractOption,\n ): Promise<string> {\n return this.aiString(prompt, opt);\n }\n\n async describeElementAtPoint(\n center: [number, number],\n opt?: {\n verifyPrompt?: boolean;\n retryLimit?: number;\n deepThink?: boolean;\n } & LocatorValidatorOption,\n ): Promise<AgentDescribeElementAtPointResult> {\n const { verifyPrompt = true, retryLimit = 3 } = opt || {};\n\n let success = false;\n let retryCount = 0;\n let resultPrompt = '';\n let deepThink = opt?.deepThink || false;\n let verifyResult: LocateValidatorResult | undefined;\n\n while (!success && retryCount < retryLimit) {\n if (retryCount >= 2) {\n deepThink = true;\n }\n debug(\n 'aiDescribe',\n center,\n 'verifyPrompt',\n verifyPrompt,\n 'retryCount',\n retryCount,\n 'deepThink',\n deepThink,\n );\n // use same intent as aiLocate\n const modelConfig = this.modelConfigManager.getModelConfig('grounding');\n\n const text = await this.insight.describe(center, modelConfig, {\n deepThink,\n });\n debug('aiDescribe text', text);\n assert(text.description, `failed to describe element at [${center}]`);\n resultPrompt = text.description;\n\n verifyResult = await this.verifyLocator(\n resultPrompt,\n deepThink ? { deepThink: true } : undefined,\n center,\n opt,\n );\n if (verifyResult.pass) {\n success = true;\n } else {\n retryCount++;\n }\n }\n\n return {\n prompt: resultPrompt,\n deepThink,\n verifyResult,\n };\n }\n\n async verifyLocator(\n prompt: string,\n locateOpt: LocateOption | undefined,\n expectCenter: [number, number],\n verifyLocateOption?: LocatorValidatorOption,\n ): Promise<LocateValidatorResult> {\n debug('verifyLocator', prompt, locateOpt, expectCenter, verifyLocateOption);\n\n const { center: verifyCenter, rect: verifyRect } = await this.aiLocate(\n prompt,\n locateOpt,\n );\n const distance = distanceOfTwoPoints(expectCenter, verifyCenter);\n const included = includedInRect(expectCenter, verifyRect);\n const pass =\n distance <= (verifyLocateOption?.centerDistanceThreshold || 20) ||\n included;\n const verifyResult = {\n pass,\n rect: verifyRect,\n center: verifyCenter,\n centerDistance: distance,\n };\n debug('aiDescribe verifyResult', verifyResult);\n return verifyResult;\n }\n\n async aiLocate(prompt: TUserPrompt, opt?: LocateOption) {\n const locateParam = buildDetailedLocateParam(prompt, opt);\n assert(locateParam, 'cannot get locate param for aiLocate');\n const locatePlan = locatePlanForLocate(locateParam);\n const plans = [locatePlan];\n const modelConfig = this.modelConfigManager.getModelConfig('grounding');\n\n const { executor, output } = await this.taskExecutor.runPlans(\n taskTitleStr('Locate', locateParamStr(locateParam)),\n plans,\n modelConfig,\n );\n await this.afterTaskRunning(executor);\n\n const { element } = output;\n\n return {\n rect: element?.rect,\n center: element?.center,\n scale: (await this.interface.size()).dpr,\n } as Pick<LocateResultElement, 'rect' | 'center'> & {\n scale: number;\n };\n }\n\n async aiAssert(\n assertion: TUserPrompt,\n msg?: string,\n opt?: AgentAssertOpt & InsightExtractOption,\n ) {\n const modelConfig = this.modelConfigManager.getModelConfig('VQA');\n\n const insightOpt: InsightExtractOption = {\n domIncluded: opt?.domIncluded ?? defaultInsightExtractOption.domIncluded,\n screenshotIncluded:\n opt?.screenshotIncluded ??\n defaultInsightExtractOption.screenshotIncluded,\n isWaitForAssert: opt?.isWaitForAssert,\n doNotThrowError: opt?.doNotThrowError,\n };\n\n const { output, executor, thought } = await this.taskExecutor.assert(\n assertion,\n modelConfig,\n insightOpt,\n );\n await this.afterTaskRunning(executor, true);\n\n const message = output\n ? undefined\n : `Assertion failed: ${msg || (typeof assertion === 'string' ? assertion : assertion.prompt)}\\nReason: ${\n thought || executor.latestErrorTask()?.error || '(no_reason)'\n }`;\n\n if (opt?.keepRawResponse) {\n return {\n pass: output,\n thought,\n message,\n };\n }\n\n if (!output) {\n throw new Error(message);\n }\n }\n\n async aiWaitFor(assertion: TUserPrompt, opt?: AgentWaitForOpt) {\n const modelConfig = this.modelConfigManager.getModelConfig('VQA');\n const { executor } = await this.taskExecutor.waitFor(\n assertion,\n {\n timeoutMs: opt?.timeoutMs || 15 * 1000,\n checkIntervalMs: opt?.checkIntervalMs || 3 * 1000,\n },\n modelConfig,\n );\n await this.afterTaskRunning(executor, true);\n\n if (executor.isInErrorState()) {\n const errorTask = executor.latestErrorTask();\n throw new Error(`${errorTask?.error}\\n${errorTask?.errorStack}`);\n }\n }\n\n async ai(taskPrompt: string, type = 'action') {\n if (type === 'action') {\n return this.aiAction(taskPrompt);\n }\n if (type === 'query') {\n return this.aiQuery(taskPrompt);\n }\n\n if (type === 'assert') {\n return this.aiAssert(taskPrompt);\n }\n\n if (type === 'tap') {\n return this.aiTap(taskPrompt);\n }\n\n if (type === 'rightClick') {\n return this.aiRightClick(taskPrompt);\n }\n\n if (type === 'doubleClick') {\n return this.aiDoubleClick(taskPrompt);\n }\n\n throw new Error(\n `Unknown type: ${type}, only support 'action', 'query', 'assert', 'tap', 'rightClick', 'doubleClick'`,\n );\n }\n\n async runYaml(yamlScriptContent: string): Promise<{\n result: Record<string, any>;\n }> {\n const script = parseYamlScript(yamlScriptContent, 'yaml');\n const player = new ScriptPlayer(script, async () => {\n return { agent: this, freeFn: [] };\n });\n await player.run();\n\n if (player.status === 'error') {\n const errors = player.taskStatusList\n .filter((task) => task.status === 'error')\n .map((task) => {\n return `task - ${task.name}: ${task.error?.message}`;\n })\n .join('\\n');\n throw new Error(`Error(s) occurred in running yaml script:\\n${errors}`);\n }\n\n return {\n result: player.result,\n };\n }\n\n async evaluateJavaScript(script: string) {\n assert(\n this.interface.evaluateJavaScript,\n 'evaluateJavaScript is not supported in current agent',\n );\n return this.interface.evaluateJavaScript(script);\n }\n\n async destroy() {\n await this.interface.destroy?.();\n this.resetDump(); // reset dump to release memory\n this.destroyed = true;\n }\n\n async logScreenshot(\n title?: string,\n opt?: {\n content: string;\n },\n ) {\n // 1. screenshot\n const base64 = await this.interface.screenshotBase64();\n const now = Date.now();\n // 2. build recorder\n const recorder: ExecutionRecorderItem[] = [\n {\n type: 'screenshot',\n ts: now,\n screenshot: base64,\n },\n ];\n // 3. build ExecutionTaskLog\n const task: ExecutionTaskLog = {\n type: 'Log',\n subType: 'Screenshot',\n status: 'finished',\n recorder,\n timing: {\n start: now,\n end: now,\n cost: 0,\n },\n param: {\n content: opt?.content || '',\n },\n executor: async () => {},\n };\n // 4. build ExecutionDump\n const executionDump: ExecutionDump = {\n sdkVersion: '',\n logTime: now,\n name: `Log - ${title || 'untitled'}`,\n description: opt?.content || '',\n tasks: [task],\n };\n // 5. append to execution dump\n this.appendExecutionDump(executionDump);\n\n try {\n this.onDumpUpdate?.(this.dumpDataString());\n } catch (error) {\n console.error('Failed to update dump', error);\n }\n\n this.writeOutActionDumps();\n }\n\n _unstableLogContent() {\n const { groupName, groupDescription, executions } = this.dump;\n const newExecutions = Array.isArray(executions)\n ? executions.map((execution: any) => {\n const { tasks, ...restExecution } = execution;\n let newTasks = tasks;\n if (Array.isArray(tasks)) {\n newTasks = tasks.map((task: any) => {\n // only remove uiContext and log from task\n const { uiContext, log, ...restTask } = task;\n return restTask;\n });\n }\n return { ...restExecution, ...(newTasks ? { tasks: newTasks } : {}) };\n })\n : [];\n return {\n groupName,\n groupDescription,\n executions: newExecutions,\n };\n }\n\n /**\n * Freezes the current page context to be reused in subsequent AI operations\n * This avoids recalculating page context for each operation\n */\n async freezePageContext(): Promise<void> {\n debug('Freezing page context');\n const context = await this._snapshotContext();\n // Mark the context as frozen\n context._isFrozen = true;\n this.frozenUIContext = context;\n debug('Page context frozen successfully');\n }\n\n /**\n * Unfreezes the page context, allowing AI operations to calculate context dynamically\n */\n async unfreezePageContext(): Promise<void> {\n debug('Unfreezing page context');\n this.frozenUIContext = undefined;\n debug('Page context unfrozen successfully');\n }\n\n /**\n * Process cache configuration and return normalized cache settings\n */\n private processCacheConfig(\n opts: AgentOpt,\n ): { id: string; enabled: boolean; readOnly: boolean } | null {\n // 1. New cache object configuration (highest priority)\n if (opts.cache !== undefined) {\n if (opts.cache === false) {\n return null; // Completely disable cache\n }\n\n if (opts.cache === true) {\n throw new Error(\n 'cache: true requires an explicit cache ID. Please provide:\\n' +\n 'Example: cache: { id: \"my-cache-id\" }',\n );\n }\n\n // cache is object configuration\n if (typeof opts.cache === 'object') {\n const config = opts.cache;\n if (!config.id) {\n throw new Error(\n 'cache configuration requires an explicit id. Please provide:\\n' +\n 'Example: cache: { id: \"my-cache-id\" }',\n );\n }\n const id = config.id;\n const rawStrategy = config.strategy as unknown;\n let strategyValue: string;\n\n if (rawStrategy === undefined) {\n strategyValue = 'read-write';\n } else if (typeof rawStrategy === 'string') {\n strategyValue = rawStrategy;\n } else {\n throw new Error(\n `cache.strategy must be a string when provided, but received type ${typeof rawStrategy}`,\n );\n }\n\n if (!isValidCacheStrategy(strategyValue)) {\n throw new Error(\n `cache.strategy must be one of ${CACHE_STRATEGY_VALUES}, but received \"${strategyValue}\"`,\n );\n }\n\n const isReadOnly = strategyValue === 'read-only';\n\n return {\n id,\n enabled: true,\n readOnly: isReadOnly,\n };\n }\n }\n\n // 2. Backward compatibility: support old cacheId (requires environment variable)\n if (opts.cacheId) {\n const envEnabled =\n globalConfigManager.getEnvConfigInBoolean(MIDSCENE_CACHE);\n if (envEnabled) {\n return {\n id: opts.cacheId,\n enabled: true,\n readOnly: false,\n };\n }\n }\n\n // 3. No cache configuration\n return null;\n }\n\n /**\n * Manually flush cache to file\n * Only meaningful in read-only mode, other modes will throw error\n */\n async flushCache(): Promise<void> {\n if (!this.taskCache) {\n throw new Error('Cache is not configured');\n }\n\n this.taskCache.flushCacheToFile();\n }\n}\n\nexport const createAgent = (\n interfaceInstance: AbstractInterface,\n opts?: AgentOpt,\n) => {\n return new Agent(interfaceInstance, opts);\n};\n"],"names":["debug","getDebug","distanceOfTwoPoints","p1","p2","x1","y1","x2","y2","Math","includedInRect","point","rect","x","y","left","top","width","height","defaultInsightExtractOption","CACHE_STRATEGIES","isValidCacheStrategy","strategy","value","CACHE_STRATEGY_VALUES","Agent","action","commonContextParser","prompt","console","execution","trimmedExecution","trimContextByViewport","currentDump","stringifyDumpData","reportHTMLContent","Error","generateReport","autoPrintReportMsg","writeLogFile","groupedActionDumpFileExt","printReportMsg","task","param","paramStr","tip","typeStr","executor","doNotThrowError","error","errorTask","type","opt","actionPlan","plans","Boolean","title","taskTitleStr","locateParamStr","modelConfig","output","locatePrompt","assert","detailedLocateParam","buildDetailedLocateParam","locatePromptOrValue","locatePromptOrOpt","optOrUndefined","optWithValue","locatePromptOrKeyName","keyName","undefined","locatePromptOrScrollParam","scrollParam","taskPrompt","_this_taskCache","_this_taskCache1","cacheable","isVlmUiTars","matchedCache","_matchedCache_cacheContent","_matchedCache_cacheContent1","yaml","yamlContent","yamlFlowStr","demand","textPrompt","multimodalPrompt","parsePrompt","center","verifyPrompt","retryLimit","success","retryCount","resultPrompt","deepThink","verifyResult","text","locateOpt","expectCenter","verifyLocateOption","verifyCenter","verifyRect","distance","included","pass","locateParam","locatePlan","locatePlanForLocate","element","assertion","msg","_executor_latestErrorTask","insightOpt","thought","message","yamlScriptContent","script","parseYamlScript","player","ScriptPlayer","errors","_task_error","_this_interface","base64","now","Date","recorder","executionDump","_this","groupName","groupDescription","executions","newExecutions","Array","tasks","restExecution","newTasks","uiContext","log","restTask","context","opts","config","id","rawStrategy","strategyValue","isReadOnly","envEnabled","globalConfigManager","MIDSCENE_CACHE","interfaceInstance","Object","ModelConfigManager","globalModelConfigManager","Insight","cacheConfig","TaskCache","TaskExecutor","getReportFileName","createAgent"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"agent/agent.mjs","sources":["webpack://@midscene/core/./src/agent/agent.ts"],"sourcesContent":["import {\n type AgentAssertOpt,\n type AgentDescribeElementAtPointResult,\n type AgentWaitForOpt,\n type DeviceAction,\n type ExecutionDump,\n type ExecutionRecorderItem,\n type ExecutionTask,\n type ExecutionTaskLog,\n type Executor,\n type GroupedActionDump,\n Insight,\n type InsightAction,\n type InsightExtractOption,\n type InsightExtractParam,\n type LocateOption,\n type LocateResultElement,\n type LocateValidatorResult,\n type LocatorValidatorOption,\n type MidsceneYamlScript,\n type OnTaskStartTip,\n type PlanningAction,\n type Rect,\n type ScrollParam,\n type TUserPrompt,\n type UIContext,\n} from '../index';\n\nimport yaml from 'js-yaml';\n\nimport {\n groupedActionDumpFileExt,\n reportHTMLContent,\n stringifyDumpData,\n writeLogFile,\n} from '@/utils';\nimport {\n ScriptPlayer,\n buildDetailedLocateParam,\n parseYamlScript,\n} from '../yaml/index';\n\nimport type { AbstractInterface } from '@/device';\nimport type { AgentOpt, CacheConfig } from '@/types';\nimport {\n MIDSCENE_CACHE,\n ModelConfigManager,\n globalConfigManager,\n globalModelConfigManager,\n} from '@midscene/shared/env';\nimport { imageInfoOfBase64, resizeImgBase64 } from '@midscene/shared/img';\nimport { getDebug } from '@midscene/shared/logger';\nimport { assert } from '@midscene/shared/utils';\n// import type { AndroidDeviceInputOpt } from '../device';\nimport { TaskCache } from './task-cache';\nimport { TaskExecutor, locatePlanForLocate } from './tasks';\nimport { locateParamStr, paramStr, taskTitleStr, typeStr } from './ui-utils';\nimport {\n commonContextParser,\n getReportFileName,\n parsePrompt,\n printReportMsg,\n} from './utils';\nimport { trimContextByViewport } from './utils';\n\nconst debug = getDebug('agent');\n\nconst distanceOfTwoPoints = (p1: [number, number], p2: [number, number]) => {\n const [x1, y1] = p1;\n const [x2, y2] = p2;\n return Math.round(Math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2));\n};\n\nconst includedInRect = (point: [number, number], rect: Rect) => {\n const [x, y] = point;\n const { left, top, width, height } = rect;\n return x >= left && x <= left + width && y >= top && y <= top + height;\n};\n\nconst defaultInsightExtractOption: InsightExtractOption = {\n domIncluded: false,\n screenshotIncluded: true,\n};\n\ntype CacheStrategy = NonNullable<CacheConfig['strategy']>;\n\nconst CACHE_STRATEGIES: readonly CacheStrategy[] = ['read-only', 'read-write'];\n\nconst isValidCacheStrategy = (strategy: string): strategy is CacheStrategy =>\n CACHE_STRATEGIES.some((value) => value === strategy);\n\nconst CACHE_STRATEGY_VALUES = CACHE_STRATEGIES.map(\n (value) => `\"${value}\"`,\n).join(', ');\n\nexport class Agent<\n InterfaceType extends AbstractInterface = AbstractInterface,\n> {\n interface: InterfaceType;\n\n insight: Insight;\n\n dump: GroupedActionDump;\n\n reportFile?: string | null;\n\n reportFileName?: string;\n\n taskExecutor: TaskExecutor;\n\n opts: AgentOpt;\n\n /**\n * If true, the agent will not perform any actions\n */\n dryMode = false;\n\n onTaskStartTip?: OnTaskStartTip;\n\n taskCache?: TaskCache;\n\n onDumpUpdate?: (dump: string) => void;\n\n destroyed = false;\n\n modelConfigManager: ModelConfigManager;\n\n /**\n * Frozen page context for consistent AI operations\n */\n private frozenUIContext?: UIContext;\n\n /**\n * Flag to track if VL model warning has been shown\n */\n private hasWarnedNonVLModel = false;\n\n /**\n * Screenshot scale factor derived from actual screenshot dimensions\n */\n private screenshotScale?: number;\n\n /**\n * Internal promise to deduplicate screenshot scale computation\n */\n private screenshotScalePromise?: Promise<number>;\n\n // @deprecated use .interface instead\n get page() {\n return this.interface;\n }\n\n /**\n * Ensures VL model warning is shown once when needed\n */\n private ensureVLModelWarning() {\n if (\n !this.hasWarnedNonVLModel &&\n this.interface.interfaceType !== 'puppeteer' &&\n this.interface.interfaceType !== 'playwright' &&\n this.interface.interfaceType !== 'static' &&\n this.interface.interfaceType !== 'chrome-extension-proxy'\n ) {\n this.modelConfigManager.throwErrorIfNonVLModel();\n this.hasWarnedNonVLModel = true;\n }\n }\n\n /**\n * Lazily compute the ratio between the physical screenshot width and the logical page width\n */\n private async getScreenshotScale(context: UIContext): Promise<number> {\n if (this.screenshotScale !== undefined) {\n return this.screenshotScale;\n }\n\n if (!this.screenshotScalePromise) {\n this.screenshotScalePromise = (async () => {\n const pageWidth = context.size?.width;\n assert(\n pageWidth && pageWidth > 0,\n `Invalid page width when computing screenshot scale: ${pageWidth}`,\n );\n\n const { width: screenshotWidth } = await imageInfoOfBase64(\n context.screenshotBase64,\n );\n\n assert(\n Number.isFinite(screenshotWidth) && screenshotWidth > 0,\n `Invalid screenshot width when computing screenshot scale: ${screenshotWidth}`,\n );\n\n const computedScale = screenshotWidth / pageWidth;\n assert(\n Number.isFinite(computedScale) && computedScale > 0,\n `Invalid computed screenshot scale: ${computedScale}`,\n );\n\n debug(\n `Computed screenshot scale ${computedScale} from screenshot width ${screenshotWidth} and page width ${pageWidth}`,\n );\n return computedScale;\n })();\n }\n\n try {\n this.screenshotScale = await this.screenshotScalePromise;\n return this.screenshotScale;\n } finally {\n this.screenshotScalePromise = undefined;\n }\n }\n\n constructor(interfaceInstance: InterfaceType, opts?: AgentOpt) {\n this.interface = interfaceInstance;\n this.opts = Object.assign(\n {\n generateReport: true,\n autoPrintReportMsg: true,\n groupName: 'Midscene Report',\n groupDescription: '',\n },\n opts || {},\n );\n\n if (opts?.modelConfig && typeof opts?.modelConfig !== 'function') {\n throw new Error(\n `opts.modelConfig must be one of function or undefined, but got ${typeof opts?.modelConfig}`,\n );\n }\n this.modelConfigManager = opts?.modelConfig\n ? new ModelConfigManager(opts.modelConfig)\n : globalModelConfigManager;\n\n this.onTaskStartTip = this.opts.onTaskStartTip;\n\n this.insight = new Insight(async (action: InsightAction) => {\n return this.getUIContext(action);\n });\n\n // Process cache configuration\n const cacheConfig = this.processCacheConfig(opts || {});\n if (cacheConfig) {\n this.taskCache = new TaskCache(\n cacheConfig.id,\n cacheConfig.enabled,\n undefined, // cacheFilePath\n cacheConfig.readOnly,\n );\n }\n\n this.taskExecutor = new TaskExecutor(this.interface, this.insight, {\n taskCache: this.taskCache,\n onTaskStart: this.callbackOnTaskStartTip.bind(this),\n replanningCycleLimit: this.opts.replanningCycleLimit,\n });\n this.dump = this.resetDump();\n this.reportFileName =\n opts?.reportFileName ||\n getReportFileName(opts?.testId || this.interface.interfaceType || 'web');\n }\n\n async getActionSpace(): Promise<DeviceAction[]> {\n return this.interface.actionSpace();\n }\n\n async getUIContext(action?: InsightAction): Promise<UIContext> {\n // Check VL model configuration when UI context is first needed\n this.ensureVLModelWarning();\n\n // If page context is frozen, return the frozen context for all actions\n if (this.frozenUIContext) {\n debug('Using frozen page context for action:', action);\n return this.frozenUIContext;\n }\n\n // Get original context\n let context: UIContext;\n if (this.interface.getContext) {\n debug('Using page.getContext for action:', action);\n context = await this.interface.getContext();\n } else {\n debug('Using commonContextParser for action:', action);\n context = await commonContextParser(this.interface, {\n uploadServerUrl: this.modelConfigManager.getUploadTestServerUrl(),\n });\n }\n\n const computedScreenshotScale = await this.getScreenshotScale(context);\n\n if (computedScreenshotScale !== 1) {\n const scaleForLog = Number.parseFloat(computedScreenshotScale.toFixed(4));\n debug(\n `Applying computed screenshot scale: ${scaleForLog} (resize to logical size)`,\n );\n const targetWidth = Math.round(context.size.width);\n const targetHeight = Math.round(context.size.height);\n debug(`Resizing screenshot to ${targetWidth}x${targetHeight}`);\n context.screenshotBase64 = await resizeImgBase64(\n context.screenshotBase64,\n { width: targetWidth, height: targetHeight },\n );\n } else {\n debug(`screenshot scale=${computedScreenshotScale}`);\n }\n\n return context;\n }\n\n async _snapshotContext(): Promise<UIContext> {\n return await this.getUIContext('locate');\n }\n\n async setAIActionContext(prompt: string) {\n if (this.opts.aiActionContext) {\n console.warn(\n 'aiActionContext is already set, and it is called again, will override the previous setting',\n );\n }\n this.opts.aiActionContext = prompt;\n }\n\n resetDump() {\n this.dump = {\n groupName: this.opts.groupName!,\n groupDescription: this.opts.groupDescription,\n executions: [],\n modelBriefs: [],\n };\n\n return this.dump;\n }\n\n appendExecutionDump(execution: ExecutionDump) {\n // use trimContextByViewport to process execution\n const trimmedExecution = trimContextByViewport(execution);\n const currentDump = this.dump;\n currentDump.executions.push(trimmedExecution);\n }\n\n dumpDataString() {\n // update dump info\n this.dump.groupName = this.opts.groupName!;\n this.dump.groupDescription = this.opts.groupDescription;\n return stringifyDumpData(this.dump);\n }\n\n reportHTMLString() {\n return reportHTMLContent(this.dumpDataString());\n }\n\n writeOutActionDumps() {\n if (this.destroyed) {\n throw new Error(\n 'PageAgent has been destroyed. Cannot update report file.',\n );\n }\n const { generateReport, autoPrintReportMsg } = this.opts;\n this.reportFile = writeLogFile({\n fileName: this.reportFileName!,\n fileExt: groupedActionDumpFileExt,\n fileContent: this.dumpDataString(),\n type: 'dump',\n generateReport,\n });\n debug('writeOutActionDumps', this.reportFile);\n if (generateReport && autoPrintReportMsg && this.reportFile) {\n printReportMsg(this.reportFile);\n }\n }\n\n private async callbackOnTaskStartTip(task: ExecutionTask) {\n const param = paramStr(task);\n const tip = param ? `${typeStr(task)} - ${param}` : typeStr(task);\n\n if (this.onTaskStartTip) {\n await this.onTaskStartTip(tip);\n }\n }\n\n private async afterTaskRunning(executor: Executor, doNotThrowError = false) {\n this.appendExecutionDump(executor.dump());\n\n try {\n if (this.onDumpUpdate) {\n this.onDumpUpdate(this.dumpDataString());\n }\n } catch (error) {\n console.error('Error in onDumpUpdate', error);\n }\n\n this.writeOutActionDumps();\n\n if (executor.isInErrorState() && !doNotThrowError) {\n const errorTask = executor.latestErrorTask();\n throw new Error(`${errorTask?.errorMessage}\\n${errorTask?.errorStack}`, {\n cause: errorTask?.error,\n });\n }\n }\n\n async callActionInActionSpace<T = any>(\n type: string,\n opt?: T, // and all other action params\n ) {\n debug('callActionInActionSpace', type, ',', opt);\n\n const actionPlan: PlanningAction<T> = {\n type: type as any,\n param: (opt as any) || {},\n thought: '',\n };\n debug('actionPlan', actionPlan); // , ', in which the locateParam is', locateParam);\n\n const plans: PlanningAction[] = [actionPlan].filter(\n Boolean,\n ) as PlanningAction[];\n\n const title = taskTitleStr(\n type as any,\n locateParamStr((opt as any)?.locate || {}),\n );\n\n // assume all operation in action space is related to locating\n const modelConfig = this.modelConfigManager.getModelConfig('grounding');\n\n const { output, executor } = await this.taskExecutor.runPlans(\n title,\n plans,\n modelConfig,\n );\n await this.afterTaskRunning(executor);\n return output;\n }\n\n async aiTap(locatePrompt: TUserPrompt, opt?: LocateOption) {\n assert(locatePrompt, 'missing locate prompt for tap');\n\n const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);\n\n return this.callActionInActionSpace('Tap', {\n locate: detailedLocateParam,\n });\n }\n\n async aiRightClick(locatePrompt: TUserPrompt, opt?: LocateOption) {\n assert(locatePrompt, 'missing locate prompt for right click');\n\n const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);\n\n return this.callActionInActionSpace('RightClick', {\n locate: detailedLocateParam,\n });\n }\n\n async aiDoubleClick(locatePrompt: TUserPrompt, opt?: LocateOption) {\n assert(locatePrompt, 'missing locate prompt for double click');\n\n const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);\n\n return this.callActionInActionSpace('DoubleClick', {\n locate: detailedLocateParam,\n });\n }\n\n async aiHover(locatePrompt: TUserPrompt, opt?: LocateOption) {\n assert(locatePrompt, 'missing locate prompt for hover');\n\n const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);\n\n return this.callActionInActionSpace('Hover', {\n locate: detailedLocateParam,\n });\n }\n\n // New signature, always use locatePrompt as the first param\n async aiInput(\n locatePrompt: TUserPrompt,\n opt: LocateOption & { value: string } & { autoDismissKeyboard?: boolean },\n ): Promise<any>;\n\n // Legacy signature - deprecated\n /**\n * @deprecated Use aiInput(locatePrompt, opt) instead where opt contains the value\n */\n async aiInput(\n value: string,\n locatePrompt: TUserPrompt,\n opt?: LocateOption & { autoDismissKeyboard?: boolean }, // AndroidDeviceInputOpt &\n ): Promise<any>;\n\n // Implementation\n async aiInput(\n locatePromptOrValue: TUserPrompt | string,\n locatePromptOrOpt:\n | TUserPrompt\n | (LocateOption & { value: string } & { autoDismissKeyboard?: boolean }) // AndroidDeviceInputOpt &\n | undefined,\n optOrUndefined?: LocateOption, // AndroidDeviceInputOpt &\n ) {\n let value: string;\n let locatePrompt: TUserPrompt;\n let opt:\n | (LocateOption & { value: string } & { autoDismissKeyboard?: boolean }) // AndroidDeviceInputOpt &\n | undefined;\n\n // Check if using new signature (first param is locatePrompt, second has value)\n if (\n typeof locatePromptOrOpt === 'object' &&\n locatePromptOrOpt !== null &&\n 'value' in locatePromptOrOpt\n ) {\n // New signature: aiInput(locatePrompt, opt)\n locatePrompt = locatePromptOrValue as TUserPrompt;\n const optWithValue = locatePromptOrOpt as LocateOption & {\n // AndroidDeviceInputOpt &\n value: string;\n autoDismissKeyboard?: boolean;\n };\n value = optWithValue.value;\n opt = optWithValue;\n } else {\n // Legacy signature: aiInput(value, locatePrompt, opt)\n value = locatePromptOrValue as string;\n locatePrompt = locatePromptOrOpt as TUserPrompt;\n opt = {\n ...optOrUndefined,\n value,\n };\n }\n\n assert(\n typeof value === 'string',\n 'input value must be a string, use empty string if you want to clear the input',\n );\n assert(locatePrompt, 'missing locate prompt for input');\n\n const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);\n\n return this.callActionInActionSpace('Input', {\n ...(opt || {}),\n locate: detailedLocateParam,\n });\n }\n\n // New signature\n async aiKeyboardPress(\n locatePrompt: TUserPrompt,\n opt: LocateOption & { keyName: string },\n ): Promise<any>;\n\n // Legacy signature - deprecated\n /**\n * @deprecated Use aiKeyboardPress(locatePrompt, opt) instead where opt contains the keyName\n */\n async aiKeyboardPress(\n keyName: string,\n locatePrompt?: TUserPrompt,\n opt?: LocateOption,\n ): Promise<any>;\n\n // Implementation\n async aiKeyboardPress(\n locatePromptOrKeyName: TUserPrompt | string,\n locatePromptOrOpt:\n | TUserPrompt\n | (LocateOption & { keyName: string })\n | undefined,\n optOrUndefined?: LocateOption,\n ) {\n let keyName: string;\n let locatePrompt: TUserPrompt | undefined;\n let opt: (LocateOption & { keyName: string }) | undefined;\n\n // Check if using new signature (first param is locatePrompt, second has keyName)\n if (\n typeof locatePromptOrOpt === 'object' &&\n locatePromptOrOpt !== null &&\n 'keyName' in locatePromptOrOpt\n ) {\n // New signature: aiKeyboardPress(locatePrompt, opt)\n locatePrompt = locatePromptOrKeyName as TUserPrompt;\n opt = locatePromptOrOpt as LocateOption & {\n keyName: string;\n };\n } else {\n // Legacy signature: aiKeyboardPress(keyName, locatePrompt, opt)\n keyName = locatePromptOrKeyName as string;\n locatePrompt = locatePromptOrOpt as TUserPrompt | undefined;\n opt = {\n ...(optOrUndefined || {}),\n keyName,\n };\n }\n\n assert(opt?.keyName, 'missing keyName for keyboard press');\n\n const detailedLocateParam = locatePrompt\n ? buildDetailedLocateParam(locatePrompt, opt)\n : undefined;\n\n return this.callActionInActionSpace('KeyboardPress', {\n ...(opt || {}),\n locate: detailedLocateParam,\n });\n }\n\n // New signature\n async aiScroll(\n locatePrompt: TUserPrompt | undefined,\n opt: LocateOption & ScrollParam,\n ): Promise<any>;\n\n // Legacy signature - deprecated\n /**\n * @deprecated Use aiScroll(locatePrompt, opt) instead where opt contains the scroll parameters\n */\n async aiScroll(\n scrollParam: ScrollParam,\n locatePrompt?: TUserPrompt,\n opt?: LocateOption,\n ): Promise<any>;\n\n // Implementation\n async aiScroll(\n locatePromptOrScrollParam: TUserPrompt | ScrollParam | undefined,\n locatePromptOrOpt: TUserPrompt | (LocateOption & ScrollParam) | undefined,\n optOrUndefined?: LocateOption,\n ) {\n let scrollParam: ScrollParam;\n let locatePrompt: TUserPrompt | undefined;\n let opt: LocateOption | undefined;\n\n // Check if using new signature (first param is locatePrompt, second has scroll params)\n if (\n typeof locatePromptOrOpt === 'object' &&\n ('direction' in locatePromptOrOpt ||\n 'scrollType' in locatePromptOrOpt ||\n 'distance' in locatePromptOrOpt)\n ) {\n // New signature: aiScroll(locatePrompt, opt)\n locatePrompt = locatePromptOrScrollParam as TUserPrompt;\n opt = locatePromptOrOpt as LocateOption & ScrollParam;\n } else {\n // Legacy signature: aiScroll(scrollParam, locatePrompt, opt)\n scrollParam = locatePromptOrScrollParam as ScrollParam;\n locatePrompt = locatePromptOrOpt as TUserPrompt | undefined;\n opt = {\n ...(optOrUndefined || {}),\n ...(scrollParam || {}),\n };\n }\n\n const detailedLocateParam = buildDetailedLocateParam(\n locatePrompt || '',\n opt,\n );\n\n return this.callActionInActionSpace('Scroll', {\n ...(opt || {}),\n locate: detailedLocateParam,\n });\n }\n\n async aiAction(\n taskPrompt: string,\n opt?: {\n cacheable?: boolean;\n },\n ) {\n const modelConfig = this.modelConfigManager.getModelConfig('planning');\n\n const cacheable = opt?.cacheable;\n // if vlm-ui-tars, plan cache is not used\n const isVlmUiTars = modelConfig.vlMode === 'vlm-ui-tars';\n const matchedCache =\n isVlmUiTars || cacheable === false\n ? undefined\n : this.taskCache?.matchPlanCache(taskPrompt);\n if (matchedCache && this.taskCache?.isCacheResultUsed) {\n // log into report file\n const { executor } = await this.taskExecutor.loadYamlFlowAsPlanning(\n taskPrompt,\n matchedCache.cacheContent?.yamlWorkflow,\n );\n\n await this.afterTaskRunning(executor);\n\n debug('matched cache, will call .runYaml to run the action');\n const yaml = matchedCache.cacheContent?.yamlWorkflow;\n return this.runYaml(yaml);\n }\n\n const { output, executor } = await this.taskExecutor.action(\n taskPrompt,\n modelConfig,\n this.opts.aiActionContext,\n );\n\n // update cache\n if (this.taskCache && output?.yamlFlow && cacheable !== false) {\n const yamlContent: MidsceneYamlScript = {\n tasks: [\n {\n name: taskPrompt,\n flow: output.yamlFlow,\n },\n ],\n };\n const yamlFlowStr = yaml.dump(yamlContent);\n this.taskCache.updateOrAppendCacheRecord(\n {\n type: 'plan',\n prompt: taskPrompt,\n yamlWorkflow: yamlFlowStr,\n },\n matchedCache,\n );\n }\n\n await this.afterTaskRunning(executor);\n return output;\n }\n\n async aiQuery<ReturnType = any>(\n demand: InsightExtractParam,\n opt: InsightExtractOption = defaultInsightExtractOption,\n ): Promise<ReturnType> {\n const modelConfig = this.modelConfigManager.getModelConfig('VQA');\n const { output, executor } =\n await this.taskExecutor.createTypeQueryExecution(\n 'Query',\n demand,\n modelConfig,\n opt,\n );\n await this.afterTaskRunning(executor);\n return output as ReturnType;\n }\n\n async aiBoolean(\n prompt: TUserPrompt,\n opt: InsightExtractOption = defaultInsightExtractOption,\n ): Promise<boolean> {\n const modelConfig = this.modelConfigManager.getModelConfig('VQA');\n\n const { textPrompt, multimodalPrompt } = parsePrompt(prompt);\n const { output, executor } =\n await this.taskExecutor.createTypeQueryExecution(\n 'Boolean',\n textPrompt,\n modelConfig,\n opt,\n multimodalPrompt,\n );\n await this.afterTaskRunning(executor);\n return output as boolean;\n }\n\n async aiNumber(\n prompt: TUserPrompt,\n opt: InsightExtractOption = defaultInsightExtractOption,\n ): Promise<number> {\n const modelConfig = this.modelConfigManager.getModelConfig('VQA');\n\n const { textPrompt, multimodalPrompt } = parsePrompt(prompt);\n const { output, executor } =\n await this.taskExecutor.createTypeQueryExecution(\n 'Number',\n textPrompt,\n modelConfig,\n opt,\n multimodalPrompt,\n );\n await this.afterTaskRunning(executor);\n return output as number;\n }\n\n async aiString(\n prompt: TUserPrompt,\n opt: InsightExtractOption = defaultInsightExtractOption,\n ): Promise<string> {\n const modelConfig = this.modelConfigManager.getModelConfig('VQA');\n\n const { textPrompt, multimodalPrompt } = parsePrompt(prompt);\n const { output, executor } =\n await this.taskExecutor.createTypeQueryExecution(\n 'String',\n textPrompt,\n modelConfig,\n opt,\n multimodalPrompt,\n );\n await this.afterTaskRunning(executor);\n return output as string;\n }\n\n async aiAsk(\n prompt: TUserPrompt,\n opt: InsightExtractOption = defaultInsightExtractOption,\n ): Promise<string> {\n return this.aiString(prompt, opt);\n }\n\n async describeElementAtPoint(\n center: [number, number],\n opt?: {\n verifyPrompt?: boolean;\n retryLimit?: number;\n deepThink?: boolean;\n } & LocatorValidatorOption,\n ): Promise<AgentDescribeElementAtPointResult> {\n const { verifyPrompt = true, retryLimit = 3 } = opt || {};\n\n let success = false;\n let retryCount = 0;\n let resultPrompt = '';\n let deepThink = opt?.deepThink || false;\n let verifyResult: LocateValidatorResult | undefined;\n\n while (!success && retryCount < retryLimit) {\n if (retryCount >= 2) {\n deepThink = true;\n }\n debug(\n 'aiDescribe',\n center,\n 'verifyPrompt',\n verifyPrompt,\n 'retryCount',\n retryCount,\n 'deepThink',\n deepThink,\n );\n // use same intent as aiLocate\n const modelConfig = this.modelConfigManager.getModelConfig('grounding');\n\n const text = await this.insight.describe(center, modelConfig, {\n deepThink,\n });\n debug('aiDescribe text', text);\n assert(text.description, `failed to describe element at [${center}]`);\n resultPrompt = text.description;\n\n verifyResult = await this.verifyLocator(\n resultPrompt,\n deepThink ? { deepThink: true } : undefined,\n center,\n opt,\n );\n if (verifyResult.pass) {\n success = true;\n } else {\n retryCount++;\n }\n }\n\n return {\n prompt: resultPrompt,\n deepThink,\n verifyResult,\n };\n }\n\n async verifyLocator(\n prompt: string,\n locateOpt: LocateOption | undefined,\n expectCenter: [number, number],\n verifyLocateOption?: LocatorValidatorOption,\n ): Promise<LocateValidatorResult> {\n debug('verifyLocator', prompt, locateOpt, expectCenter, verifyLocateOption);\n\n const { center: verifyCenter, rect: verifyRect } = await this.aiLocate(\n prompt,\n locateOpt,\n );\n const distance = distanceOfTwoPoints(expectCenter, verifyCenter);\n const included = includedInRect(expectCenter, verifyRect);\n const pass =\n distance <= (verifyLocateOption?.centerDistanceThreshold || 20) ||\n included;\n const verifyResult = {\n pass,\n rect: verifyRect,\n center: verifyCenter,\n centerDistance: distance,\n };\n debug('aiDescribe verifyResult', verifyResult);\n return verifyResult;\n }\n\n async aiLocate(prompt: TUserPrompt, opt?: LocateOption) {\n const locateParam = buildDetailedLocateParam(prompt, opt);\n assert(locateParam, 'cannot get locate param for aiLocate');\n const locatePlan = locatePlanForLocate(locateParam);\n const plans = [locatePlan];\n const modelConfig = this.modelConfigManager.getModelConfig('grounding');\n\n const { executor, output } = await this.taskExecutor.runPlans(\n taskTitleStr('Locate', locateParamStr(locateParam)),\n plans,\n modelConfig,\n );\n await this.afterTaskRunning(executor);\n\n const { element } = output;\n\n const dprValue = await (this.interface.size() as any).dpr;\n const dprEntry = dprValue\n ? {\n dpr: dprValue,\n }\n : {};\n return {\n rect: element?.rect,\n center: element?.center,\n ...dprEntry,\n } as Pick<LocateResultElement, 'rect' | 'center'> & {\n dpr?: number; // this field is deprecated\n };\n }\n\n async aiAssert(\n assertion: TUserPrompt,\n msg?: string,\n opt?: AgentAssertOpt & InsightExtractOption,\n ) {\n const modelConfig = this.modelConfigManager.getModelConfig('VQA');\n\n const insightOpt: InsightExtractOption = {\n domIncluded: opt?.domIncluded ?? defaultInsightExtractOption.domIncluded,\n screenshotIncluded:\n opt?.screenshotIncluded ??\n defaultInsightExtractOption.screenshotIncluded,\n isWaitForAssert: opt?.isWaitForAssert,\n doNotThrowError: opt?.doNotThrowError,\n };\n\n const { output, executor, thought } = await this.taskExecutor.assert(\n assertion,\n modelConfig,\n insightOpt,\n );\n await this.afterTaskRunning(executor, true);\n\n const message = output\n ? undefined\n : `Assertion failed: ${msg || (typeof assertion === 'string' ? assertion : assertion.prompt)}\\nReason: ${\n thought || executor.latestErrorTask()?.error || '(no_reason)'\n }`;\n\n if (opt?.keepRawResponse) {\n return {\n pass: output,\n thought,\n message,\n };\n }\n\n if (!output) {\n throw new Error(message);\n }\n }\n\n async aiWaitFor(assertion: TUserPrompt, opt?: AgentWaitForOpt) {\n const modelConfig = this.modelConfigManager.getModelConfig('VQA');\n const { executor } = await this.taskExecutor.waitFor(\n assertion,\n {\n timeoutMs: opt?.timeoutMs || 15 * 1000,\n checkIntervalMs: opt?.checkIntervalMs || 3 * 1000,\n },\n modelConfig,\n );\n await this.afterTaskRunning(executor, true);\n\n if (executor.isInErrorState()) {\n const errorTask = executor.latestErrorTask();\n throw new Error(`${errorTask?.error}\\n${errorTask?.errorStack}`);\n }\n }\n\n async ai(taskPrompt: string, type = 'action') {\n if (type === 'action') {\n return this.aiAction(taskPrompt);\n }\n if (type === 'query') {\n return this.aiQuery(taskPrompt);\n }\n\n if (type === 'assert') {\n return this.aiAssert(taskPrompt);\n }\n\n if (type === 'tap') {\n return this.aiTap(taskPrompt);\n }\n\n if (type === 'rightClick') {\n return this.aiRightClick(taskPrompt);\n }\n\n if (type === 'doubleClick') {\n return this.aiDoubleClick(taskPrompt);\n }\n\n throw new Error(\n `Unknown type: ${type}, only support 'action', 'query', 'assert', 'tap', 'rightClick', 'doubleClick'`,\n );\n }\n\n async runYaml(yamlScriptContent: string): Promise<{\n result: Record<string, any>;\n }> {\n const script = parseYamlScript(yamlScriptContent, 'yaml');\n const player = new ScriptPlayer(script, async () => {\n return { agent: this, freeFn: [] };\n });\n await player.run();\n\n if (player.status === 'error') {\n const errors = player.taskStatusList\n .filter((task) => task.status === 'error')\n .map((task) => {\n return `task - ${task.name}: ${task.error?.message}`;\n })\n .join('\\n');\n throw new Error(`Error(s) occurred in running yaml script:\\n${errors}`);\n }\n\n return {\n result: player.result,\n };\n }\n\n async evaluateJavaScript(script: string) {\n assert(\n this.interface.evaluateJavaScript,\n 'evaluateJavaScript is not supported in current agent',\n );\n return this.interface.evaluateJavaScript(script);\n }\n\n async destroy() {\n await this.interface.destroy?.();\n this.resetDump(); // reset dump to release memory\n this.destroyed = true;\n }\n\n async logScreenshot(\n title?: string,\n opt?: {\n content: string;\n },\n ) {\n // 1. screenshot\n const base64 = await this.interface.screenshotBase64();\n const now = Date.now();\n // 2. build recorder\n const recorder: ExecutionRecorderItem[] = [\n {\n type: 'screenshot',\n ts: now,\n screenshot: base64,\n },\n ];\n // 3. build ExecutionTaskLog\n const task: ExecutionTaskLog = {\n type: 'Log',\n subType: 'Screenshot',\n status: 'finished',\n recorder,\n timing: {\n start: now,\n end: now,\n cost: 0,\n },\n param: {\n content: opt?.content || '',\n },\n executor: async () => {},\n };\n // 4. build ExecutionDump\n const executionDump: ExecutionDump = {\n sdkVersion: '',\n logTime: now,\n name: `Log - ${title || 'untitled'}`,\n description: opt?.content || '',\n tasks: [task],\n };\n // 5. append to execution dump\n this.appendExecutionDump(executionDump);\n\n try {\n this.onDumpUpdate?.(this.dumpDataString());\n } catch (error) {\n console.error('Failed to update dump', error);\n }\n\n this.writeOutActionDumps();\n }\n\n _unstableLogContent() {\n const { groupName, groupDescription, executions } = this.dump;\n const newExecutions = Array.isArray(executions)\n ? executions.map((execution: any) => {\n const { tasks, ...restExecution } = execution;\n let newTasks = tasks;\n if (Array.isArray(tasks)) {\n newTasks = tasks.map((task: any) => {\n // only remove uiContext and log from task\n const { uiContext, log, ...restTask } = task;\n return restTask;\n });\n }\n return { ...restExecution, ...(newTasks ? { tasks: newTasks } : {}) };\n })\n : [];\n return {\n groupName,\n groupDescription,\n executions: newExecutions,\n };\n }\n\n /**\n * Freezes the current page context to be reused in subsequent AI operations\n * This avoids recalculating page context for each operation\n */\n async freezePageContext(): Promise<void> {\n debug('Freezing page context');\n const context = await this._snapshotContext();\n // Mark the context as frozen\n context._isFrozen = true;\n this.frozenUIContext = context;\n debug('Page context frozen successfully');\n }\n\n /**\n * Unfreezes the page context, allowing AI operations to calculate context dynamically\n */\n async unfreezePageContext(): Promise<void> {\n debug('Unfreezing page context');\n this.frozenUIContext = undefined;\n debug('Page context unfrozen successfully');\n }\n\n /**\n * Process cache configuration and return normalized cache settings\n */\n private processCacheConfig(\n opts: AgentOpt,\n ): { id: string; enabled: boolean; readOnly: boolean } | null {\n // 1. New cache object configuration (highest priority)\n if (opts.cache !== undefined) {\n if (opts.cache === false) {\n return null; // Completely disable cache\n }\n\n if (opts.cache === true) {\n throw new Error(\n 'cache: true requires an explicit cache ID. Please provide:\\n' +\n 'Example: cache: { id: \"my-cache-id\" }',\n );\n }\n\n // cache is object configuration\n if (typeof opts.cache === 'object') {\n const config = opts.cache;\n if (!config.id) {\n throw new Error(\n 'cache configuration requires an explicit id. Please provide:\\n' +\n 'Example: cache: { id: \"my-cache-id\" }',\n );\n }\n const id = config.id;\n const rawStrategy = config.strategy as unknown;\n let strategyValue: string;\n\n if (rawStrategy === undefined) {\n strategyValue = 'read-write';\n } else if (typeof rawStrategy === 'string') {\n strategyValue = rawStrategy;\n } else {\n throw new Error(\n `cache.strategy must be a string when provided, but received type ${typeof rawStrategy}`,\n );\n }\n\n if (!isValidCacheStrategy(strategyValue)) {\n throw new Error(\n `cache.strategy must be one of ${CACHE_STRATEGY_VALUES}, but received \"${strategyValue}\"`,\n );\n }\n\n const isReadOnly = strategyValue === 'read-only';\n\n return {\n id,\n enabled: true,\n readOnly: isReadOnly,\n };\n }\n }\n\n // 2. Backward compatibility: support old cacheId (requires environment variable)\n if (opts.cacheId) {\n const envEnabled =\n globalConfigManager.getEnvConfigInBoolean(MIDSCENE_CACHE);\n if (envEnabled) {\n return {\n id: opts.cacheId,\n enabled: true,\n readOnly: false,\n };\n }\n }\n\n // 3. No cache configuration\n return null;\n }\n\n /**\n * Manually flush cache to file\n * Only meaningful in read-only mode, other modes will throw error\n */\n async flushCache(): Promise<void> {\n if (!this.taskCache) {\n throw new Error('Cache is not configured');\n }\n\n this.taskCache.flushCacheToFile();\n }\n}\n\nexport const createAgent = (\n interfaceInstance: AbstractInterface,\n opts?: AgentOpt,\n) => {\n return new Agent(interfaceInstance, opts);\n};\n"],"names":["debug","getDebug","distanceOfTwoPoints","p1","p2","x1","y1","x2","y2","Math","includedInRect","point","rect","x","y","left","top","width","height","defaultInsightExtractOption","CACHE_STRATEGIES","isValidCacheStrategy","strategy","value","CACHE_STRATEGY_VALUES","Agent","context","undefined","_context_size","pageWidth","assert","screenshotWidth","imageInfoOfBase64","Number","computedScale","action","commonContextParser","computedScreenshotScale","scaleForLog","targetWidth","targetHeight","resizeImgBase64","prompt","console","execution","trimmedExecution","trimContextByViewport","currentDump","stringifyDumpData","reportHTMLContent","Error","generateReport","autoPrintReportMsg","writeLogFile","groupedActionDumpFileExt","printReportMsg","task","param","paramStr","tip","typeStr","executor","doNotThrowError","error","errorTask","type","opt","actionPlan","plans","Boolean","title","taskTitleStr","locateParamStr","modelConfig","output","locatePrompt","detailedLocateParam","buildDetailedLocateParam","locatePromptOrValue","locatePromptOrOpt","optOrUndefined","optWithValue","locatePromptOrKeyName","keyName","locatePromptOrScrollParam","scrollParam","taskPrompt","_this_taskCache","_this_taskCache1","cacheable","isVlmUiTars","matchedCache","_matchedCache_cacheContent","_matchedCache_cacheContent1","yaml","yamlContent","yamlFlowStr","demand","textPrompt","multimodalPrompt","parsePrompt","center","verifyPrompt","retryLimit","success","retryCount","resultPrompt","deepThink","verifyResult","text","locateOpt","expectCenter","verifyLocateOption","verifyCenter","verifyRect","distance","included","pass","locateParam","locatePlan","locatePlanForLocate","element","dprValue","dprEntry","assertion","msg","_executor_latestErrorTask","insightOpt","thought","message","yamlScriptContent","script","parseYamlScript","player","ScriptPlayer","errors","_task_error","_this_interface","base64","now","Date","recorder","executionDump","_this","groupName","groupDescription","executions","newExecutions","Array","tasks","restExecution","newTasks","uiContext","log","restTask","opts","config","id","rawStrategy","strategyValue","isReadOnly","envEnabled","globalConfigManager","MIDSCENE_CACHE","interfaceInstance","Object","ModelConfigManager","globalModelConfigManager","Insight","cacheConfig","TaskCache","TaskExecutor","getReportFileName","createAgent"],"mappings":"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"}
|
package/dist/es/agent/utils.mjs
CHANGED
|
@@ -3,7 +3,6 @@ import { uploadTestInfoToServer } from "../utils.mjs";
|
|
|
3
3
|
import { NodeType } from "@midscene/shared/constants";
|
|
4
4
|
import { MIDSCENE_REPORT_TAG_NAME, globalConfigManager } from "@midscene/shared/env";
|
|
5
5
|
import { generateElementByPosition, getNodeFromCacheList } from "@midscene/shared/extractor";
|
|
6
|
-
import { resizeImgBase64 } from "@midscene/shared/img";
|
|
7
6
|
import { getDebug } from "@midscene/shared/logger";
|
|
8
7
|
import { assert, logMsg, uuid } from "@midscene/shared/utils";
|
|
9
8
|
import dayjs from "dayjs";
|
|
@@ -21,18 +20,10 @@ async function commonContextParser(interfaceInstance, _opt) {
|
|
|
21
20
|
serverUrl: _opt.uploadServerUrl
|
|
22
21
|
});
|
|
23
22
|
debugProfile('UploadTestInfoToServer end');
|
|
24
|
-
|
|
23
|
+
const screenshotBase64 = await interfaceInstance.screenshotBase64();
|
|
25
24
|
assert(screenshotBase64, 'screenshotBase64 is required');
|
|
26
25
|
const size = await interfaceInstance.size();
|
|
27
26
|
debugProfile(`size: ${size.width}x${size.height} dpr: ${size.dpr}`);
|
|
28
|
-
if (size.dpr && 1 !== size.dpr) {
|
|
29
|
-
debugProfile('Resizing screenshot for non-1 dpr');
|
|
30
|
-
screenshotBase64 = await resizeImgBase64(screenshotBase64, {
|
|
31
|
-
width: size.width,
|
|
32
|
-
height: size.height
|
|
33
|
-
});
|
|
34
|
-
debugProfile('ResizeImgBase64 end');
|
|
35
|
-
}
|
|
36
27
|
return {
|
|
37
28
|
tree: {
|
|
38
29
|
node: null,
|
|
@@ -152,7 +143,7 @@ function trimContextByViewport(execution) {
|
|
|
152
143
|
}) : execution.tasks
|
|
153
144
|
};
|
|
154
145
|
}
|
|
155
|
-
const getMidsceneVersion = ()=>"0.30.
|
|
146
|
+
const getMidsceneVersion = ()=>"0.30.2-beta-20250930144216.0";
|
|
156
147
|
const parsePrompt = (prompt)=>{
|
|
157
148
|
if ('string' == typeof prompt) return {
|
|
158
149
|
textPrompt: prompt,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent/utils.mjs","sources":["webpack://@midscene/core/./src/agent/utils.ts"],"sourcesContent":["import { elementByPositionWithElementInfo } from '@/ai-model';\nimport type { AbstractInterface } from '@/device';\nimport type {\n BaseElement,\n ElementCacheFeature,\n ElementTreeNode,\n ExecutionDump,\n ExecutionTask,\n ExecutorContext,\n LocateResultElement,\n PlanningLocateParam,\n TMultimodalPrompt,\n TUserPrompt,\n UIContext,\n} from '@/index';\nimport { uploadTestInfoToServer } from '@/utils';\nimport { NodeType } from '@midscene/shared/constants';\nimport {\n MIDSCENE_REPORT_TAG_NAME,\n globalConfigManager,\n} from '@midscene/shared/env';\nimport {\n generateElementByPosition,\n getNodeFromCacheList,\n} from '@midscene/shared/extractor';\nimport { resizeImgBase64 } from '@midscene/shared/img';\nimport { getDebug } from '@midscene/shared/logger';\nimport { _keyDefinitions } from '@midscene/shared/us-keyboard-layout';\nimport { assert, logMsg, uuid } from '@midscene/shared/utils';\nimport dayjs from 'dayjs';\nimport { debug as cacheDebug } from './task-cache';\nimport type { TaskExecutor } from './tasks';\n\nconst debugProfile = getDebug('web:tool:profile');\n\nexport async function commonContextParser(\n interfaceInstance: AbstractInterface,\n _opt: { uploadServerUrl?: string },\n): Promise<UIContext> {\n assert(interfaceInstance, 'interfaceInstance is required');\n\n debugProfile('Getting interface description');\n const description = interfaceInstance.describe?.() || '';\n debugProfile('Interface description end');\n\n debugProfile('Uploading test info to server');\n uploadTestInfoToServer({\n testUrl: description,\n serverUrl: _opt.uploadServerUrl,\n });\n debugProfile('UploadTestInfoToServer end');\n\n let screenshotBase64 = await interfaceInstance.screenshotBase64();\n assert(screenshotBase64!, 'screenshotBase64 is required');\n\n const size = await interfaceInstance.size();\n debugProfile(`size: ${size.width}x${size.height} dpr: ${size.dpr}`);\n\n if (size.dpr && size.dpr !== 1) {\n debugProfile('Resizing screenshot for non-1 dpr');\n screenshotBase64 = await resizeImgBase64(screenshotBase64, {\n width: size.width,\n height: size.height,\n });\n debugProfile('ResizeImgBase64 end');\n }\n\n return {\n tree: {\n node: null,\n children: [],\n },\n size,\n screenshotBase64: screenshotBase64!,\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 logMsg(`Midscene - report file updated: ${filepath}`);\n}\n\n/**\n * Get the current execution file name\n * @returns The name of the current execution file\n */\nexport function getCurrentExecutionFile(trace?: string): string | false {\n const error = new Error();\n const stackTrace = trace || error.stack;\n const pkgDir = process.cwd() || '';\n if (stackTrace) {\n const stackLines = stackTrace.split('\\n');\n for (const line of stackLines) {\n if (\n line.includes('.spec.') ||\n line.includes('.test.') ||\n line.includes('.ts') ||\n line.includes('.js')\n ) {\n const match = line.match(/(?:at\\s+)?(.*?\\.(?:spec|test)\\.[jt]s)/);\n if (match?.[1]) {\n const targetFileName = match[1]\n .replace(pkgDir, '')\n .trim()\n .replace('at ', '');\n return targetFileName;\n }\n }\n }\n }\n return false;\n}\n\nconst testFileIndex = new Map<string, number>();\n\nexport function generateCacheId(fileName?: string): string {\n let taskFile = fileName || getCurrentExecutionFile();\n if (!taskFile) {\n taskFile = uuid();\n console.warn(\n 'Midscene - using random UUID for cache id. Cache may be invalid.',\n );\n }\n\n if (testFileIndex.has(taskFile)) {\n const currentIndex = testFileIndex.get(taskFile);\n if (currentIndex !== undefined) {\n testFileIndex.set(taskFile, currentIndex + 1);\n }\n } else {\n testFileIndex.set(taskFile, 1);\n }\n return `${taskFile}-${testFileIndex.get(taskFile)}`;\n}\n\nexport function matchElementFromPlan(\n planLocateParam: PlanningLocateParam,\n tree: ElementTreeNode<BaseElement>,\n) {\n if (!planLocateParam) {\n return undefined;\n }\n if (planLocateParam.id) {\n return getNodeFromCacheList(planLocateParam.id);\n }\n\n if (planLocateParam.bbox) {\n const centerPosition = {\n x: Math.floor((planLocateParam.bbox[0] + planLocateParam.bbox[2]) / 2),\n y: Math.floor((planLocateParam.bbox[1] + planLocateParam.bbox[3]) / 2),\n };\n let element = elementByPositionWithElementInfo(tree, centerPosition);\n\n if (!element) {\n element = generateElementByPosition(centerPosition) as BaseElement;\n }\n\n return element;\n }\n\n return undefined;\n}\n\nexport async function matchElementFromCache(\n taskExecutor: TaskExecutor,\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 (!taskExecutor.taskCache?.isCacheResultUsed) {\n return undefined;\n }\n\n if (!taskExecutor.interface.rectMatchesCacheFeature) {\n cacheDebug(\n 'interface does not implement rectMatchesCacheFeature, skip cache',\n );\n return undefined;\n }\n\n try {\n const rect =\n await taskExecutor.interface.rectMatchesCacheFeature(cacheEntry);\n const element: LocateResultElement = {\n id: uuid(),\n center: [\n Math.round(rect.left + rect.width / 2),\n Math.round(rect.top + rect.height / 2),\n ],\n rect,\n xpaths: [],\n attributes: {\n nodeType: NodeType.POSITION,\n },\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\nexport function trimContextByViewport(execution: ExecutionDump) {\n function filterVisibleTree(\n node: ElementTreeNode<BaseElement>,\n ): ElementTreeNode<BaseElement> | null {\n if (!node) return null;\n\n // recursively process all children\n const filteredChildren = Array.isArray(node.children)\n ? (node.children\n .map(filterVisibleTree)\n .filter((child) => child !== null) as ElementTreeNode<BaseElement>[])\n : [];\n\n // if the current node is visible, keep it and the filtered children\n if (node.node && node.node.isVisible === true) {\n return {\n ...node,\n children: filteredChildren,\n };\n }\n\n // if the current node is invisible, but has visible children, create an empty node to include these children\n if (filteredChildren.length > 0) {\n return {\n node: null,\n children: filteredChildren,\n };\n }\n\n // if the current node is invisible and has no visible children, return null\n return null;\n }\n\n return {\n ...execution,\n tasks: Array.isArray(execution.tasks)\n ? execution.tasks.map((task: ExecutionTask) => {\n const newTask = { ...task };\n if (task.uiContext?.tree) {\n newTask.uiContext = {\n ...task.uiContext,\n tree: filterVisibleTree(task.uiContext.tree) || {\n node: null,\n children: [],\n },\n };\n }\n return newTask;\n })\n : execution.tasks,\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"],"names":["debugProfile","getDebug","commonContextParser","interfaceInstance","_opt","assert","description","uploadTestInfoToServer","screenshotBase64","size","resizeImgBase64","getReportFileName","tag","reportTagName","globalConfigManager","MIDSCENE_REPORT_TAG_NAME","dateTimeInFileName","dayjs","uniqueId","uuid","printReportMsg","filepath","logMsg","getCurrentExecutionFile","trace","error","Error","stackTrace","pkgDir","process","stackLines","line","match","targetFileName","testFileIndex","Map","generateCacheId","fileName","taskFile","console","currentIndex","undefined","matchElementFromPlan","planLocateParam","tree","getNodeFromCacheList","centerPosition","Math","element","elementByPositionWithElementInfo","generateElementByPosition","matchElementFromCache","taskExecutor","cacheEntry","cachePrompt","cacheable","_taskExecutor_taskCache","cacheDebug","rect","NodeType","trimContextByViewport","execution","filterVisibleTree","node","filteredChildren","Array","child","task","_task_uiContext","newTask","getMidsceneVersion","__VERSION__","parsePrompt","prompt"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"agent/utils.mjs","sources":["webpack://@midscene/core/./src/agent/utils.ts"],"sourcesContent":["import { elementByPositionWithElementInfo } from '@/ai-model';\nimport type { AbstractInterface } from '@/device';\nimport type {\n BaseElement,\n ElementCacheFeature,\n ElementTreeNode,\n ExecutionDump,\n ExecutionTask,\n ExecutorContext,\n LocateResultElement,\n PlanningLocateParam,\n TMultimodalPrompt,\n TUserPrompt,\n UIContext,\n} from '@/index';\nimport { uploadTestInfoToServer } from '@/utils';\nimport { NodeType } from '@midscene/shared/constants';\nimport {\n MIDSCENE_REPORT_TAG_NAME,\n globalConfigManager,\n} from '@midscene/shared/env';\nimport {\n generateElementByPosition,\n getNodeFromCacheList,\n} from '@midscene/shared/extractor';\nimport { resizeImgBase64 } from '@midscene/shared/img';\nimport { getDebug } from '@midscene/shared/logger';\nimport { _keyDefinitions } from '@midscene/shared/us-keyboard-layout';\nimport { assert, logMsg, uuid } from '@midscene/shared/utils';\nimport dayjs from 'dayjs';\nimport { debug as cacheDebug } from './task-cache';\nimport type { TaskExecutor } from './tasks';\n\nconst debugProfile = getDebug('web:tool:profile');\n\nexport async function commonContextParser(\n interfaceInstance: AbstractInterface,\n _opt: { uploadServerUrl?: string },\n): Promise<UIContext> {\n assert(interfaceInstance, 'interfaceInstance is required');\n\n debugProfile('Getting interface description');\n const description = interfaceInstance.describe?.() || '';\n debugProfile('Interface description end');\n\n debugProfile('Uploading test info to server');\n uploadTestInfoToServer({\n testUrl: description,\n serverUrl: _opt.uploadServerUrl,\n });\n debugProfile('UploadTestInfoToServer end');\n\n const screenshotBase64 = await interfaceInstance.screenshotBase64();\n assert(screenshotBase64!, 'screenshotBase64 is required');\n\n const size = await interfaceInstance.size();\n debugProfile(`size: ${size.width}x${size.height} dpr: ${size.dpr}`);\n\n return {\n tree: {\n node: null,\n children: [],\n },\n size,\n screenshotBase64: screenshotBase64!,\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 logMsg(`Midscene - report file updated: ${filepath}`);\n}\n\n/**\n * Get the current execution file name\n * @returns The name of the current execution file\n */\nexport function getCurrentExecutionFile(trace?: string): string | false {\n const error = new Error();\n const stackTrace = trace || error.stack;\n const pkgDir = process.cwd() || '';\n if (stackTrace) {\n const stackLines = stackTrace.split('\\n');\n for (const line of stackLines) {\n if (\n line.includes('.spec.') ||\n line.includes('.test.') ||\n line.includes('.ts') ||\n line.includes('.js')\n ) {\n const match = line.match(/(?:at\\s+)?(.*?\\.(?:spec|test)\\.[jt]s)/);\n if (match?.[1]) {\n const targetFileName = match[1]\n .replace(pkgDir, '')\n .trim()\n .replace('at ', '');\n return targetFileName;\n }\n }\n }\n }\n return false;\n}\n\nconst testFileIndex = new Map<string, number>();\n\nexport function generateCacheId(fileName?: string): string {\n let taskFile = fileName || getCurrentExecutionFile();\n if (!taskFile) {\n taskFile = uuid();\n console.warn(\n 'Midscene - using random UUID for cache id. Cache may be invalid.',\n );\n }\n\n if (testFileIndex.has(taskFile)) {\n const currentIndex = testFileIndex.get(taskFile);\n if (currentIndex !== undefined) {\n testFileIndex.set(taskFile, currentIndex + 1);\n }\n } else {\n testFileIndex.set(taskFile, 1);\n }\n return `${taskFile}-${testFileIndex.get(taskFile)}`;\n}\n\nexport function matchElementFromPlan(\n planLocateParam: PlanningLocateParam,\n tree: ElementTreeNode<BaseElement>,\n) {\n if (!planLocateParam) {\n return undefined;\n }\n if (planLocateParam.id) {\n return getNodeFromCacheList(planLocateParam.id);\n }\n\n if (planLocateParam.bbox) {\n const centerPosition = {\n x: Math.floor((planLocateParam.bbox[0] + planLocateParam.bbox[2]) / 2),\n y: Math.floor((planLocateParam.bbox[1] + planLocateParam.bbox[3]) / 2),\n };\n let element = elementByPositionWithElementInfo(tree, centerPosition);\n\n if (!element) {\n element = generateElementByPosition(centerPosition) as BaseElement;\n }\n\n return element;\n }\n\n return undefined;\n}\n\nexport async function matchElementFromCache(\n taskExecutor: TaskExecutor,\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 (!taskExecutor.taskCache?.isCacheResultUsed) {\n return undefined;\n }\n\n if (!taskExecutor.interface.rectMatchesCacheFeature) {\n cacheDebug(\n 'interface does not implement rectMatchesCacheFeature, skip cache',\n );\n return undefined;\n }\n\n try {\n const rect =\n await taskExecutor.interface.rectMatchesCacheFeature(cacheEntry);\n const element: LocateResultElement = {\n id: uuid(),\n center: [\n Math.round(rect.left + rect.width / 2),\n Math.round(rect.top + rect.height / 2),\n ],\n rect,\n xpaths: [],\n attributes: {\n nodeType: NodeType.POSITION,\n },\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\nexport function trimContextByViewport(execution: ExecutionDump) {\n function filterVisibleTree(\n node: ElementTreeNode<BaseElement>,\n ): ElementTreeNode<BaseElement> | null {\n if (!node) return null;\n\n // recursively process all children\n const filteredChildren = Array.isArray(node.children)\n ? (node.children\n .map(filterVisibleTree)\n .filter((child) => child !== null) as ElementTreeNode<BaseElement>[])\n : [];\n\n // if the current node is visible, keep it and the filtered children\n if (node.node && node.node.isVisible === true) {\n return {\n ...node,\n children: filteredChildren,\n };\n }\n\n // if the current node is invisible, but has visible children, create an empty node to include these children\n if (filteredChildren.length > 0) {\n return {\n node: null,\n children: filteredChildren,\n };\n }\n\n // if the current node is invisible and has no visible children, return null\n return null;\n }\n\n return {\n ...execution,\n tasks: Array.isArray(execution.tasks)\n ? execution.tasks.map((task: ExecutionTask) => {\n const newTask = { ...task };\n if (task.uiContext?.tree) {\n newTask.uiContext = {\n ...task.uiContext,\n tree: filterVisibleTree(task.uiContext.tree) || {\n node: null,\n children: [],\n },\n };\n }\n return newTask;\n })\n : execution.tasks,\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"],"names":["debugProfile","getDebug","commonContextParser","interfaceInstance","_opt","assert","description","uploadTestInfoToServer","screenshotBase64","size","getReportFileName","tag","reportTagName","globalConfigManager","MIDSCENE_REPORT_TAG_NAME","dateTimeInFileName","dayjs","uniqueId","uuid","printReportMsg","filepath","logMsg","getCurrentExecutionFile","trace","error","Error","stackTrace","pkgDir","process","stackLines","line","match","targetFileName","testFileIndex","Map","generateCacheId","fileName","taskFile","console","currentIndex","undefined","matchElementFromPlan","planLocateParam","tree","getNodeFromCacheList","centerPosition","Math","element","elementByPositionWithElementInfo","generateElementByPosition","matchElementFromCache","taskExecutor","cacheEntry","cachePrompt","cacheable","_taskExecutor_taskCache","cacheDebug","rect","NodeType","trimContextByViewport","execution","filterVisibleTree","node","filteredChildren","Array","child","task","_task_uiContext","newTask","getMidsceneVersion","__VERSION__","parsePrompt","prompt"],"mappings":"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"}
|
package/dist/es/types.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.mjs","sources":["webpack://@midscene/core/./src/types.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { NodeType } from '@midscene/shared/constants';\nimport type { TModelConfigFn } from '@midscene/shared/env';\nimport type {\n BaseElement,\n ElementTreeNode,\n Rect,\n Size,\n} from '@midscene/shared/types';\nimport type { z } from 'zod';\nimport type { TUserPrompt } from './ai-model/common';\nimport type { DetailedLocateParam, MidsceneYamlFlowItem } from './yaml';\n\nexport type {\n ElementTreeNode,\n BaseElement,\n Rect,\n Size,\n Point,\n} from '@midscene/shared/types';\nexport * from './yaml';\n\nexport type AIUsageInfo = Record<string, any> & {\n prompt_tokens: number | undefined;\n completion_tokens: number | undefined;\n total_tokens: number | undefined;\n time_cost: number | undefined;\n model_name: string | undefined;\n model_description: string | undefined;\n intent: string | undefined;\n};\n\n/**\n * openai\n *\n */\nexport enum AIResponseFormat {\n JSON = 'json_object',\n TEXT = 'text',\n}\n\nexport type AISingleElementResponseById = {\n id: string;\n reason?: string;\n text?: string;\n xpaths?: string[];\n};\n\nexport type AISingleElementResponseByPosition = {\n position?: {\n x: number;\n y: number;\n };\n bbox?: [number, number, number, number];\n reason: string;\n text: string;\n};\n\nexport type AISingleElementResponse = AISingleElementResponseById;\nexport interface AIElementLocatorResponse {\n elements: {\n id: string;\n reason?: string;\n text?: string;\n xpaths?: string[];\n }[];\n bbox?: [number, number, number, number];\n isOrderSensitive?: boolean;\n errors?: string[];\n}\n\nexport interface AIElementCoordinatesResponse {\n bbox: [number, number, number, number];\n isOrderSensitive?: boolean;\n errors?: string[];\n}\n\nexport type AIElementResponse =\n | AIElementLocatorResponse\n | AIElementCoordinatesResponse;\n\nexport interface AIDataExtractionResponse<DataDemand> {\n data: DataDemand;\n errors?: string[];\n thought?: string;\n}\n\nexport interface AISectionLocatorResponse {\n bbox: [number, number, number, number];\n references_bbox?: [number, number, number, number][];\n error?: string;\n}\n\nexport interface AIAssertionResponse {\n pass: boolean;\n thought: string;\n}\n\nexport interface AIDescribeElementResponse {\n description: string;\n error?: string;\n}\n\nexport interface LocatorValidatorOption {\n centerDistanceThreshold?: number;\n}\n\nexport interface LocateValidatorResult {\n pass: boolean;\n rect: Rect;\n center: [number, number];\n centerDistance?: number;\n}\n\nexport interface AgentDescribeElementAtPointResult {\n prompt: string;\n deepThink: boolean;\n verifyResult?: LocateValidatorResult;\n}\n\n/**\n * context\n */\n\nexport abstract class UIContext<ElementType extends BaseElement = BaseElement> {\n abstract screenshotBase64: string;\n\n abstract tree: ElementTreeNode<ElementType>;\n\n abstract size: Size;\n\n abstract _isFrozen?: boolean;\n}\n\nexport type EnsureObject<T> = { [K in keyof T]: any };\n\nexport type InsightAction = 'locate' | 'extract' | 'assert' | 'describe';\n\nexport type InsightExtractParam = string | Record<string, string>;\n\nexport type ElementCacheFeature = Record<string, unknown>;\n\nexport type LocateResultElement = {\n center: [number, number];\n rect: Rect;\n id: string;\n indexId?: number;\n xpaths: string[];\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n isOrderSensitive?: boolean;\n};\n\nexport interface LocateResult {\n element: LocateResultElement | null;\n rect?: Rect;\n}\n\nexport interface InsightTaskInfo {\n durationMs: number;\n formatResponse?: string;\n rawResponse?: string;\n usage?: AIUsageInfo;\n searchArea?: Rect;\n searchAreaRawResponse?: string;\n searchAreaUsage?: AIUsageInfo;\n}\n\nexport interface DumpMeta {\n sdkVersion: string;\n logTime: number;\n}\n\nexport interface ReportDumpWithAttributes {\n dumpString: string;\n attributes?: Record<string, any>;\n}\n\nexport interface InsightDump extends DumpMeta {\n type: 'locate' | 'extract' | 'assert';\n logId: string;\n userQuery: {\n element?: TUserPrompt;\n dataDemand?: InsightExtractParam;\n assertion?: TUserPrompt;\n };\n matchedElement: BaseElement[];\n matchedRect?: Rect;\n deepThink?: boolean;\n data: any;\n assertionPass?: boolean;\n assertionThought?: string;\n taskInfo: InsightTaskInfo;\n error?: string;\n output?: any;\n}\n\nexport type PartialInsightDumpFromSDK = Omit<\n InsightDump,\n 'sdkVersion' | 'logTime' | 'logId' | 'model_name'\n>;\n\nexport type DumpSubscriber = (dump: InsightDump) => Promise<void> | void;\n\n// intermediate variables to optimize the return value by AI\nexport interface LiteUISection {\n name: string;\n description: string;\n sectionCharacteristics: string;\n textIds: string[];\n}\n\nexport type ElementById = (id: string) => BaseElement | null;\n\nexport type InsightAssertionResponse = AIAssertionResponse & {\n usage?: AIUsageInfo;\n};\n\n/**\n * agent\n */\n\nexport type OnTaskStartTip = (tip: string) => Promise<void> | void;\n\nexport interface AgentWaitForOpt {\n checkIntervalMs?: number;\n timeoutMs?: number;\n}\n\nexport interface AgentAssertOpt {\n keepRawResponse?: boolean;\n}\n\n/**\n * planning\n *\n */\n\nexport interface PlanningLocateParam extends DetailedLocateParam {\n id?: string;\n bbox?: [number, number, number, number];\n}\n\nexport interface PlanningAction<ParamType = any> {\n thought?: string;\n type: string;\n param: ParamType;\n locate?: PlanningLocateParam | null;\n}\n\nexport interface PlanningAIResponse {\n action?: PlanningAction; // this is the qwen mode\n actions?: PlanningAction[];\n more_actions_needed_by_instruction: boolean;\n log: string;\n sleep?: number;\n error?: string;\n usage?: AIUsageInfo;\n rawResponse?: string;\n yamlFlow?: MidsceneYamlFlowItem[];\n yamlString?: string;\n}\n\nexport type PlanningActionParamTap = null;\nexport type PlanningActionParamHover = null;\nexport type PlanningActionParamRightClick = null;\n\nexport interface PlanningActionParamInputOrKeyPress {\n value: string;\n autoDismissKeyboard?: boolean;\n}\n\nexport interface PlanningActionParamSleep {\n timeMs: number;\n}\n\nexport interface PlanningActionParamError {\n thought: string;\n}\n\nexport type PlanningActionParamWaitFor = AgentWaitForOpt & {};\n\nexport interface AndroidLongPressParam {\n duration?: number;\n}\n\nexport interface AndroidPullParam {\n direction: 'up' | 'down';\n distance?: number;\n duration?: number;\n}\n/**\n * misc\n */\n\nexport interface Color {\n name: string;\n hex: string;\n}\n\nexport interface BaseAgentParserOpt {\n selector?: string;\n}\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\nexport interface PuppeteerParserOpt extends BaseAgentParserOpt {}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\nexport interface PlaywrightParserOpt extends BaseAgentParserOpt {}\n\n/*\naction\n*/\nexport interface ExecutionTaskProgressOptions {\n onTaskStart?: (task: ExecutionTask) => Promise<void> | void;\n}\n\nexport interface ExecutionRecorderItem {\n type: 'screenshot';\n ts: number;\n screenshot?: string;\n timing?: string;\n}\n\nexport type ExecutionTaskType =\n | 'Planning'\n | 'Insight'\n | 'Action'\n | 'Assertion'\n | 'Log';\n\nexport interface ExecutorContext {\n task: ExecutionTask;\n element?: LocateResultElement | null;\n}\n\nexport interface ExecutionTaskApply<\n Type extends ExecutionTaskType = any,\n TaskParam = any,\n TaskOutput = any,\n TaskLog = any,\n> {\n type: Type;\n subType?: string;\n param?: TaskParam;\n thought?: string;\n locate?: PlanningLocateParam | null;\n uiContext?: UIContext;\n executor: (\n param: TaskParam,\n context: ExecutorContext,\n ) => // biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\n | Promise<ExecutionTaskReturn<TaskOutput, TaskLog> | undefined | void>\n | undefined\n | void;\n}\n\nexport interface ExecutionTaskHitBy {\n from: string;\n context: Record<string, any>;\n}\n\nexport interface ExecutionTaskReturn<TaskOutput = unknown, TaskLog = unknown> {\n output?: TaskOutput;\n log?: TaskLog;\n recorder?: ExecutionRecorderItem[];\n hitBy?: ExecutionTaskHitBy;\n}\n\nexport type ExecutionTask<\n E extends ExecutionTaskApply<any, any, any> = ExecutionTaskApply<\n any,\n any,\n any\n >,\n> = E &\n ExecutionTaskReturn<\n E extends ExecutionTaskApply<any, any, infer TaskOutput, any>\n ? TaskOutput\n : unknown,\n E extends ExecutionTaskApply<any, any, any, infer TaskLog>\n ? TaskLog\n : unknown\n > & {\n status: 'pending' | 'running' | 'finished' | 'failed' | 'cancelled';\n error?: Error;\n errorMessage?: string;\n errorStack?: string;\n timing?: {\n start: number;\n end?: number;\n cost?: number;\n };\n usage?: AIUsageInfo;\n searchAreaUsage?: AIUsageInfo;\n };\n\nexport interface ExecutionDump extends DumpMeta {\n name: string;\n description?: string;\n tasks: ExecutionTask[];\n}\n\n/*\ntask - insight-locate\n*/\nexport type ExecutionTaskInsightLocateParam = PlanningLocateParam;\n\nexport interface ExecutionTaskInsightLocateOutput {\n element: LocateResultElement | null;\n}\n\nexport interface ExecutionTaskInsightDumpLog {\n dump?: InsightDump;\n}\n\nexport type ExecutionTaskInsightLocateApply = ExecutionTaskApply<\n 'Insight',\n ExecutionTaskInsightLocateParam,\n ExecutionTaskInsightLocateOutput,\n ExecutionTaskInsightDumpLog\n>;\n\nexport type ExecutionTaskInsightLocate =\n ExecutionTask<ExecutionTaskInsightLocateApply>;\n\n/*\ntask - insight-query\n*/\nexport interface ExecutionTaskInsightQueryParam {\n dataDemand: InsightExtractParam;\n}\n\nexport interface ExecutionTaskInsightQueryOutput {\n data: any;\n}\n\nexport type ExecutionTaskInsightQueryApply = ExecutionTaskApply<\n 'Insight',\n ExecutionTaskInsightQueryParam,\n any,\n ExecutionTaskInsightDumpLog\n>;\n\nexport type ExecutionTaskInsightQuery =\n ExecutionTask<ExecutionTaskInsightQueryApply>;\n\n/*\ntask - assertion\n*/\nexport interface ExecutionTaskInsightAssertionParam {\n assertion: string;\n}\n\nexport type ExecutionTaskInsightAssertionApply = ExecutionTaskApply<\n 'Insight',\n ExecutionTaskInsightAssertionParam,\n InsightAssertionResponse,\n ExecutionTaskInsightDumpLog\n>;\n\nexport type ExecutionTaskInsightAssertion =\n ExecutionTask<ExecutionTaskInsightAssertionApply>;\n\n/*\ntask - action (i.e. interact) \n*/\nexport type ExecutionTaskActionApply<ActionParam = any> = ExecutionTaskApply<\n 'Action',\n ActionParam,\n void,\n void\n>;\n\nexport type ExecutionTaskAction = ExecutionTask<ExecutionTaskActionApply>;\n\n/*\ntask - Log\n*/\n\nexport type ExecutionTaskLogApply<\n LogParam = {\n content: string;\n },\n> = ExecutionTaskApply<'Log', LogParam, void, void>;\n\nexport type ExecutionTaskLog = ExecutionTask<ExecutionTaskLogApply>;\n\n/*\ntask - planning\n*/\n\nexport type ExecutionTaskPlanningApply = ExecutionTaskApply<\n 'Planning',\n {\n userInstruction: string;\n },\n PlanningAIResponse\n>;\n\nexport type ExecutionTaskPlanning = ExecutionTask<ExecutionTaskPlanningApply>;\n\n/*\nGrouped dump\n*/\nexport interface GroupedActionDump {\n groupName: string;\n groupDescription?: string;\n modelBriefs: string[];\n executions: ExecutionDump[];\n}\n\nexport type InterfaceType =\n | 'puppeteer'\n | 'playwright'\n | 'static'\n | 'chrome-extension-proxy'\n | 'android'\n | string;\n\nexport interface StreamingCodeGenerationOptions {\n /** Whether to enable streaming output */\n stream?: boolean;\n /** Callback function to handle streaming chunks */\n onChunk?: StreamingCallback;\n /** Callback function to handle streaming completion */\n onComplete?: (finalCode: string) => void;\n /** Callback function to handle streaming errors */\n onError?: (error: Error) => void;\n}\n\nexport type StreamingCallback = (chunk: CodeGenerationChunk) => void;\n\nexport interface CodeGenerationChunk {\n /** The incremental content chunk */\n content: string;\n /** The reasoning content */\n reasoning_content: string;\n /** The accumulated content so far */\n accumulated: string;\n /** Whether this is the final chunk */\n isComplete: boolean;\n /** Token usage information if available */\n usage?: AIUsageInfo;\n}\n\nexport interface StreamingAIResponse {\n /** The final accumulated content */\n content: string;\n /** Token usage information */\n usage?: AIUsageInfo;\n /** Whether the response was streamed */\n isStreamed: boolean;\n}\n\nexport interface DeviceAction<T = any> {\n name: string;\n description?: string;\n interfaceAlias?: string;\n paramSchema?: z.ZodType<T>;\n call: (param: T, context: ExecutorContext) => Promise<void> | void;\n}\n\n/**\n * Web-specific types\n */\nexport interface WebElementInfo extends BaseElement {\n id: string;\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n}\n\nexport type WebUIContext = UIContext<WebElementInfo>;\n\n/**\n * Agent\n */\n\nexport type CacheConfig = { strategy?: 'read-only' | 'read-write'; id: string };\n\nexport type Cache =\n | false // No read, no write\n | true // Will throw error at runtime - deprecated\n | CacheConfig; // Object configuration (requires explicit id)\n\nexport interface AgentOpt {\n testId?: string;\n // @deprecated\n cacheId?: string; // Keep backward compatibility, but marked as deprecated\n groupName?: string;\n groupDescription?: string;\n /* if auto generate report, default true */\n generateReport?: boolean;\n /* if auto print report msg, default true */\n autoPrintReportMsg?: boolean;\n onTaskStartTip?: OnTaskStartTip;\n aiActionContext?: string;\n /* custom report file name */\n reportFileName?: string;\n modelConfig?: TModelConfigFn;\n cache?: Cache;\n replanningCycleLimit?: number;\n}\n"],"names":["AIResponseFormat","UIContext"],"mappings":";AAqCO,IAAKA,yBAAgBA,WAAAA,GAAAA,SAAhBA,gBAAgB;;;WAAhBA;;AAwFL,MAAeC;AAQtB"}
|
|
1
|
+
{"version":3,"file":"types.mjs","sources":["webpack://@midscene/core/./src/types.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { NodeType } from '@midscene/shared/constants';\nimport type { TModelConfigFn } from '@midscene/shared/env';\nimport type {\n BaseElement,\n ElementTreeNode,\n Rect,\n Size,\n} from '@midscene/shared/types';\nimport type { z } from 'zod';\nimport type { TUserPrompt } from './ai-model/common';\nimport type { DetailedLocateParam, MidsceneYamlFlowItem } from './yaml';\n\nexport type {\n ElementTreeNode,\n BaseElement,\n Rect,\n Size,\n Point,\n} from '@midscene/shared/types';\nexport * from './yaml';\n\nexport type AIUsageInfo = Record<string, any> & {\n prompt_tokens: number | undefined;\n completion_tokens: number | undefined;\n total_tokens: number | undefined;\n time_cost: number | undefined;\n model_name: string | undefined;\n model_description: string | undefined;\n intent: string | undefined;\n};\n\n/**\n * openai\n *\n */\nexport enum AIResponseFormat {\n JSON = 'json_object',\n TEXT = 'text',\n}\n\nexport type AISingleElementResponseById = {\n id: string;\n reason?: string;\n text?: string;\n xpaths?: string[];\n};\n\nexport type AISingleElementResponseByPosition = {\n position?: {\n x: number;\n y: number;\n };\n bbox?: [number, number, number, number];\n reason: string;\n text: string;\n};\n\nexport type AISingleElementResponse = AISingleElementResponseById;\nexport interface AIElementLocatorResponse {\n elements: {\n id: string;\n reason?: string;\n text?: string;\n xpaths?: string[];\n }[];\n bbox?: [number, number, number, number];\n isOrderSensitive?: boolean;\n errors?: string[];\n}\n\nexport interface AIElementCoordinatesResponse {\n bbox: [number, number, number, number];\n isOrderSensitive?: boolean;\n errors?: string[];\n}\n\nexport type AIElementResponse =\n | AIElementLocatorResponse\n | AIElementCoordinatesResponse;\n\nexport interface AIDataExtractionResponse<DataDemand> {\n data: DataDemand;\n errors?: string[];\n thought?: string;\n}\n\nexport interface AISectionLocatorResponse {\n bbox: [number, number, number, number];\n references_bbox?: [number, number, number, number][];\n error?: string;\n}\n\nexport interface AIAssertionResponse {\n pass: boolean;\n thought: string;\n}\n\nexport interface AIDescribeElementResponse {\n description: string;\n error?: string;\n}\n\nexport interface LocatorValidatorOption {\n centerDistanceThreshold?: number;\n}\n\nexport interface LocateValidatorResult {\n pass: boolean;\n rect: Rect;\n center: [number, number];\n centerDistance?: number;\n}\n\nexport interface AgentDescribeElementAtPointResult {\n prompt: string;\n deepThink: boolean;\n verifyResult?: LocateValidatorResult;\n}\n\n/**\n * context\n */\n\nexport abstract class UIContext<ElementType extends BaseElement = BaseElement> {\n abstract screenshotBase64: string;\n\n abstract tree: ElementTreeNode<ElementType>;\n\n abstract size: Size;\n\n abstract _isFrozen?: boolean;\n}\n\nexport type EnsureObject<T> = { [K in keyof T]: any };\n\nexport type InsightAction = 'locate' | 'extract' | 'assert' | 'describe';\n\nexport type InsightExtractParam = string | Record<string, string>;\n\nexport type ElementCacheFeature = Record<string, unknown>;\n\nexport type LocateResultElement = {\n center: [number, number];\n rect: Rect;\n id: string;\n indexId?: number;\n xpaths: string[];\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n isOrderSensitive?: boolean;\n};\n\nexport interface LocateResult {\n element: LocateResultElement | null;\n rect?: Rect;\n}\n\nexport interface InsightTaskInfo {\n durationMs: number;\n formatResponse?: string;\n rawResponse?: string;\n usage?: AIUsageInfo;\n searchArea?: Rect;\n searchAreaRawResponse?: string;\n searchAreaUsage?: AIUsageInfo;\n}\n\nexport interface DumpMeta {\n sdkVersion: string;\n logTime: number;\n}\n\nexport interface ReportDumpWithAttributes {\n dumpString: string;\n attributes?: Record<string, any>;\n}\n\nexport interface InsightDump extends DumpMeta {\n type: 'locate' | 'extract' | 'assert';\n logId: string;\n userQuery: {\n element?: TUserPrompt;\n dataDemand?: InsightExtractParam;\n assertion?: TUserPrompt;\n };\n matchedElement: BaseElement[];\n matchedRect?: Rect;\n deepThink?: boolean;\n data: any;\n assertionPass?: boolean;\n assertionThought?: string;\n taskInfo: InsightTaskInfo;\n error?: string;\n output?: any;\n}\n\nexport type PartialInsightDumpFromSDK = Omit<\n InsightDump,\n 'sdkVersion' | 'logTime' | 'logId' | 'model_name'\n>;\n\nexport type DumpSubscriber = (dump: InsightDump) => Promise<void> | void;\n\n// intermediate variables to optimize the return value by AI\nexport interface LiteUISection {\n name: string;\n description: string;\n sectionCharacteristics: string;\n textIds: string[];\n}\n\nexport type ElementById = (id: string) => BaseElement | null;\n\nexport type InsightAssertionResponse = AIAssertionResponse & {\n usage?: AIUsageInfo;\n};\n\n/**\n * agent\n */\n\nexport type OnTaskStartTip = (tip: string) => Promise<void> | void;\n\nexport interface AgentWaitForOpt {\n checkIntervalMs?: number;\n timeoutMs?: number;\n}\n\nexport interface AgentAssertOpt {\n keepRawResponse?: boolean;\n}\n\n/**\n * planning\n *\n */\n\nexport interface PlanningLocateParam extends DetailedLocateParam {\n id?: string;\n bbox?: [number, number, number, number];\n}\n\nexport interface PlanningAction<ParamType = any> {\n thought?: string;\n type: string;\n param: ParamType;\n locate?: PlanningLocateParam | null;\n}\n\nexport interface PlanningAIResponse {\n action?: PlanningAction; // this is the qwen mode\n actions?: PlanningAction[];\n more_actions_needed_by_instruction: boolean;\n log: string;\n sleep?: number;\n error?: string;\n usage?: AIUsageInfo;\n rawResponse?: string;\n yamlFlow?: MidsceneYamlFlowItem[];\n yamlString?: string;\n}\n\nexport type PlanningActionParamTap = null;\nexport type PlanningActionParamHover = null;\nexport type PlanningActionParamRightClick = null;\n\nexport interface PlanningActionParamInputOrKeyPress {\n value: string;\n autoDismissKeyboard?: boolean;\n}\n\nexport interface PlanningActionParamSleep {\n timeMs: number;\n}\n\nexport interface PlanningActionParamError {\n thought: string;\n}\n\nexport type PlanningActionParamWaitFor = AgentWaitForOpt & {};\n\nexport interface AndroidLongPressParam {\n duration?: number;\n}\n\nexport interface AndroidPullParam {\n direction: 'up' | 'down';\n distance?: number;\n duration?: number;\n}\n/**\n * misc\n */\n\nexport interface Color {\n name: string;\n hex: string;\n}\n\nexport interface BaseAgentParserOpt {\n selector?: string;\n}\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\nexport interface PuppeteerParserOpt extends BaseAgentParserOpt {}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\nexport interface PlaywrightParserOpt extends BaseAgentParserOpt {}\n\n/*\naction\n*/\nexport interface ExecutionTaskProgressOptions {\n onTaskStart?: (task: ExecutionTask) => Promise<void> | void;\n}\n\nexport interface ExecutionRecorderItem {\n type: 'screenshot';\n ts: number;\n screenshot?: string;\n timing?: string;\n}\n\nexport type ExecutionTaskType =\n | 'Planning'\n | 'Insight'\n | 'Action'\n | 'Assertion'\n | 'Log';\n\nexport interface ExecutorContext {\n task: ExecutionTask;\n element?: LocateResultElement | null;\n}\n\nexport interface ExecutionTaskApply<\n Type extends ExecutionTaskType = any,\n TaskParam = any,\n TaskOutput = any,\n TaskLog = any,\n> {\n type: Type;\n subType?: string;\n param?: TaskParam;\n thought?: string;\n locate?: PlanningLocateParam | null;\n uiContext?: UIContext;\n executor: (\n param: TaskParam,\n context: ExecutorContext,\n ) => // biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\n | Promise<ExecutionTaskReturn<TaskOutput, TaskLog> | undefined | void>\n | undefined\n | void;\n}\n\nexport interface ExecutionTaskHitBy {\n from: string;\n context: Record<string, any>;\n}\n\nexport interface ExecutionTaskReturn<TaskOutput = unknown, TaskLog = unknown> {\n output?: TaskOutput;\n log?: TaskLog;\n recorder?: ExecutionRecorderItem[];\n hitBy?: ExecutionTaskHitBy;\n}\n\nexport type ExecutionTask<\n E extends ExecutionTaskApply<any, any, any> = ExecutionTaskApply<\n any,\n any,\n any\n >,\n> = E &\n ExecutionTaskReturn<\n E extends ExecutionTaskApply<any, any, infer TaskOutput, any>\n ? TaskOutput\n : unknown,\n E extends ExecutionTaskApply<any, any, any, infer TaskLog>\n ? TaskLog\n : unknown\n > & {\n status: 'pending' | 'running' | 'finished' | 'failed' | 'cancelled';\n error?: Error;\n errorMessage?: string;\n errorStack?: string;\n timing?: {\n start: number;\n end?: number;\n cost?: number;\n };\n usage?: AIUsageInfo;\n searchAreaUsage?: AIUsageInfo;\n };\n\nexport interface ExecutionDump extends DumpMeta {\n name: string;\n description?: string;\n tasks: ExecutionTask[];\n}\n\n/*\ntask - insight-locate\n*/\nexport type ExecutionTaskInsightLocateParam = PlanningLocateParam;\n\nexport interface ExecutionTaskInsightLocateOutput {\n element: LocateResultElement | null;\n}\n\nexport interface ExecutionTaskInsightDumpLog {\n dump?: InsightDump;\n}\n\nexport type ExecutionTaskInsightLocateApply = ExecutionTaskApply<\n 'Insight',\n ExecutionTaskInsightLocateParam,\n ExecutionTaskInsightLocateOutput,\n ExecutionTaskInsightDumpLog\n>;\n\nexport type ExecutionTaskInsightLocate =\n ExecutionTask<ExecutionTaskInsightLocateApply>;\n\n/*\ntask - insight-query\n*/\nexport interface ExecutionTaskInsightQueryParam {\n dataDemand: InsightExtractParam;\n}\n\nexport interface ExecutionTaskInsightQueryOutput {\n data: any;\n}\n\nexport type ExecutionTaskInsightQueryApply = ExecutionTaskApply<\n 'Insight',\n ExecutionTaskInsightQueryParam,\n any,\n ExecutionTaskInsightDumpLog\n>;\n\nexport type ExecutionTaskInsightQuery =\n ExecutionTask<ExecutionTaskInsightQueryApply>;\n\n/*\ntask - assertion\n*/\nexport interface ExecutionTaskInsightAssertionParam {\n assertion: string;\n}\n\nexport type ExecutionTaskInsightAssertionApply = ExecutionTaskApply<\n 'Insight',\n ExecutionTaskInsightAssertionParam,\n InsightAssertionResponse,\n ExecutionTaskInsightDumpLog\n>;\n\nexport type ExecutionTaskInsightAssertion =\n ExecutionTask<ExecutionTaskInsightAssertionApply>;\n\n/*\ntask - action (i.e. interact) \n*/\nexport type ExecutionTaskActionApply<ActionParam = any> = ExecutionTaskApply<\n 'Action',\n ActionParam,\n void,\n void\n>;\n\nexport type ExecutionTaskAction = ExecutionTask<ExecutionTaskActionApply>;\n\n/*\ntask - Log\n*/\n\nexport type ExecutionTaskLogApply<\n LogParam = {\n content: string;\n },\n> = ExecutionTaskApply<'Log', LogParam, void, void>;\n\nexport type ExecutionTaskLog = ExecutionTask<ExecutionTaskLogApply>;\n\n/*\ntask - planning\n*/\n\nexport type ExecutionTaskPlanningApply = ExecutionTaskApply<\n 'Planning',\n {\n userInstruction: string;\n },\n PlanningAIResponse\n>;\n\nexport type ExecutionTaskPlanning = ExecutionTask<ExecutionTaskPlanningApply>;\n\n/*\nGrouped dump\n*/\nexport interface GroupedActionDump {\n groupName: string;\n groupDescription?: string;\n modelBriefs: string[];\n executions: ExecutionDump[];\n}\n\nexport type InterfaceType =\n | 'puppeteer'\n | 'playwright'\n | 'static'\n | 'chrome-extension-proxy'\n | 'android'\n | string;\n\nexport interface StreamingCodeGenerationOptions {\n /** Whether to enable streaming output */\n stream?: boolean;\n /** Callback function to handle streaming chunks */\n onChunk?: StreamingCallback;\n /** Callback function to handle streaming completion */\n onComplete?: (finalCode: string) => void;\n /** Callback function to handle streaming errors */\n onError?: (error: Error) => void;\n}\n\nexport type StreamingCallback = (chunk: CodeGenerationChunk) => void;\n\nexport interface CodeGenerationChunk {\n /** The incremental content chunk */\n content: string;\n /** The reasoning content */\n reasoning_content: string;\n /** The accumulated content so far */\n accumulated: string;\n /** Whether this is the final chunk */\n isComplete: boolean;\n /** Token usage information if available */\n usage?: AIUsageInfo;\n}\n\nexport interface StreamingAIResponse {\n /** The final accumulated content */\n content: string;\n /** Token usage information */\n usage?: AIUsageInfo;\n /** Whether the response was streamed */\n isStreamed: boolean;\n}\n\nexport interface DeviceAction<T = any> {\n name: string;\n description?: string;\n interfaceAlias?: string;\n paramSchema?: z.ZodType<T>;\n call: (param: T, context: ExecutorContext) => Promise<void> | void;\n}\n\n/**\n * Web-specific types\n */\nexport interface WebElementInfo extends BaseElement {\n id: string;\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n}\n\nexport type WebUIContext = UIContext<WebElementInfo>;\n\n/**\n * Agent\n */\n\nexport type CacheConfig = { strategy?: 'read-only' | 'read-write'; id: string };\n\nexport type Cache =\n | false // No read, no write\n | true // Will throw error at runtime - deprecated\n | CacheConfig; // Object configuration (requires explicit id)\n\nexport interface AgentOpt {\n testId?: string;\n // @deprecated\n cacheId?: string; // Keep backward compatibility, but marked as deprecated\n groupName?: string;\n groupDescription?: string;\n /* if auto generate report, default true */\n generateReport?: boolean;\n /* if auto print report msg, default true */\n autoPrintReportMsg?: boolean;\n onTaskStartTip?: OnTaskStartTip;\n aiActionContext?: string;\n /* custom report file name */\n reportFileName?: string;\n modelConfig?: TModelConfigFn;\n cache?: Cache;\n replanningCycleLimit?: number;\n /* Screenshot scaling ratio to reduce image size sent to AI for better performance */\n screenshotScale?: number;\n}\n"],"names":["AIResponseFormat","UIContext"],"mappings":";AAqCO,IAAKA,yBAAgBA,WAAAA,GAAAA,SAAhBA,gBAAgB;;;WAAhBA;;AAwFL,MAAeC;AAQtB"}
|