@rpascene/core 0.30.18 → 0.30.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/dist/es/agent/agent.mjs +6 -4
  2. package/dist/es/agent/agent.mjs.map +1 -1
  3. package/dist/es/agent/task-cache.mjs.map +1 -1
  4. package/dist/es/agent/tasks.mjs +14 -47
  5. package/dist/es/agent/tasks.mjs.map +1 -1
  6. package/dist/es/agent/utils.mjs.map +1 -1
  7. package/dist/es/ai-model/action-executor.mjs +6 -5
  8. package/dist/es/ai-model/action-executor.mjs.map +1 -1
  9. package/dist/es/ai-model/common.mjs.map +1 -1
  10. package/dist/es/ai-model/inspect.mjs +6 -6
  11. package/dist/es/ai-model/inspect.mjs.map +1 -1
  12. package/dist/es/ai-model/llm-planning.mjs +2 -2
  13. package/dist/es/ai-model/llm-planning.mjs.map +1 -1
  14. package/dist/es/ai-model/prompt/playwright-generator.mjs +6 -5
  15. package/dist/es/ai-model/prompt/playwright-generator.mjs.map +1 -1
  16. package/dist/es/ai-model/prompt/yaml-generator.mjs +6 -5
  17. package/dist/es/ai-model/prompt/yaml-generator.mjs.map +1 -1
  18. package/dist/es/ai-model/service-caller/index.mjs +11 -6
  19. package/dist/es/ai-model/service-caller/index.mjs.map +1 -1
  20. package/dist/es/ai-model/ui-tars-planning.mjs +2 -2
  21. package/dist/es/ai-model/ui-tars-planning.mjs.map +1 -1
  22. package/dist/es/device/index.mjs.map +1 -1
  23. package/dist/es/insight/index.mjs +9 -6
  24. package/dist/es/insight/index.mjs.map +1 -1
  25. package/dist/es/types.mjs.map +1 -1
  26. package/dist/es/utils.mjs +1 -1
  27. package/dist/es/yaml/player.mjs.map +1 -1
  28. package/dist/lib/agent/agent.js +6 -4
  29. package/dist/lib/agent/agent.js.map +1 -1
  30. package/dist/lib/agent/task-cache.js.map +1 -1
  31. package/dist/lib/agent/tasks.js +14 -47
  32. package/dist/lib/agent/tasks.js.map +1 -1
  33. package/dist/lib/agent/utils.js.map +1 -1
  34. package/dist/lib/ai-model/action-executor.js +6 -5
  35. package/dist/lib/ai-model/action-executor.js.map +1 -1
  36. package/dist/lib/ai-model/common.js.map +1 -1
  37. package/dist/lib/ai-model/inspect.js +6 -6
  38. package/dist/lib/ai-model/inspect.js.map +1 -1
  39. package/dist/lib/ai-model/llm-planning.js +2 -2
  40. package/dist/lib/ai-model/llm-planning.js.map +1 -1
  41. package/dist/lib/ai-model/prompt/playwright-generator.js +6 -5
  42. package/dist/lib/ai-model/prompt/playwright-generator.js.map +1 -1
  43. package/dist/lib/ai-model/prompt/yaml-generator.js +6 -5
  44. package/dist/lib/ai-model/prompt/yaml-generator.js.map +1 -1
  45. package/dist/lib/ai-model/service-caller/index.js +11 -6
  46. package/dist/lib/ai-model/service-caller/index.js.map +1 -1
  47. package/dist/lib/ai-model/ui-tars-planning.js +2 -2
  48. package/dist/lib/ai-model/ui-tars-planning.js.map +1 -1
  49. package/dist/lib/device/index.js.map +1 -1
  50. package/dist/lib/insight/index.js +9 -6
  51. package/dist/lib/insight/index.js.map +1 -1
  52. package/dist/lib/types.js.map +1 -1
  53. package/dist/lib/utils.js +1 -1
  54. package/dist/lib/yaml/player.js.map +1 -1
  55. package/dist/types/agent/agent.d.ts +2 -0
  56. package/dist/types/agent/tasks.d.ts +2 -6
  57. package/dist/types/ai-model/action-executor.d.ts +2 -2
  58. package/dist/types/ai-model/common.d.ts +1 -1
  59. package/dist/types/ai-model/inspect.d.ts +3 -0
  60. package/dist/types/ai-model/llm-planning.d.ts +1 -0
  61. package/dist/types/ai-model/prompt/playwright-generator.d.ts +2 -2
  62. package/dist/types/ai-model/prompt/yaml-generator.d.ts +2 -2
  63. package/dist/types/ai-model/service-caller/index.d.ts +3 -2
  64. package/dist/types/ai-model/ui-tars-planning.d.ts +1 -0
  65. package/dist/types/insight/index.d.ts +3 -2
  66. package/dist/types/types.d.ts +1 -0
  67. package/package.json +3 -3
@@ -285,6 +285,8 @@ class Agent {
285
285
  }
286
286
  async aiAction(taskPrompt, opt) {
287
287
  var _this_taskCache, _this_taskCache1;
288
+ const abortSignal = null == opt ? void 0 : opt.abortSignal;
289
+ if (null == abortSignal ? void 0 : abortSignal.aborted) throw new Error(`aiAct aborted: ${abortSignal.reason || 'signal already aborted'}`);
288
290
  const modelConfig = this.modelConfigManager.getModelConfig('planning');
289
291
  const cacheable = null == opt ? void 0 : opt.cacheable;
290
292
  const isVlmUiTars = 'vlm-ui-tars' === modelConfig.vlMode;
@@ -297,7 +299,7 @@ class Agent {
297
299
  const yaml = null == (_matchedCache_cacheContent1 = matchedCache.cacheContent) ? void 0 : _matchedCache_cacheContent1.yamlWorkflow;
298
300
  return this.runYaml(yaml);
299
301
  }
300
- const { output, executor } = await this.taskExecutor.action(taskPrompt, modelConfig, this.opts.aiActionContext, cacheable);
302
+ const { output, executor } = await this.taskExecutor.action(taskPrompt, modelConfig, this.opts.aiActionContext, cacheable, abortSignal);
301
303
  console.log(output, 'output');
302
304
  if (this.taskCache && (null == output ? void 0 : output.yamlFlow) && false !== cacheable) {
303
305
  const yamlContent = {
@@ -349,7 +351,7 @@ class Agent {
349
351
  return this.aiString(prompt, opt);
350
352
  }
351
353
  async describeElementAtPoint(center, opt) {
352
- const { verifyPrompt = true, retryLimit = 3 } = opt || {};
354
+ const { verifyPrompt = true, retryLimit = 3, abortSignal } = opt || {};
353
355
  let success = false;
354
356
  let retryCount = 0;
355
357
  let resultPrompt = '';
@@ -360,7 +362,8 @@ class Agent {
360
362
  debug('aiDescribe', center, 'verifyPrompt', verifyPrompt, 'retryCount', retryCount, 'deepThink', deepThink);
361
363
  const modelConfig = this.modelConfigManager.getModelConfig('grounding');
362
364
  const text = await this.insight.describe(center, modelConfig, {
363
- deepThink
365
+ deepThink,
366
+ abortSignal
364
367
  });
365
368
  debug('aiDescribe text', text);
366
369
  assert(text.description, `failed to describe element at [${center}]`);
@@ -478,7 +481,6 @@ class Agent {
478
481
  async destroy() {
479
482
  var _this_interface_destroy, _this_interface;
480
483
  if (this.destroyed) return;
481
- this.taskExecutor.cancelPlanning();
482
484
  await (null == (_this_interface_destroy = (_this_interface = this.interface).destroy) ? void 0 : _this_interface_destroy.call(_this_interface));
483
485
  this.resetDump();
484
486
  this.destroyed = true;
@@ -1 +1 @@
1
- {"version":3,"file":"agent\\agent.mjs","sources":["webpack://@rpascene/core/./src/agent/agent.ts"],"sourcesContent":["import {\n type AgentAssertOpt,\n type AgentDescribeElementAtPointResult,\n type AgentOpt,\n type AgentWaitForOpt,\n type CacheConfig,\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 RpasceneYamlScript,\n type OnTaskStartTip,\n type PlanningAction,\n type Rect,\n type ScrollParam,\n type TUserPrompt,\n type UIContext,\n} from '../index';\nexport type TestStatus =\n | 'passed'\n | 'failed'\n | 'timedOut'\n | 'skipped'\n | 'interrupted';\nimport yaml from 'js-yaml';\n\nimport {\n getVersion,\n groupedActionDumpFileExt,\n processCacheConfig,\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 {\n ModelConfigManager,\n globalModelConfigManager,\n} from '@rpascene/shared/env';\nimport { imageInfoOfBase64, resizeImgBase64 } from '@rpascene/shared/img';\nimport { getDebug } from '@rpascene/shared/logger';\nimport { assert } from '@rpascene/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[] = [\n 'read-only',\n 'read-write',\n 'write-only',\n];\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 this.interface.interfaceType !== 'page-over-chrome-extension-bridge'\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: 'Rpascene 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 cacheConfigObj = this.processCacheConfig(opts || {});\n if (cacheConfigObj) {\n this.taskCache = new TaskCache(\n cacheConfigObj.id,\n cacheConfigObj.enabled,\n undefined, // cacheFilePath\n {\n readOnly: cacheConfigObj.readOnly,\n writeOnly: cacheConfigObj.writeOnly,\n },\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 sdkVersion: getVersion(),\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 const executionDump = executor.dump();\n if (this.opts.aiActionContext) {\n executionDump.aiActionContext = this.opts.aiActionContext;\n }\n this.appendExecutionDump(executionDump);\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'); // UI 定位能力\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 | number } & {\n autoDismissKeyboard?: boolean;\n } & { mode?: 'replace' | 'clear' | 'append' },\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 | number,\n locatePrompt: TUserPrompt,\n opt?: LocateOption & { autoDismissKeyboard?: boolean } & {\n mode?: 'replace' | 'clear' | 'append';\n }, // AndroidDeviceInputOpt &\n ): Promise<any>;\n\n // Implementation\n async aiInput(\n locatePromptOrValue: TUserPrompt | string | number,\n locatePromptOrOpt:\n | TUserPrompt\n | (LocateOption & { value: string | number } & {\n autoDismissKeyboard?: boolean;\n } & { mode?: 'replace' | 'clear' | 'append' }) // AndroidDeviceInputOpt &\n | undefined,\n optOrUndefined?: LocateOption, // AndroidDeviceInputOpt &\n ) {\n let value: string | number;\n let locatePrompt: TUserPrompt;\n let opt:\n | (LocateOption & { value: string | number } & {\n autoDismissKeyboard?: boolean;\n } & { mode?: 'replace' | 'clear' | 'append' }) // 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 | number;\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 | number;\n locatePrompt = locatePromptOrOpt as TUserPrompt;\n opt = {\n ...optOrUndefined,\n value,\n };\n }\n\n assert(\n typeof value === 'string' || typeof value === 'number',\n 'input value must be a string or number, 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 cacheable,\n );\n\n console.log(output, 'output')\n\n // update cache\n if (this.taskCache && output?.yamlFlow && cacheable !== false) {\n const yamlContent: RpasceneYamlScript = {\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'); // UI 定位能力\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'); // UI 定位能力\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 doNotThrowError: opt?.doNotThrowError,\n };\n\n const { textPrompt, multimodalPrompt } = parsePrompt(assertion);\n\n const { output, executor, thought } =\n await this.taskExecutor.createTypeQueryExecution<boolean>(\n 'Assert',\n textPrompt,\n modelConfig,\n insightOpt,\n multimodalPrompt,\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: ${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 // Early return if already destroyed\n if (this.destroyed) {\n return;\n }\n this.taskExecutor.cancelPlanning();\n await this.interface.destroy?.();\n\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 logTime: now,\n name: `Log - ${title || 'untitled'}`,\n description: opt?.content || '',\n tasks: [task],\n };\n if (this.opts.aiActionContext) {\n executionDump.aiActionContext = this.opts.aiActionContext;\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(opts: AgentOpt): {\n id: string;\n enabled: boolean;\n readOnly: boolean;\n writeOnly: boolean;\n } | null {\n // Validate original cache config before processing\n // Agent requires explicit IDs - don't allow auto-generation\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 // Check if cache config object is missing ID\n if (\n opts.cache &&\n typeof opts.cache === 'object' &&\n opts.cache !== null &&\n !opts.cache.id\n ) {\n throw new Error(\n 'cache configuration requires an explicit id.\\n' +\n 'Example: cache: { id: \"my-cache-id\" }',\n );\n }\n\n // Use the unified utils function to process cache configuration\n const cacheConfig = processCacheConfig(\n opts.cache,\n opts.cacheId || opts.testId || 'default',\n );\n\n if (!cacheConfig) {\n return null;\n }\n\n // Handle cache configuration object\n if (typeof cacheConfig === 'object' && cacheConfig !== null) {\n const id = cacheConfig.id;\n const rawStrategy = cacheConfig.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 const isWriteOnly = strategyValue === 'write-only';\n\n return {\n id,\n enabled: !isWriteOnly,\n readOnly: isReadOnly,\n writeOnly: isWriteOnly,\n };\n }\n\n return null;\n }\n\n /**\n * Manually flush cache to file\n * @param options - Optional configuration\n * @param options.cleanUnused - If true, removes unused cache records before flushing\n */\n async flushCache(options?: { cleanUnused?: boolean }): Promise<void> {\n if (!this.taskCache) {\n throw new Error('Cache is not configured');\n }\n\n this.taskCache.flushCacheToFile(options);\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","getVersion","execution","trimmedExecution","trimContextByViewport","currentDump","stringifyDumpData","reportHTMLContent","Error","generateReport","autoPrintReportMsg","writeLogFile","groupedActionDumpFileExt","printReportMsg","task","param","paramStr","tip","typeStr","executor","doNotThrowError","executionDump","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","_this","groupName","groupDescription","executions","newExecutions","Array","tasks","restExecution","newTasks","uiContext","log","restTask","opts","cacheConfig","processCacheConfig","id","rawStrategy","strategyValue","isReadOnly","isWriteOnly","options","interfaceInstance","Object","ModelConfigManager","globalModelConfigManager","Insight","cacheConfigObj","TaskCache","TaskExecutor","getReportFileName","createAgent"],"mappings":"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"}
1
+ {"version":3,"file":"agent\\agent.mjs","sources":["webpack://@rpascene/core/./src/agent/agent.ts"],"sourcesContent":["import {\n type AgentAssertOpt,\n type AgentDescribeElementAtPointResult,\n type AgentOpt,\n type AgentWaitForOpt,\n type CacheConfig,\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 OnTaskStartTip,\n type PlanningAction,\n type Rect,\n type RpasceneYamlScript,\n type ScrollParam,\n type TUserPrompt,\n type UIContext,\n} from '../index';\nexport type TestStatus =\n | 'passed'\n | 'failed'\n | 'timedOut'\n | 'skipped'\n | 'interrupted';\nimport yaml from 'js-yaml';\n\nimport {\n getVersion,\n groupedActionDumpFileExt,\n processCacheConfig,\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 {\n ModelConfigManager,\n globalModelConfigManager,\n} from '@rpascene/shared/env';\nimport { imageInfoOfBase64, resizeImgBase64 } from '@rpascene/shared/img';\nimport { getDebug } from '@rpascene/shared/logger';\nimport { assert } from '@rpascene/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[] = [\n 'read-only',\n 'read-write',\n 'write-only',\n];\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 this.interface.interfaceType !== 'page-over-chrome-extension-bridge'\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: 'Rpascene 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 cacheConfigObj = this.processCacheConfig(opts || {});\n if (cacheConfigObj) {\n this.taskCache = new TaskCache(\n cacheConfigObj.id,\n cacheConfigObj.enabled,\n undefined, // cacheFilePath\n {\n readOnly: cacheConfigObj.readOnly,\n writeOnly: cacheConfigObj.writeOnly,\n },\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 sdkVersion: getVersion(),\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 const executionDump = executor.dump();\n if (this.opts.aiActionContext) {\n executionDump.aiActionContext = this.opts.aiActionContext;\n }\n this.appendExecutionDump(executionDump);\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'); // UI 定位能力\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 | number } & {\n autoDismissKeyboard?: boolean;\n } & { mode?: 'replace' | 'clear' | 'append' },\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 | number,\n locatePrompt: TUserPrompt,\n opt?: LocateOption & { autoDismissKeyboard?: boolean } & {\n mode?: 'replace' | 'clear' | 'append';\n }, // AndroidDeviceInputOpt &\n ): Promise<any>;\n\n // Implementation\n async aiInput(\n locatePromptOrValue: TUserPrompt | string | number,\n locatePromptOrOpt:\n | TUserPrompt\n | (LocateOption & { value: string | number } & {\n autoDismissKeyboard?: boolean;\n } & { mode?: 'replace' | 'clear' | 'append' }) // AndroidDeviceInputOpt &\n | undefined,\n optOrUndefined?: LocateOption, // AndroidDeviceInputOpt &\n ) {\n let value: string | number;\n let locatePrompt: TUserPrompt;\n let opt:\n | (LocateOption & { value: string | number } & {\n autoDismissKeyboard?: boolean;\n } & { mode?: 'replace' | 'clear' | 'append' }) // 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 | number;\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 | number;\n locatePrompt = locatePromptOrOpt as TUserPrompt;\n opt = {\n ...optOrUndefined,\n value,\n };\n }\n\n assert(\n typeof value === 'string' || typeof value === 'number',\n 'input value must be a string or number, 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 abortSignal?: AbortSignal;\n },\n ) {\n const abortSignal = opt?.abortSignal;\n if (abortSignal?.aborted) {\n throw new Error(\n `aiAct aborted: ${abortSignal.reason || 'signal already aborted'}`,\n );\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 cacheable,\n abortSignal,\n );\n\n console.log(output, 'output');\n\n // update cache\n if (this.taskCache && output?.yamlFlow && cacheable !== false) {\n const yamlContent: RpasceneYamlScript = {\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 abortSignal?: AbortSignal;\n } & LocatorValidatorOption,\n ): Promise<AgentDescribeElementAtPointResult> {\n const { verifyPrompt = true, retryLimit = 3, abortSignal } = 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'); // UI 定位能力\n\n const text = await this.insight.describe(center, modelConfig, {\n deepThink,\n abortSignal,\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'); // UI 定位能力\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 doNotThrowError: opt?.doNotThrowError,\n };\n\n const { textPrompt, multimodalPrompt } = parsePrompt(assertion);\n\n const { output, executor, thought } =\n await this.taskExecutor.createTypeQueryExecution<boolean>(\n 'Assert',\n textPrompt,\n modelConfig,\n insightOpt,\n multimodalPrompt,\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: ${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 // Early return if already destroyed\n if (this.destroyed) {\n return;\n }\n\n await this.interface.destroy?.();\n\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 logTime: now,\n name: `Log - ${title || 'untitled'}`,\n description: opt?.content || '',\n tasks: [task],\n };\n if (this.opts.aiActionContext) {\n executionDump.aiActionContext = this.opts.aiActionContext;\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(opts: AgentOpt): {\n id: string;\n enabled: boolean;\n readOnly: boolean;\n writeOnly: boolean;\n } | null {\n // Validate original cache config before processing\n // Agent requires explicit IDs - don't allow auto-generation\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 // Check if cache config object is missing ID\n if (\n opts.cache &&\n typeof opts.cache === 'object' &&\n opts.cache !== null &&\n !opts.cache.id\n ) {\n throw new Error(\n 'cache configuration requires an explicit id.\\n' +\n 'Example: cache: { id: \"my-cache-id\" }',\n );\n }\n\n // Use the unified utils function to process cache configuration\n const cacheConfig = processCacheConfig(\n opts.cache,\n opts.cacheId || opts.testId || 'default',\n );\n\n if (!cacheConfig) {\n return null;\n }\n\n // Handle cache configuration object\n if (typeof cacheConfig === 'object' && cacheConfig !== null) {\n const id = cacheConfig.id;\n const rawStrategy = cacheConfig.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 const isWriteOnly = strategyValue === 'write-only';\n\n return {\n id,\n enabled: !isWriteOnly,\n readOnly: isReadOnly,\n writeOnly: isWriteOnly,\n };\n }\n\n return null;\n }\n\n /**\n * Manually flush cache to file\n * @param options - Optional configuration\n * @param options.cleanUnused - If true, removes unused cache records before flushing\n */\n async flushCache(options?: { cleanUnused?: boolean }): Promise<void> {\n if (!this.taskCache) {\n throw new Error('Cache is not configured');\n }\n\n this.taskCache.flushCacheToFile(options);\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","getVersion","execution","trimmedExecution","trimContextByViewport","currentDump","stringifyDumpData","reportHTMLContent","Error","generateReport","autoPrintReportMsg","writeLogFile","groupedActionDumpFileExt","printReportMsg","task","param","paramStr","tip","typeStr","executor","doNotThrowError","executionDump","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","abortSignal","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","_this","groupName","groupDescription","executions","newExecutions","Array","tasks","restExecution","newTasks","uiContext","log","restTask","opts","cacheConfig","processCacheConfig","id","rawStrategy","strategyValue","isReadOnly","isWriteOnly","options","interfaceInstance","Object","ModelConfigManager","globalModelConfigManager","Insight","cacheConfigObj","TaskCache","TaskExecutor","getReportFileName","createAgent"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"agent\\task-cache.mjs","sources":["webpack://@rpascene/core/./src/agent/task-cache.ts"],"sourcesContent":["import assert from 'node:assert';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { isDeepStrictEqual } from 'node:util';\nimport type { TUserPrompt } from '@/ai-model';\nimport type { ElementCacheFeature } from '@/types';\nimport { getRpasceneRunSubDir } from '@rpascene/shared/common';\nimport {\n MIDSCENE_CACHE_MAX_FILENAME_LENGTH,\n globalConfigManager,\n} from '@rpascene/shared/env';\nimport { getDebug } from '@rpascene/shared/logger';\nimport { ifInBrowser, ifInWorker } from '@rpascene/shared/utils';\nimport { generateHashId } from '@rpascene/shared/utils';\nimport { replaceIllegalPathCharsAndSpace } from '@rpascene/shared/utils';\nimport yaml from 'js-yaml';\nimport semver from 'semver';\nimport { getRpasceneVersion } from './utils';\n\nconst DEFAULT_CACHE_MAX_FILENAME_LENGTH = 200;\n\nexport const debug = getDebug('cache');\n\nexport interface PlanningCache {\n type: 'plan';\n prompt: string;\n yamlWorkflow: string;\n}\n\nexport interface LocateCache {\n type: 'locate';\n prompt: TUserPrompt;\n cache?: ElementCacheFeature;\n /** @deprecated kept for backward compatibility */\n xpaths?: string[];\n}\n\nexport interface MatchCacheResult<T extends PlanningCache | LocateCache> {\n cacheContent: T;\n updateFn: (cb: (cache: T) => void) => void;\n}\n\nexport type CacheFileContent = {\n rpasceneVersion: string;\n cacheId: string;\n caches: Array<PlanningCache | LocateCache>;\n};\n\nconst lowestSupportedRpasceneVersion = '0.16.10';\nexport const cacheFileExt = '.cache.yaml';\n\nexport class TaskCache {\n cacheId: string;\n\n cacheFilePath?: string;\n\n cache: CacheFileContent;\n\n isCacheResultUsed: boolean; // a flag to indicate if the cache result should be used\n cacheOriginalLength: number;\n\n readOnlyMode: boolean; // a flag to indicate if the cache is in read-only mode\n\n writeOnlyMode: boolean; // a flag to indicate if the cache is in write-only mode\n\n private matchedCacheIndices: Set<string> = new Set(); // Track matched records\n\n constructor(\n cacheId: string,\n isCacheResultUsed: boolean,\n cacheFilePath?: string,\n options: { readOnly?: boolean; writeOnly?: boolean } = {},\n ) {\n assert(cacheId, 'cacheId is required');\n let safeCacheId = replaceIllegalPathCharsAndSpace(cacheId);\n const cacheMaxFilenameLength =\n globalConfigManager.getEnvConfigInNumber(\n MIDSCENE_CACHE_MAX_FILENAME_LENGTH,\n ) || DEFAULT_CACHE_MAX_FILENAME_LENGTH;\n if (Buffer.byteLength(safeCacheId, 'utf8') > cacheMaxFilenameLength) {\n const prefix = safeCacheId.slice(0, 32);\n const hash = generateHashId(undefined, safeCacheId);\n safeCacheId = `${prefix}-${hash}`;\n }\n this.cacheId = safeCacheId;\n\n this.cacheFilePath =\n ifInBrowser || ifInWorker\n ? undefined\n : cacheFilePath ||\n join(getRpasceneRunSubDir('cache'), `${this.cacheId}${cacheFileExt}`);\n const readOnlyMode = Boolean(options?.readOnly);\n const writeOnlyMode = Boolean(options?.writeOnly);\n\n if (readOnlyMode && writeOnlyMode) {\n throw new Error('TaskCache cannot be both read-only and write-only');\n }\n\n this.isCacheResultUsed = writeOnlyMode ? false : isCacheResultUsed;\n this.readOnlyMode = readOnlyMode;\n this.writeOnlyMode = writeOnlyMode;\n\n let cacheContent;\n if (this.cacheFilePath && !this.writeOnlyMode) {\n cacheContent = this.loadCacheFromFile();\n }\n if (!cacheContent) {\n cacheContent = {\n rpasceneVersion: getRpasceneVersion(),\n cacheId: this.cacheId,\n caches: [],\n };\n }\n this.cache = cacheContent;\n this.cacheOriginalLength = this.isCacheResultUsed\n ? this.cache.caches.length\n : 0;\n }\n\n matchCache(\n prompt: TUserPrompt,\n type: 'plan' | 'locate',\n ): MatchCacheResult<PlanningCache | LocateCache> | undefined {\n if (!this.isCacheResultUsed) {\n return undefined;\n }\n // Find the first unused matching cache\n for (let i = 0; i < this.cacheOriginalLength; i++) {\n const item = this.cache.caches[i];\n const promptStr =\n typeof prompt === 'string' ? prompt : JSON.stringify(prompt);\n const key = `${type}:${promptStr}:${i}`;\n if (\n item.type === type &&\n isDeepStrictEqual(item.prompt, prompt) &&\n !this.matchedCacheIndices.has(key)\n ) {\n if (item.type === 'locate') {\n const locateItem = item as LocateCache;\n if (!locateItem.cache && Array.isArray(locateItem.xpaths)) {\n locateItem.cache = { xpaths: locateItem.xpaths };\n }\n if ('xpaths' in locateItem) {\n locateItem.xpaths = undefined;\n }\n }\n this.matchedCacheIndices.add(key);\n debug(\n 'cache found and marked as used, type: %s, prompt: %s, index: %d',\n type,\n prompt,\n i,\n );\n return {\n cacheContent: item,\n updateFn: (cb: (cache: PlanningCache | LocateCache) => void) => {\n debug(\n 'will call updateFn to update cache, type: %s, prompt: %s, index: %d',\n type,\n prompt,\n i,\n );\n cb(item);\n\n if (this.readOnlyMode) {\n debug(\n 'read-only mode, cache updated in memory but not flushed to file',\n );\n return;\n }\n\n debug(\n 'cache updated, will flush to file, type: %s, prompt: %s, index: %d',\n type,\n prompt,\n i,\n );\n this.flushCacheToFile();\n },\n };\n }\n }\n debug('no unused cache found, type: %s, prompt: %s', type, prompt);\n return undefined;\n }\n\n matchPlanCache(prompt: string): MatchCacheResult<PlanningCache> | undefined {\n return this.matchCache(prompt, 'plan') as\n | MatchCacheResult<PlanningCache>\n | undefined;\n }\n\n matchLocateCache(\n prompt: TUserPrompt,\n ): MatchCacheResult<LocateCache> | undefined {\n return this.matchCache(prompt, 'locate') as\n | MatchCacheResult<LocateCache>\n | undefined;\n }\n\n appendCache(cache: PlanningCache | LocateCache) {\n debug('will append cache', cache);\n this.cache.caches.push(cache);\n\n if (this.readOnlyMode) {\n debug('read-only mode, cache appended to memory but not flushed to file');\n return;\n }\n\n this.flushCacheToFile();\n }\n\n loadCacheFromFile() {\n const cacheFile = this.cacheFilePath;\n assert(cacheFile, 'cache file path is required');\n\n if (!existsSync(cacheFile)) {\n debug('no cache file found, path: %s', cacheFile);\n return undefined;\n }\n\n // detect old cache file\n const jsonTypeCacheFile = cacheFile.replace(cacheFileExt, '.json');\n if (existsSync(jsonTypeCacheFile) && this.isCacheResultUsed) {\n console.warn(\n `An outdated cache file from an earlier version of Rpascene has been detected. Since version 0.17, we have implemented an improved caching strategy. Please delete the old file located at: ${jsonTypeCacheFile}.`,\n );\n return undefined;\n }\n\n try {\n const data = readFileSync(cacheFile, 'utf8');\n const jsonData = yaml.load(data) as CacheFileContent;\n\n const version = getRpasceneVersion();\n if (!version) {\n debug('no rpascene version info, will not read cache from file');\n return undefined;\n }\n\n if (\n semver.lt(jsonData.rpasceneVersion, lowestSupportedRpasceneVersion) &&\n !jsonData.rpasceneVersion.includes('beta') // for internal test\n ) {\n console.warn(\n `You are using an old version of Rpascene cache file, and we cannot match any info from it. Starting from Rpascene v0.17, we changed our strategy to use xpath for cache info, providing better performance.\\nPlease delete the existing cache and rebuild it. Sorry for the inconvenience.\\ncache file: ${cacheFile}`,\n );\n return undefined;\n }\n\n debug(\n 'cache loaded from file, path: %s, cache version: %s, record length: %s',\n cacheFile,\n jsonData.rpasceneVersion,\n jsonData.caches.length,\n );\n jsonData.rpasceneVersion = getRpasceneVersion(); // update the version\n return jsonData;\n } catch (err) {\n debug(\n 'cache file exists but load failed, path: %s, error: %s',\n cacheFile,\n err,\n );\n return undefined;\n }\n }\n\n flushCacheToFile(options?: { cleanUnused?: boolean }) {\n const version = getRpasceneVersion();\n if (!version) {\n debug('no rpascene version info, will not write cache to file');\n return;\n }\n\n if (!this.cacheFilePath) {\n debug('no cache file path, will not write cache to file');\n return;\n }\n\n // Clean unused caches if requested\n if (options?.cleanUnused) {\n // Skip cleaning in write-only mode or when cache is not used\n if (this.isCacheResultUsed) {\n const originalLength = this.cache.caches.length;\n\n // Collect indices of used caches\n const usedIndices = new Set<number>();\n for (const key of this.matchedCacheIndices) {\n // key format: \"type:prompt:index\"\n const parts = key.split(':');\n const index = Number.parseInt(parts[parts.length - 1], 10);\n if (!Number.isNaN(index)) {\n usedIndices.add(index);\n }\n }\n\n // Filter: keep used caches and newly added caches\n this.cache.caches = this.cache.caches.filter((_, index) => {\n const isUsed = usedIndices.has(index);\n const isNew = index >= this.cacheOriginalLength;\n return isUsed || isNew;\n });\n\n const removedCount = originalLength - this.cache.caches.length;\n if (removedCount > 0) {\n debug('cleaned %d unused cache record(s)', removedCount);\n } else {\n debug('no unused cache to clean');\n }\n } else {\n debug('skip cleaning: cache is not used for reading');\n }\n }\n\n try {\n const dir = dirname(this.cacheFilePath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n debug('created cache directory: %s', dir);\n }\n\n // Sort caches to ensure plan entries come before locate entries for better readability\n // Create a sorted copy for writing to disk while keeping in-memory order unchanged\n const sortedCaches = [...this.cache.caches].sort((a, b) => {\n if (a.type === 'plan' && b.type === 'locate') return -1;\n if (a.type === 'locate' && b.type === 'plan') return 1;\n return 0;\n });\n\n const cacheToWrite = {\n ...this.cache,\n caches: sortedCaches,\n };\n\n const yamlData = yaml.dump(cacheToWrite);\n writeFileSync(this.cacheFilePath, yamlData);\n debug('cache flushed to file: %s', this.cacheFilePath);\n } catch (err) {\n debug(\n 'write cache to file failed, path: %s, error: %s',\n this.cacheFilePath,\n err,\n );\n }\n }\n\n updateOrAppendCacheRecord(\n newRecord: PlanningCache | LocateCache,\n cachedRecord?: MatchCacheResult<PlanningCache | LocateCache>,\n ) {\n if (cachedRecord) {\n // update existing record\n if (newRecord.type === 'plan') {\n cachedRecord.updateFn((cache) => {\n (cache as PlanningCache).yamlWorkflow = newRecord.yamlWorkflow;\n });\n } else {\n cachedRecord.updateFn((cache) => {\n const locateCache = cache as LocateCache;\n locateCache.cache = newRecord.cache;\n if ('xpaths' in locateCache) {\n locateCache.xpaths = undefined;\n }\n });\n }\n } else {\n this.appendCache(newRecord);\n }\n }\n}\n"],"names":["DEFAULT_CACHE_MAX_FILENAME_LENGTH","debug","getDebug","lowestSupportedRpasceneVersion","cacheFileExt","TaskCache","prompt","type","i","item","promptStr","JSON","key","isDeepStrictEqual","locateItem","Array","undefined","cb","cache","cacheFile","assert","existsSync","jsonTypeCacheFile","console","data","readFileSync","jsonData","yaml","version","getRpasceneVersion","semver","err","options","originalLength","usedIndices","Set","parts","index","Number","_","isUsed","isNew","removedCount","dir","dirname","mkdirSync","sortedCaches","a","b","cacheToWrite","yamlData","writeFileSync","newRecord","cachedRecord","locateCache","cacheId","isCacheResultUsed","cacheFilePath","safeCacheId","replaceIllegalPathCharsAndSpace","cacheMaxFilenameLength","globalConfigManager","MIDSCENE_CACHE_MAX_FILENAME_LENGTH","Buffer","prefix","hash","generateHashId","ifInBrowser","ifInWorker","join","getRpasceneRunSubDir","readOnlyMode","Boolean","writeOnlyMode","Error","cacheContent"],"mappings":"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"}
1
+ {"version":3,"file":"agent\\task-cache.mjs","sources":["webpack://@rpascene/core/./src/agent/task-cache.ts"],"sourcesContent":["import assert from 'node:assert';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { isDeepStrictEqual } from 'node:util';\nimport type { TUserPrompt } from '@/ai-model';\nimport type { ElementCacheFeature } from '@/types';\nimport { getRpasceneRunSubDir } from '@rpascene/shared/common';\nimport {\n MIDSCENE_CACHE_MAX_FILENAME_LENGTH,\n globalConfigManager,\n} from '@rpascene/shared/env';\nimport { getDebug } from '@rpascene/shared/logger';\nimport { ifInBrowser, ifInWorker } from '@rpascene/shared/utils';\nimport { generateHashId } from '@rpascene/shared/utils';\nimport { replaceIllegalPathCharsAndSpace } from '@rpascene/shared/utils';\nimport yaml from 'js-yaml';\nimport semver from 'semver';\nimport { getRpasceneVersion } from './utils';\n\nconst DEFAULT_CACHE_MAX_FILENAME_LENGTH = 200;\n\nexport const debug = getDebug('cache');\n\nexport interface PlanningCache {\n type: 'plan';\n prompt: string;\n yamlWorkflow: string;\n}\n\nexport interface LocateCache {\n type: 'locate';\n prompt: TUserPrompt;\n cache?: ElementCacheFeature;\n /** @deprecated kept for backward compatibility */\n xpaths?: string[];\n}\n\nexport interface MatchCacheResult<T extends PlanningCache | LocateCache> {\n cacheContent: T;\n updateFn: (cb: (cache: T) => void) => void;\n}\n\nexport type CacheFileContent = {\n rpasceneVersion: string;\n cacheId: string;\n caches: Array<PlanningCache | LocateCache>;\n};\n\nconst lowestSupportedRpasceneVersion = '0.16.10';\nexport const cacheFileExt = '.cache.yaml';\n\nexport class TaskCache {\n cacheId: string;\n\n cacheFilePath?: string;\n\n cache: CacheFileContent;\n\n isCacheResultUsed: boolean; // a flag to indicate if the cache result should be used\n cacheOriginalLength: number;\n\n readOnlyMode: boolean; // a flag to indicate if the cache is in read-only mode\n\n writeOnlyMode: boolean; // a flag to indicate if the cache is in write-only mode\n\n private matchedCacheIndices: Set<string> = new Set(); // Track matched records\n\n constructor(\n cacheId: string,\n isCacheResultUsed: boolean,\n cacheFilePath?: string,\n options: { readOnly?: boolean; writeOnly?: boolean } = {},\n ) {\n assert(cacheId, 'cacheId is required');\n let safeCacheId = replaceIllegalPathCharsAndSpace(cacheId);\n const cacheMaxFilenameLength =\n globalConfigManager.getEnvConfigInNumber(\n MIDSCENE_CACHE_MAX_FILENAME_LENGTH,\n ) || DEFAULT_CACHE_MAX_FILENAME_LENGTH;\n if (Buffer.byteLength(safeCacheId, 'utf8') > cacheMaxFilenameLength) {\n const prefix = safeCacheId.slice(0, 32);\n const hash = generateHashId(undefined, safeCacheId);\n safeCacheId = `${prefix}-${hash}`;\n }\n this.cacheId = safeCacheId;\n\n this.cacheFilePath =\n ifInBrowser || ifInWorker\n ? undefined\n : cacheFilePath ||\n join(getRpasceneRunSubDir('cache'), `${this.cacheId}${cacheFileExt}`);\n const readOnlyMode = Boolean(options?.readOnly);\n const writeOnlyMode = Boolean(options?.writeOnly);\n\n if (readOnlyMode && writeOnlyMode) {\n throw new Error('TaskCache cannot be both read-only and write-only');\n }\n\n this.isCacheResultUsed = writeOnlyMode ? false : isCacheResultUsed;\n this.readOnlyMode = readOnlyMode;\n this.writeOnlyMode = writeOnlyMode;\n\n let cacheContent;\n if (this.cacheFilePath && !this.writeOnlyMode) {\n cacheContent = this.loadCacheFromFile();\n }\n if (!cacheContent) {\n cacheContent = {\n rpasceneVersion: getRpasceneVersion(),\n cacheId: this.cacheId,\n caches: [],\n };\n }\n this.cache = cacheContent;\n this.cacheOriginalLength = this.isCacheResultUsed\n ? this.cache.caches.length\n : 0;\n }\n\n matchCache(\n prompt: TUserPrompt,\n type: 'plan' | 'locate',\n ): MatchCacheResult<PlanningCache | LocateCache> | undefined {\n if (!this.isCacheResultUsed) {\n return undefined;\n }\n // Find the first unused matching cache\n for (let i = 0; i < this.cacheOriginalLength; i++) {\n const item = this.cache.caches[i];\n const promptStr =\n typeof prompt === 'string' ? prompt : JSON.stringify(prompt);\n const key = `${type}:${promptStr}:${i}`;\n if (\n item.type === type &&\n isDeepStrictEqual(item.prompt, prompt) &&\n !this.matchedCacheIndices.has(key)\n ) {\n if (item.type === 'locate') {\n const locateItem = item as LocateCache;\n if (!locateItem.cache && Array.isArray(locateItem.xpaths)) {\n locateItem.cache = { xpaths: locateItem.xpaths };\n }\n if ('xpaths' in locateItem) {\n locateItem.xpaths = undefined;\n }\n }\n this.matchedCacheIndices.add(key);\n debug(\n 'cache found and marked as used, type: %s, prompt: %s, index: %d',\n type,\n prompt,\n i,\n );\n return {\n cacheContent: item,\n updateFn: (cb: (cache: PlanningCache | LocateCache) => void) => {\n debug(\n 'will call updateFn to update cache, type: %s, prompt: %s, index: %d',\n type,\n prompt,\n i,\n );\n cb(item);\n\n if (this.readOnlyMode) {\n debug(\n 'read-only mode, cache updated in memory but not flushed to file',\n );\n return;\n }\n\n debug(\n 'cache updated, will flush to file, type: %s, prompt: %s, index: %d',\n type,\n prompt,\n i,\n );\n this.flushCacheToFile();\n },\n };\n }\n }\n debug('no unused cache found, type: %s, prompt: %s', type, prompt);\n return undefined;\n }\n\n matchPlanCache(prompt: string): MatchCacheResult<PlanningCache> | undefined {\n return this.matchCache(prompt, 'plan') as\n | MatchCacheResult<PlanningCache>\n | undefined;\n }\n\n matchLocateCache(\n prompt: TUserPrompt,\n ): MatchCacheResult<LocateCache> | undefined {\n return this.matchCache(prompt, 'locate') as\n | MatchCacheResult<LocateCache>\n | undefined;\n }\n\n appendCache(cache: PlanningCache | LocateCache) {\n debug('will append cache', cache);\n this.cache.caches.push(cache);\n\n if (this.readOnlyMode) {\n debug('read-only mode, cache appended to memory but not flushed to file');\n return;\n }\n\n this.flushCacheToFile();\n }\n\n loadCacheFromFile() {\n const cacheFile = this.cacheFilePath;\n assert(cacheFile, 'cache file path is required');\n\n if (!existsSync(cacheFile)) {\n debug('no cache file found, path: %s', cacheFile);\n return undefined;\n }\n\n // detect old cache file\n const jsonTypeCacheFile = cacheFile.replace(cacheFileExt, '.json');\n if (existsSync(jsonTypeCacheFile) && this.isCacheResultUsed) {\n console.warn(\n `An outdated cache file from an earlier version of Rpascene has been detected. Since version 0.17, we have implemented an improved caching strategy. Please delete the old file located at: ${jsonTypeCacheFile}.`,\n );\n return undefined;\n }\n\n try {\n const data = readFileSync(cacheFile, 'utf8');\n const jsonData = yaml.load(data) as CacheFileContent;\n\n const version = getRpasceneVersion();\n if (!version) {\n debug('no rpascene version info, will not read cache from file');\n return undefined;\n }\n\n if (\n semver.lt(jsonData.rpasceneVersion, lowestSupportedRpasceneVersion) &&\n !jsonData.rpasceneVersion.includes('beta') // for internal test\n ) {\n console.warn(\n `You are using an old version of Rpascene cache file, and we cannot match any info from it. Starting from Rpascene v0.17, we changed our strategy to use xpath for cache info, providing better performance.\\nPlease delete the existing cache and rebuild it. Sorry for the inconvenience.\\ncache file: ${cacheFile}`,\n );\n return undefined;\n }\n\n debug(\n 'cache loaded from file, path: %s, cache version: %s, record length: %s',\n cacheFile,\n jsonData.rpasceneVersion,\n jsonData.caches.length,\n );\n jsonData.rpasceneVersion = getRpasceneVersion(); // update the version\n return jsonData;\n } catch (err) {\n debug(\n 'cache file exists but load failed, path: %s, error: %s',\n cacheFile,\n err,\n );\n return undefined;\n }\n }\n\n flushCacheToFile(options?: { cleanUnused?: boolean }) {\n const version = getRpasceneVersion();\n if (!version) {\n debug('no rpascene version info, will not write cache to file');\n return;\n }\n\n if (!this.cacheFilePath) {\n debug('no cache file path, will not write cache to file');\n return;\n }\n\n // Clean unused caches if requested\n if (options?.cleanUnused) {\n // Skip cleaning in write-only mode or when cache is not used\n if (this.isCacheResultUsed) {\n const originalLength = this.cache.caches.length;\n\n // Collect indices of used caches\n const usedIndices = new Set<number>();\n for (const key of this.matchedCacheIndices) {\n // key format: \"type:prompt:index\"\n const parts = key.split(':');\n const index = Number.parseInt(parts[parts.length - 1], 10);\n if (!Number.isNaN(index)) {\n usedIndices.add(index);\n }\n }\n\n // Filter: keep used caches and newly added caches\n this.cache.caches = this.cache.caches.filter((_, index) => {\n const isUsed = usedIndices.has(index);\n const isNew = index >= this.cacheOriginalLength;\n return isUsed || isNew;\n });\n\n const removedCount = originalLength - this.cache.caches.length;\n if (removedCount > 0) {\n debug('cleaned %d unused cache record(s)', removedCount);\n } else {\n debug('no unused cache to clean');\n }\n } else {\n debug('skip cleaning: cache is not used for reading');\n }\n }\n\n try {\n const dir = dirname(this.cacheFilePath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n debug('created cache directory: %s', dir);\n }\n\n // Sort caches to ensure plan entries come before locate entries for better readability\n // Create a sorted copy for writing to disk while keeping in-memory order unchanged\n const sortedCaches = [...this.cache.caches].sort((a, b) => {\n if (a.type === 'plan' && b.type === 'locate') return -1;\n if (a.type === 'locate' && b.type === 'plan') return 1;\n return 0;\n });\n\n const cacheToWrite = {\n ...this.cache,\n caches: sortedCaches,\n };\n\n const yamlData = yaml.dump(cacheToWrite);\n writeFileSync(this.cacheFilePath, yamlData);\n debug('cache flushed to file: %s', this.cacheFilePath);\n } catch (err) {\n debug(\n 'write cache to file failed, path: %s, error: %s',\n this.cacheFilePath,\n err,\n );\n }\n }\n\n updateOrAppendCacheRecord(\n newRecord: PlanningCache | LocateCache,\n cachedRecord?: MatchCacheResult<PlanningCache | LocateCache>,\n ) {\n if (cachedRecord) {\n // update existing record\n if (newRecord.type === 'plan') {\n cachedRecord.updateFn((cache) => {\n (cache as PlanningCache).yamlWorkflow = newRecord.yamlWorkflow;\n });\n } else {\n cachedRecord.updateFn((cache) => {\n const locateCache = cache as LocateCache;\n locateCache.cache = newRecord.cache;\n if ('xpaths' in locateCache) {\n locateCache.xpaths = undefined;\n }\n });\n }\n } else {\n this.appendCache(newRecord);\n }\n }\n}\n"],"names":["DEFAULT_CACHE_MAX_FILENAME_LENGTH","debug","getDebug","lowestSupportedRpasceneVersion","cacheFileExt","TaskCache","prompt","type","i","item","promptStr","JSON","key","isDeepStrictEqual","locateItem","Array","undefined","cb","cache","cacheFile","assert","existsSync","jsonTypeCacheFile","console","data","readFileSync","jsonData","yaml","version","getRpasceneVersion","semver","err","options","originalLength","usedIndices","Set","parts","index","Number","_","isUsed","isNew","removedCount","dir","dirname","mkdirSync","sortedCaches","a","b","cacheToWrite","yamlData","writeFileSync","newRecord","cachedRecord","locateCache","cacheId","isCacheResultUsed","cacheFilePath","safeCacheId","replaceIllegalPathCharsAndSpace","cacheMaxFilenameLength","globalConfigManager","MIDSCENE_CACHE_MAX_FILENAME_LENGTH","Buffer","prefix","hash","generateHashId","ifInBrowser","ifInWorker","join","getRpasceneRunSubDir","readOnlyMode","Boolean","writeOnlyMode","Error","cacheContent"],"mappings":"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"}
@@ -81,7 +81,7 @@ class TaskExecutor {
81
81
  thought: plan.thought,
82
82
  executor: async (param, taskContext)=>{
83
83
  var _this_taskCache, _locateCacheRecord_cacheContent;
84
- const { task } = taskContext;
84
+ const { task, abortSignal } = taskContext;
85
85
  assert((null == param ? void 0 : param.prompt) || (null == param ? void 0 : param.id) || (null == param ? void 0 : param.bbox), `No prompt or id or position or bbox to locate, param=${JSON.stringify(param)}`);
86
86
  let insightDump;
87
87
  let usage;
@@ -119,7 +119,7 @@ class TaskExecutor {
119
119
  const planHitFlag = !!elementFromPlan;
120
120
  const elementFromAiLocate = userExpectedPathHitFlag || cacheHitFlag || planHitFlag ? void 0 : (await this.insight.locate(param, {
121
121
  context: uiContext
122
- }, modelConfig)).element;
122
+ }, modelConfig, abortSignal)).element;
123
123
  const aiLocateHitFlag = !!elementFromAiLocate;
124
124
  const element = elementFromXpath || elementFromCache || elementFromPlan || elementFromAiLocate;
125
125
  if (this.interface.getElementFromPoint && element.center) try {
@@ -465,44 +465,21 @@ class TaskExecutor {
465
465
  getReplanningCycleLimit(isVlmUiTars) {
466
466
  return this.replanningCycleLimit || globalConfigManager.getEnvConfigInNumber(MIDSCENE_REPLANNING_CYCLE_LIMIT) || (isVlmUiTars ? defaultVlmUiTarsReplanningCycleLimit : defaultReplanningCycleLimit);
467
467
  }
468
- cancelPlanning() {
469
- var _this_abortController;
470
- console.log("\u53D6\u6D88\u6267\u884C\u89C4\u5212");
471
- this.isPlanning = false;
472
- null == (_this_abortController = this.abortController) || _this_abortController.abort();
473
- }
474
- cleanupPlanning() {
475
- var _this_abortController;
476
- null == (_this_abortController = this.abortController) || _this_abortController.abort();
477
- this.isPlanning = false;
478
- }
479
- isActive() {
480
- return this.isPlanning;
481
- }
482
- async action(userPrompt, modelConfig, actionContext, cacheable) {
483
- console.log(actionContext, 'actionContext--------------');
484
- if (this.isPlanning) {
485
- var _this_abortController;
486
- console.warn('Executor is already running');
487
- null == (_this_abortController = this.abortController) || _this_abortController.abort();
488
- }
468
+ async action(userPrompt, modelConfig, actionContext, cacheable, abortSignal) {
489
469
  this.conversationHistory.reset();
490
470
  const userPromptList = userPrompt.split('\n').map((item)=>item.trim()).filter(Boolean);
491
471
  let nextPrompt = userPromptList.shift();
492
- const abortController = new AbortController();
493
- this.abortController = abortController;
494
472
  const taskExecutor = new Executor(taskTitleStr('Action', userPrompt), {
495
473
  onTaskStart: this.onTaskStartCallback,
496
- signal: abortController.signal
474
+ abortSignal
497
475
  });
498
- this.isPlanning = true;
499
476
  let replanCount = 0;
500
477
  const yamlFlow = [];
501
478
  const replanningCycleLimit = this.getReplanningCycleLimit('vlm-ui-tars' === modelConfig.vlMode);
502
- while(this.isPlanning && nextPrompt){
479
+ while(nextPrompt){
503
480
  var _result_output;
504
481
  console.log('action while running', nextPrompt);
505
- if (abortController.signal.aborted) return {
482
+ if (null == abortSignal ? void 0 : abortSignal.aborted) return {
506
483
  output: void 0,
507
484
  executor: taskExecutor
508
485
  };
@@ -515,14 +492,10 @@ class TaskExecutor {
515
492
  const result = await taskExecutor.flush();
516
493
  console.dir(null == result ? void 0 : null == (_result_output = result.output) ? void 0 : _result_output.actions, 'result?.output?.actions');
517
494
  const planResult = null == result ? void 0 : result.output;
518
- console.log('more_actions_needed_by_instruction:', null == planResult ? void 0 : planResult.more_actions_needed_by_instruction);
519
- if (taskExecutor.isInErrorState()) {
520
- this.cleanupPlanning();
521
- return {
522
- output: planResult,
523
- executor: taskExecutor
524
- };
525
- }
495
+ if (taskExecutor.isInErrorState()) return {
496
+ output: planResult,
497
+ executor: taskExecutor
498
+ };
526
499
  const plans = (null == planResult ? void 0 : planResult.actions) || [];
527
500
  yamlFlow.push(...(null == planResult ? void 0 : planResult.yamlFlow) || []);
528
501
  let executables;
@@ -530,17 +503,13 @@ class TaskExecutor {
530
503
  executables = await this.convertPlanToExecutable(plans, modelConfig, cacheable);
531
504
  taskExecutor.append(executables.tasks);
532
505
  } catch (error) {
533
- this.cleanupPlanning();
534
506
  return this.appendErrorPlan(taskExecutor, `Error converting plans to executable tasks: ${error}, plans: ${JSON.stringify(plans)}`, modelConfig);
535
507
  }
536
508
  await taskExecutor.flush();
537
- if (taskExecutor.isInErrorState()) {
538
- this.cleanupPlanning();
539
- return {
540
- output: void 0,
541
- executor: taskExecutor
542
- };
543
- }
509
+ if (taskExecutor.isInErrorState()) return {
510
+ output: void 0,
511
+ executor: taskExecutor
512
+ };
544
513
  if (null == planResult ? void 0 : planResult.more_actions_needed_by_instruction) replanCount++;
545
514
  else {
546
515
  this.conversationHistory.reset();
@@ -548,7 +517,6 @@ class TaskExecutor {
548
517
  replanCount = 0;
549
518
  }
550
519
  }
551
- this.cleanupPlanning();
552
520
  return {
553
521
  output: {
554
522
  yamlFlow
@@ -711,7 +679,6 @@ class TaskExecutor {
711
679
  _define_property(this, "onTaskStartCallback", void 0);
712
680
  _define_property(this, "replanningCycleLimit", void 0);
713
681
  _define_property(this, "isPlanning", false);
714
- _define_property(this, "abortController", null);
715
682
  this.interface = interfaceInstance;
716
683
  this.insight = insight;
717
684
  this.taskCache = opts.taskCache;