@midscene/core 0.28.1-beta-20250909024808.0 → 0.28.1-beta-20250909063633.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/es/agent/agent.mjs +4 -2
  2. package/dist/es/agent/agent.mjs.map +1 -1
  3. package/dist/es/agent/index.mjs +2 -2
  4. package/dist/es/agent/tasks.mjs +30 -14
  5. package/dist/es/agent/tasks.mjs.map +1 -1
  6. package/dist/es/agent/utils.mjs +1 -1
  7. package/dist/es/ai-model/prompt/llm-planning.mjs +1 -2
  8. package/dist/es/ai-model/prompt/llm-planning.mjs.map +1 -1
  9. package/dist/es/index.mjs +2 -2
  10. package/dist/es/index.mjs.map +1 -1
  11. package/dist/es/types.mjs.map +1 -1
  12. package/dist/es/utils.mjs +2 -2
  13. package/dist/es/yaml/player.mjs +9 -4
  14. package/dist/es/yaml/player.mjs.map +1 -1
  15. package/dist/es/yaml/utils.mjs +1 -9
  16. package/dist/es/yaml/utils.mjs.map +1 -1
  17. package/dist/lib/agent/agent.js +8 -3
  18. package/dist/lib/agent/agent.js.map +1 -1
  19. package/dist/lib/agent/index.js +3 -0
  20. package/dist/lib/agent/tasks.js +30 -14
  21. package/dist/lib/agent/tasks.js.map +1 -1
  22. package/dist/lib/agent/utils.js +1 -1
  23. package/dist/lib/ai-model/prompt/llm-planning.js +1 -2
  24. package/dist/lib/ai-model/prompt/llm-planning.js.map +1 -1
  25. package/dist/lib/index.js +3 -0
  26. package/dist/lib/index.js.map +1 -1
  27. package/dist/lib/types.js.map +1 -1
  28. package/dist/lib/utils.js +2 -2
  29. package/dist/lib/yaml/player.js +9 -4
  30. package/dist/lib/yaml/player.js.map +1 -1
  31. package/dist/lib/yaml/utils.js +1 -9
  32. package/dist/lib/yaml/utils.js.map +1 -1
  33. package/dist/types/agent/agent.d.ts +8 -15
  34. package/dist/types/agent/index.d.ts +2 -1
  35. package/dist/types/index.d.ts +1 -1
  36. package/dist/types/types.d.ts +16 -0
  37. package/dist/types/yaml/utils.d.ts +1 -1
  38. package/dist/types/yaml.d.ts +13 -5
  39. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"agent/tasks.mjs","sources":["webpack://@midscene/core/./src/agent/tasks.ts"],"sourcesContent":["import {\n type ChatCompletionMessageParam,\n elementByPositionWithElementInfo,\n findAllMidsceneLocatorField,\n resizeImageForUiTars,\n vlmPlanning,\n} from '@/ai-model';\nimport type { AbstractInterface } from '@/device';\nimport {\n type AIUsageInfo,\n type BaseElement,\n type DetailedLocateParam,\n type DumpSubscriber,\n type ExecutionRecorderItem,\n type ExecutionTaskActionApply,\n type ExecutionTaskApply,\n type ExecutionTaskHitBy,\n type ExecutionTaskInsightLocateApply,\n type ExecutionTaskInsightQueryApply,\n type ExecutionTaskPlanning,\n type ExecutionTaskPlanningApply,\n type ExecutionTaskProgressOptions,\n Executor,\n type ExecutorContext,\n type Insight,\n type InsightDump,\n type InsightExtractOption,\n type InsightExtractParam,\n type InterfaceType,\n type LocateResultElement,\n type MidsceneYamlFlowItem,\n type PlanningAIResponse,\n type PlanningAction,\n type PlanningActionParamError,\n type PlanningActionParamSleep,\n type PlanningActionParamWaitFor,\n type PlanningLocateParam,\n type TMultimodalPrompt,\n type TUserPrompt,\n type UIContext,\n plan,\n} from '@/index';\nimport { sleep } from '@/utils';\nimport { NodeType } from '@midscene/shared/constants';\nimport {\n type IModelPreferences,\n MIDSCENE_REPLANNING_CYCLE_LIMIT,\n globalConfigManager,\n} from '@midscene/shared/env';\nimport { getDebug } from '@midscene/shared/logger';\nimport { assert } from '@midscene/shared/utils';\nimport type { TaskCache } from './task-cache';\nimport { taskTitleStr } from './ui-utils';\nimport {\n matchElementFromCache,\n matchElementFromPlan,\n parsePrompt,\n} from './utils';\n\ninterface ExecutionResult<OutputType = any> {\n output: OutputType;\n thought?: string;\n executor: Executor;\n}\n\nconst debug = getDebug('device-task-executor');\nconst defaultReplanningCycleLimit = 10;\n\nexport function locatePlanForLocate(param: string | DetailedLocateParam) {\n const locate = typeof param === 'string' ? { prompt: param } : param;\n const locatePlan: PlanningAction<PlanningLocateParam> = {\n type: 'Locate',\n locate,\n param: locate,\n thought: '',\n };\n return locatePlan;\n}\n\nexport class TaskExecutor {\n interface: AbstractInterface;\n\n insight: Insight;\n\n taskCache?: TaskCache;\n\n conversationHistory: ChatCompletionMessageParam[] = [];\n\n onTaskStartCallback?: ExecutionTaskProgressOptions['onTaskStart'];\n\n // @deprecated use .interface instead\n get page() {\n return this.interface;\n }\n\n constructor(\n interfaceInstance: AbstractInterface,\n insight: Insight,\n opts: {\n taskCache?: TaskCache;\n onTaskStart?: ExecutionTaskProgressOptions['onTaskStart'];\n },\n ) {\n this.interface = interfaceInstance;\n this.insight = insight;\n this.taskCache = opts.taskCache;\n this.onTaskStartCallback = opts?.onTaskStart;\n }\n\n private async recordScreenshot(timing: ExecutionRecorderItem['timing']) {\n const base64 = await this.interface.screenshotBase64();\n const item: ExecutionRecorderItem = {\n type: 'screenshot',\n ts: Date.now(),\n screenshot: base64,\n timing,\n };\n return item;\n }\n\n private async getElementXpath(\n uiContext: UIContext<BaseElement>,\n element: LocateResultElement,\n ): Promise<string[] | undefined> {\n if (!(this.interface as any).getXpathsByPoint) {\n debug('getXpathsByPoint is not supported for this interface');\n return undefined;\n }\n\n let elementId = element?.id;\n if (element?.isOrderSensitive !== undefined) {\n try {\n const xpaths = await (this.interface as any).getXpathsByPoint(\n {\n left: element.center[0],\n top: element.center[1],\n },\n element?.isOrderSensitive,\n );\n\n return xpaths;\n } catch (error) {\n debug('getXpathsByPoint failed: %s', error);\n return undefined;\n }\n }\n\n // find the nearest xpath for the element\n if (element?.attributes?.nodeType === NodeType.POSITION) {\n await this.insight.contextRetrieverFn('locate');\n const info = elementByPositionWithElementInfo(\n uiContext.tree,\n {\n x: element.center[0],\n y: element.center[1],\n },\n {\n requireStrictDistance: false,\n filterPositionElements: true,\n },\n );\n if (info?.id) {\n elementId = info.id;\n } else {\n debug(\n 'no element id found for position node, will not update cache',\n element,\n );\n }\n }\n\n if (!elementId) {\n return undefined;\n }\n try {\n const result = await (this.interface as any).getXpathsById(elementId);\n return result;\n } catch (error) {\n debug('getXpathsById error: ', error);\n }\n }\n\n private prependExecutorWithScreenshot(\n taskApply: ExecutionTaskApply,\n appendAfterExecution = false,\n ): ExecutionTaskApply {\n const taskWithScreenshot: ExecutionTaskApply = {\n ...taskApply,\n executor: async (param, context, ...args) => {\n const recorder: ExecutionRecorderItem[] = [];\n const { task } = context;\n // set the recorder before executor in case of error\n task.recorder = recorder;\n const shot = await this.recordScreenshot(`before ${task.type}`);\n recorder.push(shot);\n\n const result = await taskApply.executor(param, context, ...args);\n\n if (appendAfterExecution) {\n const shot2 = await this.recordScreenshot('after Action');\n recorder.push(shot2);\n }\n return result;\n },\n };\n return taskWithScreenshot;\n }\n\n public async convertPlanToExecutable(plans: PlanningAction[]) {\n const tasks: ExecutionTaskApply[] = [];\n\n const taskForLocatePlan = (\n plan: PlanningAction<PlanningLocateParam>,\n detailedLocateParam: DetailedLocateParam | string,\n onResult?: (result: LocateResultElement) => void,\n ): ExecutionTaskInsightLocateApply => {\n if (typeof detailedLocateParam === 'string') {\n detailedLocateParam = {\n prompt: detailedLocateParam,\n };\n }\n const taskFind: ExecutionTaskInsightLocateApply = {\n type: 'Insight',\n subType: 'Locate',\n param: detailedLocateParam,\n thought: plan.thought,\n executor: async (param, taskContext) => {\n const { task } = taskContext;\n assert(\n param?.prompt || param?.id || param?.bbox,\n `No prompt or id or position or bbox to locate, param=${JSON.stringify(\n param,\n )}`,\n );\n let insightDump: InsightDump | undefined;\n let usage: AIUsageInfo | undefined;\n const dumpCollector: DumpSubscriber = (dump) => {\n insightDump = dump;\n usage = dump?.taskInfo?.usage;\n\n task.log = {\n dump: insightDump,\n };\n\n task.usage = usage;\n };\n this.insight.onceDumpUpdatedFn = dumpCollector;\n const shotTime = Date.now();\n\n // Get context through contextRetrieverFn which handles frozen context\n const uiContext = await this.insight.contextRetrieverFn('locate');\n task.uiContext = uiContext;\n\n const recordItem: ExecutionRecorderItem = {\n type: 'screenshot',\n ts: shotTime,\n screenshot: uiContext.screenshotBase64,\n timing: 'before Insight',\n };\n task.recorder = [recordItem];\n\n // try matching xpath\n const elementFromXpath =\n param.xpath && (this.interface as any).getElementInfoByXpath\n ? await (this.interface as any).getElementInfoByXpath(param.xpath)\n : undefined;\n const userExpectedPathHitFlag = !!elementFromXpath;\n\n // try matching cache\n const cachePrompt = param.prompt;\n const locateCacheRecord =\n this.taskCache?.matchLocateCache(cachePrompt);\n const xpaths = locateCacheRecord?.cacheContent?.xpaths;\n const elementFromCache = userExpectedPathHitFlag\n ? null\n : await matchElementFromCache(\n this,\n xpaths,\n cachePrompt,\n param.cacheable,\n );\n const cacheHitFlag = !!elementFromCache;\n\n // try matching plan\n const elementFromPlan =\n !userExpectedPathHitFlag && !cacheHitFlag\n ? matchElementFromPlan(param, uiContext.tree)\n : undefined;\n const planHitFlag = !!elementFromPlan;\n\n // try ai locate\n const elementFromAiLocate =\n !userExpectedPathHitFlag && !cacheHitFlag && !planHitFlag\n ? (\n await this.insight.locate(param, {\n // fallback to ai locate\n context: uiContext,\n })\n ).element\n : undefined;\n const aiLocateHitFlag = !!elementFromAiLocate;\n\n const element =\n elementFromXpath || // highest priority\n elementFromCache || // second priority\n elementFromPlan || // third priority\n elementFromAiLocate;\n\n // update cache\n let currentXpaths: string[] | undefined;\n if (\n element &&\n this.taskCache &&\n !cacheHitFlag &&\n param?.cacheable !== false\n ) {\n const elementXpaths = await this.getElementXpath(\n uiContext,\n element,\n );\n if (elementXpaths?.length) {\n currentXpaths = elementXpaths;\n this.taskCache.updateOrAppendCacheRecord(\n {\n type: 'locate',\n prompt: cachePrompt,\n xpaths: elementXpaths,\n },\n locateCacheRecord,\n );\n } else {\n debug(\n 'no xpaths found, will not update cache',\n cachePrompt,\n elementXpaths,\n );\n }\n }\n if (!element) {\n throw new Error(`Element not found: ${param.prompt}`);\n }\n\n let hitBy: ExecutionTaskHitBy | undefined;\n\n if (userExpectedPathHitFlag) {\n hitBy = {\n from: 'User expected path',\n context: {\n xpath: param.xpath,\n },\n };\n } else if (cacheHitFlag) {\n hitBy = {\n from: 'Cache',\n context: {\n xpathsFromCache: xpaths,\n xpathsToSave: currentXpaths,\n },\n };\n } else if (planHitFlag) {\n hitBy = {\n from: 'Planning',\n context: {\n id: elementFromPlan?.id,\n bbox: elementFromPlan?.bbox,\n },\n };\n } else if (aiLocateHitFlag) {\n hitBy = {\n from: 'AI model',\n context: {\n prompt: param.prompt,\n },\n };\n }\n\n onResult?.(element);\n\n return {\n output: {\n element,\n },\n uiContext,\n hitBy,\n };\n },\n };\n return taskFind;\n };\n\n for (const plan of plans) {\n if (plan.type === 'Locate') {\n if (\n !plan.locate ||\n plan.locate === null ||\n plan.locate?.id === null ||\n plan.locate?.id === 'null'\n ) {\n debug('Locate action with id is null, will be ignored', plan);\n continue;\n }\n const taskLocate = taskForLocatePlan(plan, plan.locate);\n\n tasks.push(taskLocate);\n } else if (plan.type === 'Error') {\n const taskActionError: ExecutionTaskActionApply<PlanningActionParamError> =\n {\n type: 'Action',\n subType: 'Error',\n param: plan.param,\n thought: plan.thought || plan.param?.thought,\n locate: plan.locate,\n executor: async () => {\n throw new Error(\n plan?.thought || plan.param?.thought || 'error without thought',\n );\n },\n };\n tasks.push(taskActionError);\n } else if (plan.type === 'Finished') {\n const taskActionFinished: ExecutionTaskActionApply<null> = {\n type: 'Action',\n subType: 'Finished',\n param: null,\n thought: plan.thought,\n locate: plan.locate,\n executor: async (param) => {},\n };\n tasks.push(taskActionFinished);\n } else if (plan.type === 'Sleep') {\n const taskActionSleep: ExecutionTaskActionApply<PlanningActionParamSleep> =\n {\n type: 'Action',\n subType: 'Sleep',\n param: plan.param,\n thought: plan.thought,\n locate: plan.locate,\n executor: async (taskParam) => {\n await sleep(taskParam?.timeMs || 3000);\n },\n };\n tasks.push(taskActionSleep);\n } else {\n // action in action space\n const planType = plan.type;\n const actionSpace = await this.interface.actionSpace();\n const action = actionSpace.find((action) => action.name === planType);\n const param = plan.param;\n\n if (!action) {\n throw new Error(`Action type '${planType}' not found`);\n }\n\n // find all params that needs location\n const locateFields = action\n ? findAllMidsceneLocatorField(action.paramSchema)\n : [];\n\n const requiredLocateFields = action\n ? findAllMidsceneLocatorField(action.paramSchema, true)\n : [];\n\n locateFields.forEach((field) => {\n if (param[field]) {\n const locatePlan = locatePlanForLocate(param[field]);\n debug(\n 'will prepend locate param for field',\n `action.type=${planType}`,\n `param=${JSON.stringify(param[field])}`,\n `locatePlan=${JSON.stringify(locatePlan)}`,\n );\n const locateTask = taskForLocatePlan(\n locatePlan,\n param[field],\n (result) => {\n param[field] = result;\n },\n );\n tasks.push(locateTask);\n } else {\n assert(\n !requiredLocateFields.includes(field),\n `Required locate field '${field}' is not provided for action ${planType}`,\n );\n debug(`field '${field}' is not provided for action ${planType}`);\n }\n });\n\n const task: ExecutionTaskApply<\n 'Action',\n any,\n { success: boolean; action: string; param: any },\n void\n > = {\n type: 'Action',\n subType: planType,\n thought: plan.thought,\n param: plan.param,\n executor: async (param, context) => {\n debug(\n 'executing action',\n planType,\n param,\n `context.element.center: ${context.element?.center}`,\n );\n\n // Get context for actionSpace operations to ensure size info is available\n const uiContext = await this.insight.contextRetrieverFn('locate');\n context.task.uiContext = uiContext;\n\n requiredLocateFields.forEach((field) => {\n assert(\n param[field],\n `field '${field}' is required for action ${planType} but not provided. Cannot execute action ${planType}.`,\n );\n });\n\n await Promise.all([\n (async () => {\n if (this.interface.beforeInvokeAction) {\n debug('will call \"beforeInvokeAction\" for interface');\n await this.interface.beforeInvokeAction(action.name, param);\n debug('called \"beforeInvokeAction\" for interface');\n }\n })(),\n sleep(200),\n ]);\n\n const actionFn = action.call.bind(this.interface);\n await actionFn(param, context);\n\n if (this.interface.afterInvokeAction) {\n debug('will call \"afterInvokeAction\" for interface');\n await this.interface.afterInvokeAction(action.name, param);\n debug('called \"afterInvokeAction\" for interface');\n }\n // Return a proper result for report generation\n return {\n output: {\n success: true,\n action: planType,\n param: param,\n },\n };\n },\n };\n tasks.push(task);\n }\n }\n\n const wrappedTasks = tasks.map(\n (task: ExecutionTaskApply, index: number) => {\n if (task.type === 'Action') {\n return this.prependExecutorWithScreenshot(\n task,\n index === tasks.length - 1,\n );\n }\n return task;\n },\n );\n\n return {\n tasks: wrappedTasks,\n };\n }\n\n private async setupPlanningContext(executorContext: ExecutorContext) {\n const shotTime = Date.now();\n const uiContext = await this.insight.contextRetrieverFn('locate');\n const recordItem: ExecutionRecorderItem = {\n type: 'screenshot',\n ts: shotTime,\n screenshot: uiContext.screenshotBase64,\n timing: 'before Planning',\n };\n\n executorContext.task.recorder = [recordItem];\n (executorContext.task as ExecutionTaskPlanning).uiContext = uiContext;\n\n return {\n uiContext,\n };\n }\n\n async loadYamlFlowAsPlanning(userInstruction: string, yamlString: string) {\n const taskExecutor = new Executor(taskTitleStr('Action', userInstruction), {\n onTaskStart: this.onTaskStartCallback,\n });\n\n const task: ExecutionTaskPlanningApply = {\n type: 'Planning',\n subType: 'LoadYaml',\n locate: null,\n param: {\n userInstruction,\n },\n executor: async (param, executorContext) => {\n await this.setupPlanningContext(executorContext);\n return {\n output: {\n actions: [],\n more_actions_needed_by_instruction: false,\n log: '',\n yamlString,\n },\n cache: {\n hit: true,\n },\n hitBy: {\n from: 'Cache',\n context: {\n yamlString,\n },\n },\n };\n },\n };\n\n await taskExecutor.append(task);\n await taskExecutor.flush();\n\n return {\n executor: taskExecutor,\n };\n }\n\n private planningTaskFromPrompt(\n userInstruction: string,\n log?: string,\n actionContext?: string,\n ) {\n const task: ExecutionTaskPlanningApply = {\n type: 'Planning',\n subType: 'Plan',\n locate: null,\n param: {\n userInstruction,\n log,\n },\n executor: async (param, executorContext) => {\n const startTime = Date.now();\n const { uiContext } = await this.setupPlanningContext(executorContext);\n\n assert(\n this.interface.actionSpace,\n 'actionSpace for device is not implemented',\n );\n const actionSpace = await this.interface.actionSpace();\n debug(\n 'actionSpace for this interface is:',\n actionSpace.map((action) => action.name).join(', '),\n );\n assert(Array.isArray(actionSpace), 'actionSpace must be an array');\n if (actionSpace.length === 0) {\n console.warn(\n `ActionSpace for ${this.interface.interfaceType} is empty. This may lead to unexpected behavior.`,\n );\n }\n\n const planResult = await plan(param.userInstruction, {\n context: uiContext,\n log: param.log,\n actionContext,\n interfaceType: this.interface.interfaceType as InterfaceType,\n actionSpace,\n });\n\n const {\n actions,\n log,\n more_actions_needed_by_instruction,\n error,\n usage,\n rawResponse,\n sleep,\n } = planResult;\n\n executorContext.task.log = {\n ...(executorContext.task.log || {}),\n rawResponse,\n };\n executorContext.task.usage = usage;\n\n const finalActions = actions || [];\n\n // TODO: check locate result\n // let bboxCollected = false;\n // (actions || []).reduce<PlanningAction[]>(\n // (acc, planningAction) => {\n // // TODO: magic field \"locate\" is used to indicate the action requires a locate\n // if (planningAction.locate) {\n // // we only collect bbox once, let qwen re-locate in the following steps\n // if (bboxCollected && planningAction.locate.bbox) {\n // // biome-ignore lint/performance/noDelete: <explanation>\n // delete planningAction.locate.bbox;\n // }\n\n // if (planningAction.locate.bbox) {\n // bboxCollected = true;\n // }\n\n // acc.push({\n // type: 'Locate',\n // locate: planningAction.locate,\n // param: null,\n // // thought is prompt created by ai, always a string\n // thought: planningAction.locate.prompt as string,\n // });\n // }\n // acc.push(planningAction);\n // return acc;\n // },\n // [],\n // );\n\n if (sleep) {\n const timeNow = Date.now();\n const timeRemaining = sleep - (timeNow - startTime);\n if (timeRemaining > 0) {\n finalActions.push({\n type: 'Sleep',\n param: {\n timeMs: timeRemaining,\n },\n locate: null,\n } as PlanningAction<PlanningActionParamSleep>);\n }\n }\n\n if (finalActions.length === 0) {\n assert(\n !more_actions_needed_by_instruction || sleep,\n error ? `Failed to plan: ${error}` : 'No plan found',\n );\n }\n\n return {\n output: {\n actions: finalActions,\n more_actions_needed_by_instruction,\n log,\n yamlFlow: planResult.yamlFlow,\n },\n cache: {\n hit: false,\n },\n uiContext,\n };\n },\n };\n\n return task;\n }\n\n private planningTaskToGoal(\n userInstruction: string,\n modelPreferences: IModelPreferences,\n ) {\n const task: ExecutionTaskPlanningApply = {\n type: 'Planning',\n subType: 'Plan',\n locate: null,\n param: {\n userInstruction,\n },\n executor: async (param, executorContext) => {\n const { uiContext } = await this.setupPlanningContext(executorContext);\n\n const imagePayload = await resizeImageForUiTars(\n uiContext.screenshotBase64,\n uiContext.size,\n modelPreferences,\n );\n\n this.appendConversationHistory({\n role: 'user',\n content: [\n {\n type: 'image_url',\n image_url: {\n url: imagePayload,\n },\n },\n ],\n });\n const planResult: {\n actions: PlanningAction<any>[];\n action_summary: string;\n usage?: AIUsageInfo;\n yamlFlow?: MidsceneYamlFlowItem[];\n rawResponse?: string;\n } = await vlmPlanning({\n userInstruction: param.userInstruction,\n conversationHistory: this.conversationHistory,\n size: uiContext.size,\n modelPreferences,\n });\n\n const { actions, action_summary, usage } = planResult;\n executorContext.task.log = {\n ...(executorContext.task.log || {}),\n rawResponse: planResult.rawResponse,\n };\n executorContext.task.usage = usage;\n this.appendConversationHistory({\n role: 'assistant',\n content: action_summary,\n });\n return {\n output: {\n actions,\n thought: actions[0]?.thought,\n actionType: actions[0].type,\n more_actions_needed_by_instruction: true,\n log: '',\n yamlFlow: planResult.yamlFlow,\n },\n cache: {\n hit: false,\n },\n };\n },\n };\n\n return task;\n }\n\n async runPlans(\n title: string,\n plans: PlanningAction[],\n ): Promise<ExecutionResult> {\n const taskExecutor = new Executor(title, {\n onTaskStart: this.onTaskStartCallback,\n });\n const { tasks } = await this.convertPlanToExecutable(plans);\n await taskExecutor.append(tasks);\n const result = await taskExecutor.flush();\n const { output } = result!;\n return {\n output,\n executor: taskExecutor,\n };\n }\n\n async action(\n userPrompt: string,\n actionContext?: string,\n ): Promise<\n ExecutionResult<\n | {\n yamlFlow?: MidsceneYamlFlowItem[]; // for cache use\n }\n | undefined\n >\n > {\n const taskExecutor = new Executor(taskTitleStr('Action', userPrompt), {\n onTaskStart: this.onTaskStartCallback,\n });\n\n let planningTask: ExecutionTaskPlanningApply | null =\n this.planningTaskFromPrompt(userPrompt, undefined, actionContext);\n let replanCount = 0;\n const logList: string[] = [];\n\n const yamlFlow: MidsceneYamlFlowItem[] = [];\n const replanningCycleLimit =\n globalConfigManager.getEnvConfigInNumber(\n MIDSCENE_REPLANNING_CYCLE_LIMIT,\n ) || defaultReplanningCycleLimit;\n while (planningTask) {\n if (replanCount > replanningCycleLimit) {\n const errorMsg =\n 'Replanning too many times, please split the task into multiple steps';\n\n return this.appendErrorPlan(taskExecutor, errorMsg);\n }\n\n // plan\n await taskExecutor.append(planningTask);\n const result = await taskExecutor.flush();\n const planResult: PlanningAIResponse = result?.output;\n if (taskExecutor.isInErrorState()) {\n return {\n output: planResult,\n executor: taskExecutor,\n };\n }\n\n const plans = planResult.actions || [];\n yamlFlow.push(...(planResult.yamlFlow || []));\n\n let executables: Awaited<ReturnType<typeof this.convertPlanToExecutable>>;\n try {\n executables = await this.convertPlanToExecutable(plans);\n taskExecutor.append(executables.tasks);\n } catch (error) {\n return this.appendErrorPlan(\n taskExecutor,\n `Error converting plans to executable tasks: ${error}, plans: ${JSON.stringify(\n plans,\n )}`,\n );\n }\n\n await taskExecutor.flush();\n if (taskExecutor.isInErrorState()) {\n return {\n output: undefined,\n executor: taskExecutor,\n };\n }\n if (planResult?.log) {\n logList.push(planResult.log);\n }\n\n if (!planResult.more_actions_needed_by_instruction) {\n planningTask = null;\n break;\n }\n planningTask = this.planningTaskFromPrompt(\n userPrompt,\n logList.length > 0 ? `- ${logList.join('\\n- ')}` : undefined,\n actionContext,\n );\n replanCount++;\n }\n\n return {\n output: {\n yamlFlow,\n },\n executor: taskExecutor,\n };\n }\n\n async actionToGoal(userPrompt: string): Promise<\n ExecutionResult<\n | {\n yamlFlow?: MidsceneYamlFlowItem[]; // for cache use\n }\n | undefined\n >\n > {\n const taskExecutor = new Executor(taskTitleStr('Action', userPrompt), {\n onTaskStart: this.onTaskStartCallback,\n });\n this.conversationHistory = [];\n const isCompleted = false;\n let currentActionCount = 0;\n const maxActionNumber = 40;\n\n const yamlFlow: MidsceneYamlFlowItem[] = [];\n while (!isCompleted && currentActionCount < maxActionNumber) {\n currentActionCount++;\n debug(\n 'actionToGoal, currentActionCount:',\n currentActionCount,\n 'userPrompt:',\n userPrompt,\n );\n const planningTask: ExecutionTaskPlanningApply = this.planningTaskToGoal(\n userPrompt,\n {\n intent: 'planning',\n },\n );\n await taskExecutor.append(planningTask);\n const result = await taskExecutor.flush();\n if (taskExecutor.isInErrorState()) {\n return {\n output: undefined,\n executor: taskExecutor,\n };\n }\n if (!result) {\n throw new Error(\n 'result of taskExecutor.flush() is undefined in function actionToGoal',\n );\n }\n const { output } = result;\n const plans = output.actions;\n yamlFlow.push(...(output.yamlFlow || []));\n let executables: Awaited<ReturnType<typeof this.convertPlanToExecutable>>;\n try {\n executables = await this.convertPlanToExecutable(plans);\n taskExecutor.append(executables.tasks);\n } catch (error) {\n return this.appendErrorPlan(\n taskExecutor,\n `Error converting plans to executable tasks: ${error}, plans: ${JSON.stringify(\n plans,\n )}`,\n );\n }\n\n await taskExecutor.flush();\n\n if (taskExecutor.isInErrorState()) {\n return {\n output: undefined,\n executor: taskExecutor,\n };\n }\n\n if (plans[0].type === 'Finished') {\n break;\n }\n }\n return {\n output: {\n yamlFlow,\n },\n executor: taskExecutor,\n };\n }\n\n private createTypeQueryTask(\n type: 'Query' | 'Boolean' | 'Number' | 'String' | 'Assert',\n demand: InsightExtractParam,\n opt?: InsightExtractOption,\n multimodalPrompt?: TMultimodalPrompt,\n ) {\n const queryTask: ExecutionTaskInsightQueryApply = {\n type: 'Insight',\n subType: type,\n locate: null,\n param: {\n // TODO: display image thumbnail in report\n dataDemand: multimodalPrompt\n ? ({\n demand,\n multimodalPrompt,\n } as never)\n : demand, // for user param presentation in report right sidebar\n },\n executor: async (param, taskContext) => {\n const { task } = taskContext;\n let insightDump: InsightDump | undefined;\n const dumpCollector: DumpSubscriber = (dump) => {\n insightDump = dump;\n };\n this.insight.onceDumpUpdatedFn = dumpCollector;\n\n // Get context for query operations\n const shotTime = Date.now();\n const uiContext = await this.insight.contextRetrieverFn('extract');\n task.uiContext = uiContext;\n\n const recordItem: ExecutionRecorderItem = {\n type: 'screenshot',\n ts: shotTime,\n screenshot: uiContext.screenshotBase64,\n timing: 'before Extract',\n };\n task.recorder = [recordItem];\n\n const ifTypeRestricted = type !== 'Query';\n let demandInput = demand;\n if (ifTypeRestricted) {\n const returnType = type === 'Assert' ? 'Boolean' : type;\n demandInput = {\n result: `${returnType}, ${demand}`,\n };\n }\n\n const { data, usage, thought } = await this.insight.extract<any>(\n demandInput,\n opt,\n multimodalPrompt,\n );\n\n let outputResult = data;\n if (ifTypeRestricted) {\n // If AI returned a plain string instead of structured format, use it directly\n if (typeof data === 'string') {\n outputResult = data;\n } else {\n assert(data?.result !== undefined, 'No result in query data');\n outputResult = (data as any).result;\n }\n }\n\n return {\n output: outputResult,\n log: { dump: insightDump, isWaitForAssert: opt?.isWaitForAssert },\n usage,\n thought,\n };\n },\n };\n\n return queryTask;\n }\n async createTypeQueryExecution<T>(\n type: 'Query' | 'Boolean' | 'Number' | 'String' | 'Assert',\n demand: InsightExtractParam,\n opt?: InsightExtractOption,\n multimodalPrompt?: TMultimodalPrompt,\n ): Promise<ExecutionResult<T>> {\n const taskExecutor = new Executor(\n taskTitleStr(\n type,\n typeof demand === 'string' ? demand : JSON.stringify(demand),\n ),\n {\n onTaskStart: this.onTaskStartCallback,\n },\n );\n\n const queryTask = await this.createTypeQueryTask(\n type,\n demand,\n opt,\n multimodalPrompt,\n );\n\n await taskExecutor.append(this.prependExecutorWithScreenshot(queryTask));\n const result = await taskExecutor.flush();\n\n if (!result) {\n throw new Error(\n 'result of taskExecutor.flush() is undefined in function createTypeQueryTask',\n );\n }\n\n const { output, thought } = result;\n\n return {\n output,\n thought,\n executor: taskExecutor,\n };\n }\n\n async assert(\n assertion: TUserPrompt,\n opt?: InsightExtractOption,\n ): Promise<ExecutionResult<boolean>> {\n const { textPrompt, multimodalPrompt } = parsePrompt(assertion);\n return await this.createTypeQueryExecution<boolean>(\n 'Assert',\n textPrompt,\n opt,\n multimodalPrompt,\n );\n }\n\n /**\n * Append a message to the conversation history\n * For user messages with images:\n * - Keep max 4 user image messages in history\n * - Remove oldest user image message when limit reached\n * For assistant messages:\n * - Simply append to history\n * @param conversationHistory Message to append\n */\n private appendConversationHistory(\n conversationHistory: ChatCompletionMessageParam,\n ) {\n if (conversationHistory.role === 'user') {\n // Get all existing user messages with images\n const userImgItems = this.conversationHistory.filter(\n (item) => item.role === 'user',\n );\n\n // If we already have 4 user image messages\n if (userImgItems.length >= 4 && conversationHistory.role === 'user') {\n // Remove first user image message when we already have 4, before adding new one\n const firstUserImgIndex = this.conversationHistory.findIndex(\n (item) => item.role === 'user',\n );\n if (firstUserImgIndex >= 0) {\n this.conversationHistory.splice(firstUserImgIndex, 1);\n }\n }\n }\n // For non-user messages, simply append to history\n this.conversationHistory.push(conversationHistory);\n }\n\n private async appendErrorPlan(taskExecutor: Executor, errorMsg: string) {\n const errorPlan: PlanningAction<PlanningActionParamError> = {\n type: 'Error',\n param: {\n thought: errorMsg,\n },\n locate: null,\n };\n const { tasks } = await this.convertPlanToExecutable([errorPlan]);\n await taskExecutor.append(this.prependExecutorWithScreenshot(tasks[0]));\n await taskExecutor.flush();\n\n return {\n output: undefined,\n executor: taskExecutor,\n };\n }\n\n async waitFor(\n assertion: TUserPrompt,\n opt: PlanningActionParamWaitFor,\n ): Promise<ExecutionResult<void>> {\n const { textPrompt, multimodalPrompt } = parsePrompt(assertion);\n\n const description = `waitFor: ${textPrompt}`;\n const taskExecutor = new Executor(taskTitleStr('WaitFor', description), {\n onTaskStart: this.onTaskStartCallback,\n });\n const { timeoutMs, checkIntervalMs } = opt;\n\n assert(assertion, 'No assertion for waitFor');\n assert(timeoutMs, 'No timeoutMs for waitFor');\n assert(checkIntervalMs, 'No checkIntervalMs for waitFor');\n\n assert(\n checkIntervalMs <= timeoutMs,\n `wrong config for waitFor: checkIntervalMs must be less than timeoutMs, config: {checkIntervalMs: ${checkIntervalMs}, timeoutMs: ${timeoutMs}}`,\n );\n\n const overallStartTime = Date.now();\n let startTime = Date.now();\n let errorThought = '';\n while (Date.now() - overallStartTime < timeoutMs) {\n startTime = Date.now();\n const queryTask = await this.createTypeQueryTask(\n 'Assert',\n textPrompt,\n {\n isWaitForAssert: true,\n returnThought: true,\n doNotThrowError: true,\n },\n multimodalPrompt,\n );\n\n await taskExecutor.append(this.prependExecutorWithScreenshot(queryTask));\n const result = (await taskExecutor.flush()) as {\n output: boolean;\n thought?: string;\n };\n\n if (!result) {\n throw new Error(\n 'result of taskExecutor.flush() is undefined in function waitFor',\n );\n }\n\n if (result?.output) {\n return {\n output: undefined,\n executor: taskExecutor,\n };\n }\n\n errorThought =\n result?.thought ||\n `unknown error when waiting for assertion: ${textPrompt}`;\n const now = Date.now();\n if (now - startTime < checkIntervalMs) {\n const timeRemaining = checkIntervalMs - (now - startTime);\n const sleepPlan: PlanningAction<PlanningActionParamSleep> = {\n type: 'Sleep',\n param: {\n timeMs: timeRemaining,\n },\n locate: null,\n };\n const { tasks: sleepTasks } = await this.convertPlanToExecutable([\n sleepPlan,\n ]);\n await taskExecutor.append(\n this.prependExecutorWithScreenshot(sleepTasks[0]),\n );\n await taskExecutor.flush();\n }\n }\n\n return this.appendErrorPlan(\n taskExecutor,\n `waitFor timeout: ${errorThought}`,\n );\n }\n}\n"],"names":["debug","getDebug","defaultReplanningCycleLimit","locatePlanForLocate","param","locate","locatePlan","TaskExecutor","timing","base64","item","Date","uiContext","element","_element_attributes","elementId","undefined","xpaths","error","NodeType","info","elementByPositionWithElementInfo","result","taskApply","appendAfterExecution","taskWithScreenshot","context","args","recorder","task","shot","shot2","plans","tasks","taskForLocatePlan","plan","detailedLocateParam","onResult","taskFind","taskContext","_this_taskCache","_locateCacheRecord_cacheContent","assert","JSON","insightDump","usage","dumpCollector","dump","_dump_taskInfo","shotTime","recordItem","elementFromXpath","userExpectedPathHitFlag","cachePrompt","locateCacheRecord","elementFromCache","matchElementFromCache","cacheHitFlag","elementFromPlan","matchElementFromPlan","planHitFlag","elementFromAiLocate","aiLocateHitFlag","currentXpaths","elementXpaths","Error","hitBy","_plan_locate","_plan_locate1","taskLocate","_plan_param","taskActionError","taskActionFinished","taskActionSleep","taskParam","sleep","planType","actionSpace","action","locateFields","findAllMidsceneLocatorField","requiredLocateFields","field","locateTask","_context_element","Promise","actionFn","wrappedTasks","index","executorContext","userInstruction","yamlString","taskExecutor","Executor","taskTitleStr","log","actionContext","startTime","Array","console","planResult","actions","more_actions_needed_by_instruction","rawResponse","finalActions","timeNow","timeRemaining","modelPreferences","_actions_","imagePayload","resizeImageForUiTars","vlmPlanning","action_summary","title","output","userPrompt","planningTask","replanCount","logList","yamlFlow","replanningCycleLimit","globalConfigManager","MIDSCENE_REPLANNING_CYCLE_LIMIT","errorMsg","executables","isCompleted","currentActionCount","maxActionNumber","type","demand","opt","multimodalPrompt","queryTask","ifTypeRestricted","demandInput","returnType","data","thought","outputResult","assertion","textPrompt","parsePrompt","conversationHistory","userImgItems","firstUserImgIndex","errorPlan","description","timeoutMs","checkIntervalMs","overallStartTime","errorThought","now","sleepPlan","sleepTasks","interfaceInstance","insight","opts"],"mappings":"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"}
1
+ {"version":3,"file":"agent/tasks.mjs","sources":["webpack://@midscene/core/./src/agent/tasks.ts"],"sourcesContent":["import {\n type ChatCompletionMessageParam,\n elementByPositionWithElementInfo,\n findAllMidsceneLocatorField,\n resizeImageForUiTars,\n vlmPlanning,\n} from '@/ai-model';\nimport type { AbstractInterface } from '@/device';\nimport {\n type AIUsageInfo,\n type BaseElement,\n type DetailedLocateParam,\n type DumpSubscriber,\n type ExecutionRecorderItem,\n type ExecutionTaskActionApply,\n type ExecutionTaskApply,\n type ExecutionTaskHitBy,\n type ExecutionTaskInsightLocateApply,\n type ExecutionTaskInsightQueryApply,\n type ExecutionTaskPlanning,\n type ExecutionTaskPlanningApply,\n type ExecutionTaskProgressOptions,\n Executor,\n type ExecutorContext,\n type Insight,\n type InsightDump,\n type InsightExtractOption,\n type InsightExtractParam,\n type InterfaceType,\n type LocateResultElement,\n type MidsceneYamlFlowItem,\n type PlanningAIResponse,\n type PlanningAction,\n type PlanningActionParamError,\n type PlanningActionParamSleep,\n type PlanningActionParamWaitFor,\n type PlanningLocateParam,\n type TMultimodalPrompt,\n type TUserPrompt,\n type UIContext,\n plan,\n} from '@/index';\nimport { sleep } from '@/utils';\nimport { NodeType } from '@midscene/shared/constants';\nimport {\n type IModelPreferences,\n MIDSCENE_REPLANNING_CYCLE_LIMIT,\n globalConfigManager,\n} from '@midscene/shared/env';\nimport { getDebug } from '@midscene/shared/logger';\nimport { assert } from '@midscene/shared/utils';\nimport type { TaskCache } from './task-cache';\nimport { taskTitleStr } from './ui-utils';\nimport {\n matchElementFromCache,\n matchElementFromPlan,\n parsePrompt,\n} from './utils';\n\ninterface ExecutionResult<OutputType = any> {\n output: OutputType;\n thought?: string;\n executor: Executor;\n}\n\nconst debug = getDebug('device-task-executor');\nconst defaultReplanningCycleLimit = 10;\n\nexport function locatePlanForLocate(param: string | DetailedLocateParam) {\n const locate = typeof param === 'string' ? { prompt: param } : param;\n const locatePlan: PlanningAction<PlanningLocateParam> = {\n type: 'Locate',\n locate,\n param: locate,\n thought: '',\n };\n return locatePlan;\n}\n\nexport class TaskExecutor {\n interface: AbstractInterface;\n\n insight: Insight;\n\n taskCache?: TaskCache;\n\n conversationHistory: ChatCompletionMessageParam[] = [];\n\n onTaskStartCallback?: ExecutionTaskProgressOptions['onTaskStart'];\n\n // @deprecated use .interface instead\n get page() {\n return this.interface;\n }\n\n constructor(\n interfaceInstance: AbstractInterface,\n insight: Insight,\n opts: {\n taskCache?: TaskCache;\n onTaskStart?: ExecutionTaskProgressOptions['onTaskStart'];\n },\n ) {\n this.interface = interfaceInstance;\n this.insight = insight;\n this.taskCache = opts.taskCache;\n this.onTaskStartCallback = opts?.onTaskStart;\n }\n\n private async recordScreenshot(timing: ExecutionRecorderItem['timing']) {\n const base64 = await this.interface.screenshotBase64();\n const item: ExecutionRecorderItem = {\n type: 'screenshot',\n ts: Date.now(),\n screenshot: base64,\n timing,\n };\n return item;\n }\n\n private async getElementXpath(\n uiContext: UIContext<BaseElement>,\n element: LocateResultElement,\n ): Promise<string[] | undefined> {\n if (!(this.interface as any).getXpathsByPoint) {\n debug('getXpathsByPoint is not supported for this interface');\n return undefined;\n }\n\n let elementId = element?.id;\n if (element?.isOrderSensitive !== undefined) {\n try {\n const xpaths = await (this.interface as any).getXpathsByPoint(\n {\n left: element.center[0],\n top: element.center[1],\n },\n element?.isOrderSensitive,\n );\n\n return xpaths;\n } catch (error) {\n debug('getXpathsByPoint failed: %s', error);\n return undefined;\n }\n }\n\n // find the nearest xpath for the element\n if (element?.attributes?.nodeType === NodeType.POSITION) {\n await this.insight.contextRetrieverFn('locate');\n const info = elementByPositionWithElementInfo(\n uiContext.tree,\n {\n x: element.center[0],\n y: element.center[1],\n },\n {\n requireStrictDistance: false,\n filterPositionElements: true,\n },\n );\n if (info?.id) {\n elementId = info.id;\n } else {\n debug(\n 'no element id found for position node, will not update cache',\n element,\n );\n }\n }\n\n if (!elementId) {\n return undefined;\n }\n try {\n const result = await (this.interface as any).getXpathsById(elementId);\n return result;\n } catch (error) {\n debug('getXpathsById error: ', error);\n }\n }\n\n private prependExecutorWithScreenshot(\n taskApply: ExecutionTaskApply,\n appendAfterExecution = false,\n ): ExecutionTaskApply {\n const taskWithScreenshot: ExecutionTaskApply = {\n ...taskApply,\n executor: async (param, context, ...args) => {\n const recorder: ExecutionRecorderItem[] = [];\n const { task } = context;\n // set the recorder before executor in case of error\n task.recorder = recorder;\n const shot = await this.recordScreenshot(`before ${task.type}`);\n recorder.push(shot);\n\n const result = await taskApply.executor(param, context, ...args);\n\n if (appendAfterExecution) {\n const shot2 = await this.recordScreenshot('after Action');\n recorder.push(shot2);\n }\n return result;\n },\n };\n return taskWithScreenshot;\n }\n\n public async convertPlanToExecutable(plans: PlanningAction[]) {\n const tasks: ExecutionTaskApply[] = [];\n\n const taskForLocatePlan = (\n plan: PlanningAction<PlanningLocateParam>,\n detailedLocateParam: DetailedLocateParam | string,\n onResult?: (result: LocateResultElement) => void,\n ): ExecutionTaskInsightLocateApply => {\n if (typeof detailedLocateParam === 'string') {\n detailedLocateParam = {\n prompt: detailedLocateParam,\n };\n }\n const taskFind: ExecutionTaskInsightLocateApply = {\n type: 'Insight',\n subType: 'Locate',\n param: detailedLocateParam,\n thought: plan.thought,\n executor: async (param, taskContext) => {\n const { task } = taskContext;\n assert(\n param?.prompt || param?.id || param?.bbox,\n `No prompt or id or position or bbox to locate, param=${JSON.stringify(\n param,\n )}`,\n );\n let insightDump: InsightDump | undefined;\n let usage: AIUsageInfo | undefined;\n const dumpCollector: DumpSubscriber = (dump) => {\n insightDump = dump;\n usage = dump?.taskInfo?.usage;\n\n task.log = {\n dump: insightDump,\n };\n\n task.usage = usage;\n };\n this.insight.onceDumpUpdatedFn = dumpCollector;\n const shotTime = Date.now();\n\n // Get context through contextRetrieverFn which handles frozen context\n const uiContext = await this.insight.contextRetrieverFn('locate');\n task.uiContext = uiContext;\n\n const recordItem: ExecutionRecorderItem = {\n type: 'screenshot',\n ts: shotTime,\n screenshot: uiContext.screenshotBase64,\n timing: 'before Insight',\n };\n task.recorder = [recordItem];\n\n // try matching xpath\n const elementFromXpath =\n param.xpath && (this.interface as any).getElementInfoByXpath\n ? await (this.interface as any).getElementInfoByXpath(param.xpath)\n : undefined;\n const userExpectedPathHitFlag = !!elementFromXpath;\n\n // try matching cache\n const cachePrompt = param.prompt;\n const locateCacheRecord =\n this.taskCache?.matchLocateCache(cachePrompt);\n const xpaths = locateCacheRecord?.cacheContent?.xpaths;\n const elementFromCache = userExpectedPathHitFlag\n ? null\n : await matchElementFromCache(\n this,\n xpaths,\n cachePrompt,\n param.cacheable,\n );\n const cacheHitFlag = !!elementFromCache;\n\n // try matching plan\n const elementFromPlan =\n !userExpectedPathHitFlag && !cacheHitFlag\n ? matchElementFromPlan(param, uiContext.tree)\n : undefined;\n const planHitFlag = !!elementFromPlan;\n\n // try ai locate\n const elementFromAiLocate =\n !userExpectedPathHitFlag && !cacheHitFlag && !planHitFlag\n ? (\n await this.insight.locate(param, {\n // fallback to ai locate\n context: uiContext,\n })\n ).element\n : undefined;\n const aiLocateHitFlag = !!elementFromAiLocate;\n\n const element =\n elementFromXpath || // highest priority\n elementFromCache || // second priority\n elementFromPlan || // third priority\n elementFromAiLocate;\n\n // update cache\n let currentXpaths: string[] | undefined;\n if (\n element &&\n this.taskCache &&\n !cacheHitFlag &&\n param?.cacheable !== false\n ) {\n const elementXpaths = await this.getElementXpath(\n uiContext,\n element,\n );\n if (elementXpaths?.length) {\n currentXpaths = elementXpaths;\n this.taskCache.updateOrAppendCacheRecord(\n {\n type: 'locate',\n prompt: cachePrompt,\n xpaths: elementXpaths,\n },\n locateCacheRecord,\n );\n } else {\n debug(\n 'no xpaths found, will not update cache',\n cachePrompt,\n elementXpaths,\n );\n }\n }\n if (!element) {\n throw new Error(`Element not found: ${param.prompt}`);\n }\n\n let hitBy: ExecutionTaskHitBy | undefined;\n\n if (userExpectedPathHitFlag) {\n hitBy = {\n from: 'User expected path',\n context: {\n xpath: param.xpath,\n },\n };\n } else if (cacheHitFlag) {\n hitBy = {\n from: 'Cache',\n context: {\n xpathsFromCache: xpaths,\n xpathsToSave: currentXpaths,\n },\n };\n } else if (planHitFlag) {\n hitBy = {\n from: 'Planning',\n context: {\n id: elementFromPlan?.id,\n bbox: elementFromPlan?.bbox,\n },\n };\n } else if (aiLocateHitFlag) {\n hitBy = {\n from: 'AI model',\n context: {\n prompt: param.prompt,\n },\n };\n }\n\n onResult?.(element);\n\n return {\n output: {\n element,\n },\n uiContext,\n hitBy,\n };\n },\n };\n return taskFind;\n };\n\n for (const plan of plans) {\n if (plan.type === 'Locate') {\n if (\n !plan.locate ||\n plan.locate === null ||\n plan.locate?.id === null ||\n plan.locate?.id === 'null'\n ) {\n debug('Locate action with id is null, will be ignored', plan);\n continue;\n }\n const taskLocate = taskForLocatePlan(plan, plan.locate);\n\n tasks.push(taskLocate);\n } else if (plan.type === 'Error') {\n const taskActionError: ExecutionTaskActionApply<PlanningActionParamError> =\n {\n type: 'Action',\n subType: 'Error',\n param: plan.param,\n thought: plan.thought || plan.param?.thought,\n locate: plan.locate,\n executor: async () => {\n throw new Error(\n plan?.thought || plan.param?.thought || 'error without thought',\n );\n },\n };\n tasks.push(taskActionError);\n } else if (plan.type === 'Finished') {\n const taskActionFinished: ExecutionTaskActionApply<null> = {\n type: 'Action',\n subType: 'Finished',\n param: null,\n thought: plan.thought,\n locate: plan.locate,\n executor: async (param) => {},\n };\n tasks.push(taskActionFinished);\n } else if (plan.type === 'Sleep') {\n const taskActionSleep: ExecutionTaskActionApply<PlanningActionParamSleep> =\n {\n type: 'Action',\n subType: 'Sleep',\n param: plan.param,\n thought: plan.thought,\n locate: plan.locate,\n executor: async (taskParam) => {\n await sleep(taskParam?.timeMs || 3000);\n },\n };\n tasks.push(taskActionSleep);\n } else {\n // action in action space\n const planType = plan.type;\n const actionSpace = await this.interface.actionSpace();\n const action = actionSpace.find((action) => action.name === planType);\n const param = plan.param;\n\n if (!action) {\n throw new Error(`Action type '${planType}' not found`);\n }\n\n // find all params that needs location\n const locateFields = action\n ? findAllMidsceneLocatorField(action.paramSchema)\n : [];\n\n const requiredLocateFields = action\n ? findAllMidsceneLocatorField(action.paramSchema, true)\n : [];\n\n locateFields.forEach((field) => {\n if (param[field]) {\n const locatePlan = locatePlanForLocate(param[field]);\n debug(\n 'will prepend locate param for field',\n `action.type=${planType}`,\n `param=${JSON.stringify(param[field])}`,\n `locatePlan=${JSON.stringify(locatePlan)}`,\n );\n const locateTask = taskForLocatePlan(\n locatePlan,\n param[field],\n (result) => {\n param[field] = result;\n },\n );\n tasks.push(locateTask);\n } else {\n assert(\n !requiredLocateFields.includes(field),\n `Required locate field '${field}' is not provided for action ${planType}`,\n );\n debug(`field '${field}' is not provided for action ${planType}`);\n }\n });\n\n const task: ExecutionTaskApply<\n 'Action',\n any,\n { success: boolean; action: string; param: any },\n void\n > = {\n type: 'Action',\n subType: planType,\n thought: plan.thought,\n param: plan.param,\n executor: async (param, context) => {\n debug(\n 'executing action',\n planType,\n param,\n `context.element.center: ${context.element?.center}`,\n );\n\n // Get context for actionSpace operations to ensure size info is available\n const uiContext = await this.insight.contextRetrieverFn('locate');\n context.task.uiContext = uiContext;\n\n requiredLocateFields.forEach((field) => {\n assert(\n param[field],\n `field '${field}' is required for action ${planType} but not provided. Cannot execute action ${planType}.`,\n );\n });\n\n try {\n await Promise.all([\n (async () => {\n if (this.interface.beforeInvokeAction) {\n debug('will call \"beforeInvokeAction\" for interface');\n await this.interface.beforeInvokeAction(action.name, param);\n debug('called \"beforeInvokeAction\" for interface');\n }\n })(),\n sleep(200),\n ]);\n } catch (originalError: any) {\n const originalMessage =\n originalError?.message || String(originalError);\n throw new Error(\n `error in running beforeInvokeAction for ${action.name}: ${originalMessage}`,\n { cause: originalError },\n );\n }\n\n debug('calling action', action.name);\n const actionFn = action.call.bind(this.interface);\n await actionFn(param, context);\n debug('called action', action.name);\n\n try {\n if (this.interface.afterInvokeAction) {\n debug('will call \"afterInvokeAction\" for interface');\n await this.interface.afterInvokeAction(action.name, param);\n debug('called \"afterInvokeAction\" for interface');\n }\n } catch (originalError: any) {\n const originalMessage =\n originalError?.message || String(originalError);\n throw new Error(\n `error in running afterInvokeAction for ${action.name}: ${originalMessage}`,\n { cause: originalError },\n );\n }\n // Return a proper result for report generation\n return {\n output: {\n success: true,\n action: planType,\n param: param,\n },\n };\n },\n };\n tasks.push(task);\n }\n }\n\n const wrappedTasks = tasks.map(\n (task: ExecutionTaskApply, index: number) => {\n if (task.type === 'Action') {\n return this.prependExecutorWithScreenshot(\n task,\n index === tasks.length - 1,\n );\n }\n return task;\n },\n );\n\n return {\n tasks: wrappedTasks,\n };\n }\n\n private async setupPlanningContext(executorContext: ExecutorContext) {\n const shotTime = Date.now();\n const uiContext = await this.insight.contextRetrieverFn('locate');\n const recordItem: ExecutionRecorderItem = {\n type: 'screenshot',\n ts: shotTime,\n screenshot: uiContext.screenshotBase64,\n timing: 'before Planning',\n };\n\n executorContext.task.recorder = [recordItem];\n (executorContext.task as ExecutionTaskPlanning).uiContext = uiContext;\n\n return {\n uiContext,\n };\n }\n\n async loadYamlFlowAsPlanning(userInstruction: string, yamlString: string) {\n const taskExecutor = new Executor(taskTitleStr('Action', userInstruction), {\n onTaskStart: this.onTaskStartCallback,\n });\n\n const task: ExecutionTaskPlanningApply = {\n type: 'Planning',\n subType: 'LoadYaml',\n locate: null,\n param: {\n userInstruction,\n },\n executor: async (param, executorContext) => {\n await this.setupPlanningContext(executorContext);\n return {\n output: {\n actions: [],\n more_actions_needed_by_instruction: false,\n log: '',\n yamlString,\n },\n cache: {\n hit: true,\n },\n hitBy: {\n from: 'Cache',\n context: {\n yamlString,\n },\n },\n };\n },\n };\n\n await taskExecutor.append(task);\n await taskExecutor.flush();\n\n return {\n executor: taskExecutor,\n };\n }\n\n private planningTaskFromPrompt(\n userInstruction: string,\n log?: string,\n actionContext?: string,\n ) {\n const task: ExecutionTaskPlanningApply = {\n type: 'Planning',\n subType: 'Plan',\n locate: null,\n param: {\n userInstruction,\n log,\n },\n executor: async (param, executorContext) => {\n const startTime = Date.now();\n const { uiContext } = await this.setupPlanningContext(executorContext);\n\n assert(\n this.interface.actionSpace,\n 'actionSpace for device is not implemented',\n );\n const actionSpace = await this.interface.actionSpace();\n debug(\n 'actionSpace for this interface is:',\n actionSpace.map((action) => action.name).join(', '),\n );\n assert(Array.isArray(actionSpace), 'actionSpace must be an array');\n if (actionSpace.length === 0) {\n console.warn(\n `ActionSpace for ${this.interface.interfaceType} is empty. This may lead to unexpected behavior.`,\n );\n }\n\n const planResult = await plan(param.userInstruction, {\n context: uiContext,\n log: param.log,\n actionContext,\n interfaceType: this.interface.interfaceType as InterfaceType,\n actionSpace,\n });\n\n const {\n actions,\n log,\n more_actions_needed_by_instruction,\n error,\n usage,\n rawResponse,\n sleep,\n } = planResult;\n\n executorContext.task.log = {\n ...(executorContext.task.log || {}),\n rawResponse,\n };\n executorContext.task.usage = usage;\n\n const finalActions = actions || [];\n\n // TODO: check locate result\n // let bboxCollected = false;\n // (actions || []).reduce<PlanningAction[]>(\n // (acc, planningAction) => {\n // // TODO: magic field \"locate\" is used to indicate the action requires a locate\n // if (planningAction.locate) {\n // // we only collect bbox once, let qwen re-locate in the following steps\n // if (bboxCollected && planningAction.locate.bbox) {\n // // biome-ignore lint/performance/noDelete: <explanation>\n // delete planningAction.locate.bbox;\n // }\n\n // if (planningAction.locate.bbox) {\n // bboxCollected = true;\n // }\n\n // acc.push({\n // type: 'Locate',\n // locate: planningAction.locate,\n // param: null,\n // // thought is prompt created by ai, always a string\n // thought: planningAction.locate.prompt as string,\n // });\n // }\n // acc.push(planningAction);\n // return acc;\n // },\n // [],\n // );\n\n if (sleep) {\n const timeNow = Date.now();\n const timeRemaining = sleep - (timeNow - startTime);\n if (timeRemaining > 0) {\n finalActions.push({\n type: 'Sleep',\n param: {\n timeMs: timeRemaining,\n },\n locate: null,\n } as PlanningAction<PlanningActionParamSleep>);\n }\n }\n\n if (finalActions.length === 0) {\n assert(\n !more_actions_needed_by_instruction || sleep,\n error ? `Failed to plan: ${error}` : 'No plan found',\n );\n }\n\n return {\n output: {\n actions: finalActions,\n more_actions_needed_by_instruction,\n log,\n yamlFlow: planResult.yamlFlow,\n },\n cache: {\n hit: false,\n },\n uiContext,\n };\n },\n };\n\n return task;\n }\n\n private planningTaskToGoal(\n userInstruction: string,\n modelPreferences: IModelPreferences,\n ) {\n const task: ExecutionTaskPlanningApply = {\n type: 'Planning',\n subType: 'Plan',\n locate: null,\n param: {\n userInstruction,\n },\n executor: async (param, executorContext) => {\n const { uiContext } = await this.setupPlanningContext(executorContext);\n\n const imagePayload = await resizeImageForUiTars(\n uiContext.screenshotBase64,\n uiContext.size,\n modelPreferences,\n );\n\n this.appendConversationHistory({\n role: 'user',\n content: [\n {\n type: 'image_url',\n image_url: {\n url: imagePayload,\n },\n },\n ],\n });\n const planResult: {\n actions: PlanningAction<any>[];\n action_summary: string;\n usage?: AIUsageInfo;\n yamlFlow?: MidsceneYamlFlowItem[];\n rawResponse?: string;\n } = await vlmPlanning({\n userInstruction: param.userInstruction,\n conversationHistory: this.conversationHistory,\n size: uiContext.size,\n modelPreferences,\n });\n\n const { actions, action_summary, usage } = planResult;\n executorContext.task.log = {\n ...(executorContext.task.log || {}),\n rawResponse: planResult.rawResponse,\n };\n executorContext.task.usage = usage;\n this.appendConversationHistory({\n role: 'assistant',\n content: action_summary,\n });\n return {\n output: {\n actions,\n thought: actions[0]?.thought,\n actionType: actions[0].type,\n more_actions_needed_by_instruction: true,\n log: '',\n yamlFlow: planResult.yamlFlow,\n },\n cache: {\n hit: false,\n },\n };\n },\n };\n\n return task;\n }\n\n async runPlans(\n title: string,\n plans: PlanningAction[],\n ): Promise<ExecutionResult> {\n const taskExecutor = new Executor(title, {\n onTaskStart: this.onTaskStartCallback,\n });\n const { tasks } = await this.convertPlanToExecutable(plans);\n await taskExecutor.append(tasks);\n const result = await taskExecutor.flush();\n const { output } = result!;\n return {\n output,\n executor: taskExecutor,\n };\n }\n\n async action(\n userPrompt: string,\n actionContext?: string,\n ): Promise<\n ExecutionResult<\n | {\n yamlFlow?: MidsceneYamlFlowItem[]; // for cache use\n }\n | undefined\n >\n > {\n const taskExecutor = new Executor(taskTitleStr('Action', userPrompt), {\n onTaskStart: this.onTaskStartCallback,\n });\n\n let planningTask: ExecutionTaskPlanningApply | null =\n this.planningTaskFromPrompt(userPrompt, undefined, actionContext);\n let replanCount = 0;\n const logList: string[] = [];\n\n const yamlFlow: MidsceneYamlFlowItem[] = [];\n const replanningCycleLimit =\n globalConfigManager.getEnvConfigInNumber(\n MIDSCENE_REPLANNING_CYCLE_LIMIT,\n ) || defaultReplanningCycleLimit;\n while (planningTask) {\n if (replanCount > replanningCycleLimit) {\n const errorMsg =\n 'Replanning too many times, please split the task into multiple steps';\n\n return this.appendErrorPlan(taskExecutor, errorMsg);\n }\n\n // plan\n await taskExecutor.append(planningTask);\n const result = await taskExecutor.flush();\n const planResult: PlanningAIResponse = result?.output;\n if (taskExecutor.isInErrorState()) {\n return {\n output: planResult,\n executor: taskExecutor,\n };\n }\n\n const plans = planResult.actions || [];\n yamlFlow.push(...(planResult.yamlFlow || []));\n\n let executables: Awaited<ReturnType<typeof this.convertPlanToExecutable>>;\n try {\n executables = await this.convertPlanToExecutable(plans);\n taskExecutor.append(executables.tasks);\n } catch (error) {\n return this.appendErrorPlan(\n taskExecutor,\n `Error converting plans to executable tasks: ${error}, plans: ${JSON.stringify(\n plans,\n )}`,\n );\n }\n\n await taskExecutor.flush();\n if (taskExecutor.isInErrorState()) {\n return {\n output: undefined,\n executor: taskExecutor,\n };\n }\n if (planResult?.log) {\n logList.push(planResult.log);\n }\n\n if (!planResult.more_actions_needed_by_instruction) {\n planningTask = null;\n break;\n }\n planningTask = this.planningTaskFromPrompt(\n userPrompt,\n logList.length > 0 ? `- ${logList.join('\\n- ')}` : undefined,\n actionContext,\n );\n replanCount++;\n }\n\n return {\n output: {\n yamlFlow,\n },\n executor: taskExecutor,\n };\n }\n\n async actionToGoal(userPrompt: string): Promise<\n ExecutionResult<\n | {\n yamlFlow?: MidsceneYamlFlowItem[]; // for cache use\n }\n | undefined\n >\n > {\n const taskExecutor = new Executor(taskTitleStr('Action', userPrompt), {\n onTaskStart: this.onTaskStartCallback,\n });\n this.conversationHistory = [];\n const isCompleted = false;\n let currentActionCount = 0;\n const maxActionNumber = 40;\n\n const yamlFlow: MidsceneYamlFlowItem[] = [];\n while (!isCompleted && currentActionCount < maxActionNumber) {\n currentActionCount++;\n debug(\n 'actionToGoal, currentActionCount:',\n currentActionCount,\n 'userPrompt:',\n userPrompt,\n );\n const planningTask: ExecutionTaskPlanningApply = this.planningTaskToGoal(\n userPrompt,\n {\n intent: 'planning',\n },\n );\n await taskExecutor.append(planningTask);\n const result = await taskExecutor.flush();\n if (taskExecutor.isInErrorState()) {\n return {\n output: undefined,\n executor: taskExecutor,\n };\n }\n if (!result) {\n throw new Error(\n 'result of taskExecutor.flush() is undefined in function actionToGoal',\n );\n }\n const { output } = result;\n const plans = output.actions;\n yamlFlow.push(...(output.yamlFlow || []));\n let executables: Awaited<ReturnType<typeof this.convertPlanToExecutable>>;\n try {\n executables = await this.convertPlanToExecutable(plans);\n taskExecutor.append(executables.tasks);\n } catch (error) {\n return this.appendErrorPlan(\n taskExecutor,\n `Error converting plans to executable tasks: ${error}, plans: ${JSON.stringify(\n plans,\n )}`,\n );\n }\n\n await taskExecutor.flush();\n\n if (taskExecutor.isInErrorState()) {\n return {\n output: undefined,\n executor: taskExecutor,\n };\n }\n\n if (plans[0].type === 'Finished') {\n break;\n }\n }\n return {\n output: {\n yamlFlow,\n },\n executor: taskExecutor,\n };\n }\n\n private createTypeQueryTask(\n type: 'Query' | 'Boolean' | 'Number' | 'String' | 'Assert',\n demand: InsightExtractParam,\n opt?: InsightExtractOption,\n multimodalPrompt?: TMultimodalPrompt,\n ) {\n const queryTask: ExecutionTaskInsightQueryApply = {\n type: 'Insight',\n subType: type,\n locate: null,\n param: {\n // TODO: display image thumbnail in report\n dataDemand: multimodalPrompt\n ? ({\n demand,\n multimodalPrompt,\n } as never)\n : demand, // for user param presentation in report right sidebar\n },\n executor: async (param, taskContext) => {\n const { task } = taskContext;\n let insightDump: InsightDump | undefined;\n const dumpCollector: DumpSubscriber = (dump) => {\n insightDump = dump;\n };\n this.insight.onceDumpUpdatedFn = dumpCollector;\n\n // Get context for query operations\n const shotTime = Date.now();\n const uiContext = await this.insight.contextRetrieverFn('extract');\n task.uiContext = uiContext;\n\n const recordItem: ExecutionRecorderItem = {\n type: 'screenshot',\n ts: shotTime,\n screenshot: uiContext.screenshotBase64,\n timing: 'before Extract',\n };\n task.recorder = [recordItem];\n\n const ifTypeRestricted = type !== 'Query';\n let demandInput = demand;\n if (ifTypeRestricted) {\n const returnType = type === 'Assert' ? 'Boolean' : type;\n demandInput = {\n result: `${returnType}, ${demand}`,\n };\n }\n\n const { data, usage, thought } = await this.insight.extract<any>(\n demandInput,\n opt,\n multimodalPrompt,\n );\n\n let outputResult = data;\n if (ifTypeRestricted) {\n // If AI returned a plain string instead of structured format, use it directly\n if (typeof data === 'string') {\n outputResult = data;\n } else {\n assert(data?.result !== undefined, 'No result in query data');\n outputResult = (data as any).result;\n }\n }\n\n return {\n output: outputResult,\n log: { dump: insightDump, isWaitForAssert: opt?.isWaitForAssert },\n usage,\n thought,\n };\n },\n };\n\n return queryTask;\n }\n async createTypeQueryExecution<T>(\n type: 'Query' | 'Boolean' | 'Number' | 'String' | 'Assert',\n demand: InsightExtractParam,\n opt?: InsightExtractOption,\n multimodalPrompt?: TMultimodalPrompt,\n ): Promise<ExecutionResult<T>> {\n const taskExecutor = new Executor(\n taskTitleStr(\n type,\n typeof demand === 'string' ? demand : JSON.stringify(demand),\n ),\n {\n onTaskStart: this.onTaskStartCallback,\n },\n );\n\n const queryTask = await this.createTypeQueryTask(\n type,\n demand,\n opt,\n multimodalPrompt,\n );\n\n await taskExecutor.append(this.prependExecutorWithScreenshot(queryTask));\n const result = await taskExecutor.flush();\n\n if (!result) {\n throw new Error(\n 'result of taskExecutor.flush() is undefined in function createTypeQueryTask',\n );\n }\n\n const { output, thought } = result;\n\n return {\n output,\n thought,\n executor: taskExecutor,\n };\n }\n\n async assert(\n assertion: TUserPrompt,\n opt?: InsightExtractOption,\n ): Promise<ExecutionResult<boolean>> {\n const { textPrompt, multimodalPrompt } = parsePrompt(assertion);\n return await this.createTypeQueryExecution<boolean>(\n 'Assert',\n textPrompt,\n opt,\n multimodalPrompt,\n );\n }\n\n /**\n * Append a message to the conversation history\n * For user messages with images:\n * - Keep max 4 user image messages in history\n * - Remove oldest user image message when limit reached\n * For assistant messages:\n * - Simply append to history\n * @param conversationHistory Message to append\n */\n private appendConversationHistory(\n conversationHistory: ChatCompletionMessageParam,\n ) {\n if (conversationHistory.role === 'user') {\n // Get all existing user messages with images\n const userImgItems = this.conversationHistory.filter(\n (item) => item.role === 'user',\n );\n\n // If we already have 4 user image messages\n if (userImgItems.length >= 4 && conversationHistory.role === 'user') {\n // Remove first user image message when we already have 4, before adding new one\n const firstUserImgIndex = this.conversationHistory.findIndex(\n (item) => item.role === 'user',\n );\n if (firstUserImgIndex >= 0) {\n this.conversationHistory.splice(firstUserImgIndex, 1);\n }\n }\n }\n // For non-user messages, simply append to history\n this.conversationHistory.push(conversationHistory);\n }\n\n private async appendErrorPlan(taskExecutor: Executor, errorMsg: string) {\n const errorPlan: PlanningAction<PlanningActionParamError> = {\n type: 'Error',\n param: {\n thought: errorMsg,\n },\n locate: null,\n };\n const { tasks } = await this.convertPlanToExecutable([errorPlan]);\n await taskExecutor.append(this.prependExecutorWithScreenshot(tasks[0]));\n await taskExecutor.flush();\n\n return {\n output: undefined,\n executor: taskExecutor,\n };\n }\n\n async waitFor(\n assertion: TUserPrompt,\n opt: PlanningActionParamWaitFor,\n ): Promise<ExecutionResult<void>> {\n const { textPrompt, multimodalPrompt } = parsePrompt(assertion);\n\n const description = `waitFor: ${textPrompt}`;\n const taskExecutor = new Executor(taskTitleStr('WaitFor', description), {\n onTaskStart: this.onTaskStartCallback,\n });\n const { timeoutMs, checkIntervalMs } = opt;\n\n assert(assertion, 'No assertion for waitFor');\n assert(timeoutMs, 'No timeoutMs for waitFor');\n assert(checkIntervalMs, 'No checkIntervalMs for waitFor');\n\n assert(\n checkIntervalMs <= timeoutMs,\n `wrong config for waitFor: checkIntervalMs must be less than timeoutMs, config: {checkIntervalMs: ${checkIntervalMs}, timeoutMs: ${timeoutMs}}`,\n );\n\n const overallStartTime = Date.now();\n let startTime = Date.now();\n let errorThought = '';\n while (Date.now() - overallStartTime < timeoutMs) {\n startTime = Date.now();\n const queryTask = await this.createTypeQueryTask(\n 'Assert',\n textPrompt,\n {\n isWaitForAssert: true,\n returnThought: true,\n doNotThrowError: true,\n },\n multimodalPrompt,\n );\n\n await taskExecutor.append(this.prependExecutorWithScreenshot(queryTask));\n const result = (await taskExecutor.flush()) as {\n output: boolean;\n thought?: string;\n };\n\n if (!result) {\n throw new Error(\n 'result of taskExecutor.flush() is undefined in function waitFor',\n );\n }\n\n if (result?.output) {\n return {\n output: undefined,\n executor: taskExecutor,\n };\n }\n\n errorThought =\n result?.thought ||\n `unknown error when waiting for assertion: ${textPrompt}`;\n const now = Date.now();\n if (now - startTime < checkIntervalMs) {\n const timeRemaining = checkIntervalMs - (now - startTime);\n const sleepPlan: PlanningAction<PlanningActionParamSleep> = {\n type: 'Sleep',\n param: {\n timeMs: timeRemaining,\n },\n locate: null,\n };\n const { tasks: sleepTasks } = await this.convertPlanToExecutable([\n sleepPlan,\n ]);\n await taskExecutor.append(\n this.prependExecutorWithScreenshot(sleepTasks[0]),\n );\n await taskExecutor.flush();\n }\n }\n\n return this.appendErrorPlan(\n taskExecutor,\n `waitFor timeout: ${errorThought}`,\n );\n }\n}\n"],"names":["debug","getDebug","defaultReplanningCycleLimit","locatePlanForLocate","param","locate","locatePlan","TaskExecutor","timing","base64","item","Date","uiContext","element","_element_attributes","elementId","undefined","xpaths","error","NodeType","info","elementByPositionWithElementInfo","result","taskApply","appendAfterExecution","taskWithScreenshot","context","args","recorder","task","shot","shot2","plans","tasks","taskForLocatePlan","plan","detailedLocateParam","onResult","taskFind","taskContext","_this_taskCache","_locateCacheRecord_cacheContent","assert","JSON","insightDump","usage","dumpCollector","dump","_dump_taskInfo","shotTime","recordItem","elementFromXpath","userExpectedPathHitFlag","cachePrompt","locateCacheRecord","elementFromCache","matchElementFromCache","cacheHitFlag","elementFromPlan","matchElementFromPlan","planHitFlag","elementFromAiLocate","aiLocateHitFlag","currentXpaths","elementXpaths","Error","hitBy","_plan_locate","_plan_locate1","taskLocate","_plan_param","taskActionError","taskActionFinished","taskActionSleep","taskParam","sleep","planType","actionSpace","action","locateFields","findAllMidsceneLocatorField","requiredLocateFields","field","locateTask","_context_element","Promise","originalError","originalMessage","String","actionFn","wrappedTasks","index","executorContext","userInstruction","yamlString","taskExecutor","Executor","taskTitleStr","log","actionContext","startTime","Array","console","planResult","actions","more_actions_needed_by_instruction","rawResponse","finalActions","timeNow","timeRemaining","modelPreferences","_actions_","imagePayload","resizeImageForUiTars","vlmPlanning","action_summary","title","output","userPrompt","planningTask","replanCount","logList","yamlFlow","replanningCycleLimit","globalConfigManager","MIDSCENE_REPLANNING_CYCLE_LIMIT","errorMsg","executables","isCompleted","currentActionCount","maxActionNumber","type","demand","opt","multimodalPrompt","queryTask","ifTypeRestricted","demandInput","returnType","data","thought","outputResult","assertion","textPrompt","parsePrompt","conversationHistory","userImgItems","firstUserImgIndex","errorPlan","description","timeoutMs","checkIntervalMs","overallStartTime","errorThought","now","sleepPlan","sleepTasks","interfaceInstance","insight","opts"],"mappings":"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"}
@@ -138,7 +138,7 @@ function trimContextByViewport(execution) {
138
138
  }) : execution.tasks
139
139
  };
140
140
  }
141
- const getMidsceneVersion = ()=>"0.28.1-beta-20250909024808.0";
141
+ const getMidsceneVersion = ()=>"0.28.1-beta-20250909063633.0";
142
142
  const parsePrompt = (prompt)=>{
143
143
  if ('string' == typeof prompt) return {
144
144
  textPrompt: prompt,
@@ -1,6 +1,5 @@
1
1
  import node_assert from "node:assert";
2
2
  import { PromptTemplate } from "@langchain/core/prompts";
3
- import { z } from "zod";
4
3
  import { ifMidsceneLocatorField } from "../common.mjs";
5
4
  import { bboxDescription } from "./common.mjs";
6
5
  const vlCoTLog = '"what_the_user_wants_to_do_next_by_instruction": string, // What the user wants to do according to the instruction and previous logs. ';
@@ -15,7 +14,7 @@ const descriptionForAction = (action, locatorSchemaTypeDescription)=>{
15
14
  const fields = [];
16
15
  fields.push(`- type: "${action.name}"`);
17
16
  if (action.paramSchema) {
18
- node_assert(action.paramSchema instanceof z.ZodObject, 'paramSchema must be a zod object');
17
+ node_assert('ZodObject' === action.paramSchema.constructor.name, 'paramSchema must be a zod object');
19
18
  const shape = action.paramSchema.shape;
20
19
  const paramLines = [];
21
20
  const getTypeName = (field)=>{
@@ -1 +1 @@
1
- {"version":3,"file":"ai-model/prompt/llm-planning.mjs","sources":["webpack://@midscene/core/./src/ai-model/prompt/llm-planning.ts"],"sourcesContent":["import assert from 'node:assert';\nimport type { DeviceAction } from '@/types';\nimport { PromptTemplate } from '@langchain/core/prompts';\nimport type { vlLocateMode } from '@midscene/shared/env';\nimport type { ResponseFormatJSONSchema } from 'openai/resources/index';\nimport { z } from 'zod';\nimport { ifMidsceneLocatorField } from '../common';\nimport { bboxDescription } from './common';\n\n// Note: put the log field first to trigger the CoT\nconst vlCoTLog = `\"what_the_user_wants_to_do_next_by_instruction\": string, // What the user wants to do according to the instruction and previous logs. `;\nconst vlCurrentLog = `\"log\": string, // Log what the next one action (ONLY ONE!) you can do according to the screenshot and the instruction. The typical log looks like \"Now i want to use action '{ action-type }' to do .. first\". If no action should be done, log the reason. \". Use the same language as the user's instruction.`;\nconst llmCurrentLog = `\"log\": string, // Log what the next actions you can do according to the screenshot and the instruction. The typical log looks like \"Now i want to use action '{ action-type }' to do ..\". If no action should be done, log the reason. \". Use the same language as the user's instruction.`;\n\nconst commonOutputFields = `\"error\"?: string, // Error messages about unexpected situations, if any. Only think it is an error when the situation is not foreseeable according to the instruction. Use the same language as the user's instruction.\n \"more_actions_needed_by_instruction\": boolean, // Consider if there is still more action(s) to do after the action in \"Log\" is done, according to the instruction. If so, set this field to true. Otherwise, set it to false.`;\nconst vlLocateParam = () =>\n '{bbox: [number, number, number, number], prompt: string }';\nconst llmLocateParam = () => '{\"id\": string, \"prompt\": string}';\n\nexport const descriptionForAction = (\n action: DeviceAction<any>,\n locatorSchemaTypeDescription: string,\n) => {\n const tab = ' ';\n const fields: string[] = [];\n\n // Add the action type field\n fields.push(`- type: \"${action.name}\"`);\n\n // Handle paramSchema if it exists\n if (action.paramSchema) {\n assert(\n action.paramSchema instanceof z.ZodObject,\n 'paramSchema must be a zod object',\n );\n // Try to extract parameter information from the zod schema\n // For zod object schemas, extract type information and descriptions\n const shape = action.paramSchema.shape;\n const paramLines: string[] = [];\n\n // Helper function to get type name from zod schema\n const getTypeName = (field: any): string => {\n // Recursively unwrap optional, nullable, and other wrapper types to get the actual inner type\n const unwrapField = (f: any): any => {\n if (!f._def) return f;\n\n const typeName = f._def.typeName;\n\n // Handle wrapper types that have innerType\n if (\n typeName === 'ZodOptional' ||\n typeName === 'ZodNullable' ||\n typeName === 'ZodDefault'\n ) {\n return unwrapField(f._def.innerType);\n }\n\n return f;\n };\n\n const actualField = unwrapField(field);\n const fieldTypeName = actualField._def?.typeName;\n\n if (fieldTypeName === 'ZodString') return 'string';\n if (fieldTypeName === 'ZodNumber') return 'number';\n if (fieldTypeName === 'ZodBoolean') return 'boolean';\n if (fieldTypeName === 'ZodArray') return 'array';\n if (fieldTypeName === 'ZodObject') {\n // Check if this is a passthrough object (like MidsceneLocation)\n if (ifMidsceneLocatorField(actualField)) {\n return locatorSchemaTypeDescription;\n }\n return 'object';\n }\n if (fieldTypeName === 'ZodEnum') {\n const values =\n (actualField._def?.values as unknown[] | undefined)\n ?.map((option: unknown) => String(`'${option}'`))\n .join(', ') ?? 'enum';\n\n return `enum(${values})`;\n }\n\n console.warn(\n 'failed to parse Zod type. This may lead to wrong params from the LLM.\\n',\n actualField._def,\n );\n return actualField.toString();\n };\n\n // Helper function to get description from zod schema\n const getDescription = (field: z.ZodTypeAny): string | null => {\n // Recursively unwrap optional, nullable, and other wrapper types to get the actual inner type\n const unwrapField = (f: any): any => {\n if (!f._def) return f;\n\n const typeName = f._def.typeName;\n\n // Handle wrapper types that have innerType\n if (\n typeName === 'ZodOptional' ||\n typeName === 'ZodNullable' ||\n typeName === 'ZodDefault'\n ) {\n return unwrapField(f._def.innerType);\n }\n\n return f;\n };\n\n // Check for direct description on the original field (wrapper may have description)\n if ('description' in field) {\n return field.description || null;\n }\n\n const actualField = unwrapField(field);\n\n // Check for description on the unwrapped field\n if ('description' in actualField) {\n return actualField.description || null;\n }\n\n // Check for MidsceneLocation fields and add description\n if (actualField._def?.typeName === 'ZodObject') {\n if ('midscene_location_field_flag' in actualField._def.shape()) {\n return 'Location information for the target element';\n }\n }\n\n return null;\n };\n\n for (const [key, field] of Object.entries(shape)) {\n if (field && typeof field === 'object') {\n // Check if field is optional\n const isOptional =\n typeof (field as any).isOptional === 'function' &&\n (field as any).isOptional();\n const keyWithOptional = isOptional ? `${key}?` : key;\n\n // Get the type name\n const typeName = getTypeName(field);\n\n // Get description\n const description = getDescription(field as z.ZodTypeAny);\n\n // Build param line for this field\n let paramLine = `${keyWithOptional}: ${typeName}`;\n if (description) {\n paramLine += ` // ${description}`;\n }\n\n paramLines.push(paramLine);\n }\n }\n\n if (paramLines.length > 0) {\n fields.push('- param:');\n for (const paramLine of paramLines) {\n fields.push(` - ${paramLine}`);\n }\n }\n }\n\n return `- ${action.name}, ${action.description || 'No description provided'}\n${tab}${fields.join(`\\n${tab}`)}\n`.trim();\n};\n\nconst systemTemplateOfVLPlanning = ({\n actionSpace,\n vlMode,\n}: {\n actionSpace: DeviceAction<any>[];\n vlMode: ReturnType<typeof vlLocateMode>;\n}) => {\n const actionNameList = actionSpace.map((action) => action.name).join(', ');\n const actionDescriptionList = actionSpace.map((action) => {\n return descriptionForAction(action, vlLocateParam());\n });\n const actionList = actionDescriptionList.join('\\n');\n\n return `\nTarget: User will give you a screenshot, an instruction and some previous logs indicating what have been done. Please tell what the next one action is (or null if no action should be done) to do the tasks the instruction requires. \n\nRestriction:\n- Don't give extra actions or plans beyond the instruction. ONLY plan for what the instruction requires. For example, don't try to submit the form if the instruction is only to fill something.\n- Always give ONLY ONE action in \\`log\\` field (or null if no action should be done), instead of multiple actions. Supported actions are ${actionNameList}.\n- Don't repeat actions in the previous logs.\n- Bbox is the bounding box of the element to be located. It's an array of 4 numbers, representing ${bboxDescription(vlMode)}.\n\nSupporting actions:\n${actionList}\n\nField description:\n* The \\`prompt\\` field inside the \\`locate\\` field is a short description that could be used to locate the element.\n\nReturn in JSON format:\n{\n ${vlCoTLog}\n ${vlCurrentLog}\n ${commonOutputFields}\n \"action\": \n {\n // one of the supporting actions\n } | null,\n ,\n \"sleep\"?: number, // The sleep time after the action, in milliseconds.\n}\n\nFor example, when the instruction is \"click 'Confirm' button, and click 'Yes' in popup\" and the log is \"I will use action Tap to click 'Confirm' button\", by viewing the screenshot and previous logs, you should consider: We have already clicked the 'Confirm' button, so next we should find and click 'Yes' in popup.\n\nthis and output the JSON:\n\n{\n \"what_the_user_wants_to_do_next_by_instruction\": \"We have already clicked the 'Confirm' button, so next we should find and click 'Yes' in popup\",\n \"log\": \"I will use action Tap to click 'Yes' in popup\",\n \"more_actions_needed_by_instruction\": false,\n \"action\": {\n \"type\": \"Tap\",\n \"param\": {\n \"locate\": {\n \"bbox\": [100, 100, 200, 200],\n \"prompt\": \"The 'Yes' button in popup\"\n }\n }\n }\n}\n`;\n};\n\nconst systemTemplateOfLLM = ({\n actionSpace,\n}: { actionSpace: DeviceAction<any>[] }) => {\n const actionNameList = actionSpace.map((action) => action.name).join(' / ');\n const actionDescriptionList = actionSpace.map((action) => {\n return descriptionForAction(action, llmLocateParam());\n });\n const actionList = actionDescriptionList.join('\\n');\n\n return `\n## Role\n\nYou are a versatile professional in software UI automation. Your outstanding contributions will impact the user experience of billions of users.\n\n## Objective\n\n- Decompose the instruction user asked into a series of actions\n- Locate the target element if possible\n- If the instruction cannot be accomplished, give a further plan.\n\n## Workflow\n\n1. Receive the screenshot, element description of screenshot(if any), user's instruction and previous logs.\n2. Decompose the user's task into a sequence of feasible actions, and place it in the \\`actions\\` field. There are different types of actions (${actionNameList}). The \"About the action\" section below will give you more details.\n3. Consider whether the user's instruction will be accomplished after the actions you composed.\n- If the instruction is accomplished, set \\`more_actions_needed_by_instruction\\` to false.\n- If more actions are needed, set \\`more_actions_needed_by_instruction\\` to true. Get ready to hand over to the next talent people like you. Carefully log what have been done in the \\`log\\` field, he or she will continue the task according to your logs.\n4. If the task is not feasible on this page, set \\`error\\` field to the reason.\n\n## Constraints\n\n- All the actions you composed MUST be feasible, which means all the action fields can be filled with the page context information you get. If not, don't plan this action.\n- Trust the \"What have been done\" field about the task (if any), don't repeat actions in it.\n- Respond only with valid JSON. Do not write an introduction or summary or markdown prefix like \\`\\`\\`json\\`\\`\\`.\n- If the screenshot and the instruction are totally irrelevant, set reason in the \\`error\\` field.\n\n## About the \\`actions\\` field\n\nThe \\`locate\\` param is commonly used in the \\`param\\` field of the action, means to locate the target element to perform the action, it conforms to the following scheme:\n\ntype LocateParam = {\n \"id\": string, // the id of the element found. It should either be the id marked with a rectangle in the screenshot or the id described in the description.\n \"prompt\"?: string // the description of the element to find. It can only be omitted when locate is null.\n} | null // If it's not on the page, the LocateParam should be null\n\n## Supported actions\n\nEach action has a \\`type\\` and corresponding \\`param\\`. To be detailed:\n${actionList}\n\n`.trim();\n};\n\nconst outputTemplate = `\n## Output JSON Format:\n\nThe JSON format is as follows:\n\n{\n \"actions\": [\n // ... some actions\n ],\n ${llmCurrentLog}\n ${commonOutputFields}\n}\n\n## Examples\n\n### Example: Decompose a task\n\nWhen you received the following information:\n\n* Instruction: 'Click the language switch button, wait 1s, click \"English\"'\n* Logs: null\n* Page Context (screenshot and description) shows: There is a language switch button, and the \"English\" option is not shown in the screenshot now.\n\nBy viewing the page screenshot and description, you should consider this and output the JSON:\n\n* The user intent is: tap the switch button, sleep, and tap the 'English' option\n* The language switch button is shown in the screenshot, and can be located by the page description or the id marked with a rectangle. So we can plan a Tap action to do this.\n* Plan a Sleep action to wait for 1 second to ensure the language options are displayed.\n* The \"English\" option button is not shown in the screenshot now, it means it may only show after the previous actions are finished. So don't plan any action to do this.\n* Log what these action do: Click the language switch button to open the language options. Wait for 1 second.\n* The task cannot be accomplished (because the last tapping action is not finished yet), so the \\`more_actions_needed_by_instruction\\` field is true. The \\`error\\` field is null.\n\n{\n \"actions\":[\n {\n \"thought\": \"Click the language switch button to open the language options.\",\n \"type\": \"Tap\", \n \"param\": {\n \"locate\": { id: \"c81c4e9a33\", prompt: \"The language switch button\" }\n }\n },\n {\n \"thought\": \"Wait for 1 second to ensure the language options are displayed.\",\n \"type\": \"Sleep\",\n \"param\": { \"timeMs\": 1000 },\n }\n ],\n \"error\": null,\n \"more_actions_needed_by_instruction\": true,\n \"log\": \"Click the language switch button to open the language options. Wait for 1 second\",\n}\n\n### Example: What NOT to do\nWrong output:\n{\n \"actions\":[\n {\n \"thought\": \"Click the language switch button to open the language options.\",\n \"type\": \"Tap\",\n \"param\": {\n \"locate\": { \"id\": \"c81c4e9a33\" } // WRONG: prompt is missing, this is not a valid LocateParam\n }\n },\n {\n \"thought\": \"Click the English option\",\n \"type\": \"Tap\", \n \"param\": {\n \"locate\": null // WRONG: if the element is not on the page, you should not plan this action\n }\n }\n ],\n \"more_actions_needed_by_instruction\": false, // WRONG: should be true\n \"log\": \"Click the language switch button to open the language options\",\n}\n`;\n\nexport async function systemPromptToTaskPlanning({\n actionSpace,\n vlMode,\n}: {\n actionSpace: DeviceAction<any>[];\n vlMode: ReturnType<typeof vlLocateMode>;\n}) {\n if (vlMode) {\n return systemTemplateOfVLPlanning({ actionSpace, vlMode });\n }\n\n return `${systemTemplateOfLLM({ actionSpace })}\\n\\n${outputTemplate}`;\n}\n\nexport const planSchema: ResponseFormatJSONSchema = {\n type: 'json_schema',\n json_schema: {\n name: 'action_items',\n strict: false,\n schema: {\n type: 'object',\n strict: false,\n properties: {\n actions: {\n type: 'array',\n items: {\n type: 'object',\n strict: false,\n properties: {\n thought: {\n type: 'string',\n description:\n 'Reasons for generating this task, and why this task is feasible on this page',\n },\n type: {\n type: 'string',\n description: 'Type of action',\n },\n param: {\n anyOf: [\n { type: 'null' },\n {\n type: 'object',\n additionalProperties: true,\n },\n ],\n description: 'Parameter of the action',\n },\n locate: {\n type: ['object', 'null'],\n properties: {\n id: { type: 'string' },\n prompt: { type: 'string' },\n },\n required: ['id', 'prompt'],\n additionalProperties: false,\n description: 'Location information for the target element',\n },\n },\n required: ['thought', 'type', 'param', 'locate'],\n additionalProperties: false,\n },\n description: 'List of actions to be performed',\n },\n more_actions_needed_by_instruction: {\n type: 'boolean',\n description:\n 'If all the actions described in the instruction have been covered by this action and logs, set this field to false.',\n },\n log: {\n type: 'string',\n description:\n 'Log what these planned actions do. Do not include further actions that have not been planned.',\n },\n error: {\n type: ['string', 'null'],\n description: 'Error messages about unexpected situations',\n },\n },\n required: [\n 'actions',\n 'more_actions_needed_by_instruction',\n 'log',\n 'error',\n ],\n additionalProperties: false,\n },\n },\n};\n\nexport const generateTaskBackgroundContext = (\n userInstruction: string,\n log?: string,\n userActionContext?: string,\n) => {\n if (log) {\n return `\nHere is the user's instruction:\n\n<instruction>\n <high_priority_knowledge>\n ${userActionContext}\n </high_priority_knowledge>\n\n ${userInstruction}\n</instruction>\n\nThese are the logs from previous executions, which indicate what was done in the previous actions.\nDo NOT repeat these actions.\n<previous_logs>\n${log}\n</previous_logs>\n`;\n }\n\n return `\nHere is the user's instruction:\n<instruction>\n <high_priority_knowledge>\n ${userActionContext}\n </high_priority_knowledge>\n\n ${userInstruction}\n</instruction>\n`;\n};\n\nexport const automationUserPrompt = (\n vlMode: ReturnType<typeof vlLocateMode>,\n) => {\n if (vlMode) {\n return new PromptTemplate({\n template: '{taskBackgroundContext}',\n inputVariables: ['taskBackgroundContext'],\n });\n }\n\n return new PromptTemplate({\n template: `\npageDescription:\n=====================================\n{pageDescription}\n=====================================\n\n{taskBackgroundContext}`,\n inputVariables: ['pageDescription', 'taskBackgroundContext'],\n });\n};\n"],"names":["vlCoTLog","vlCurrentLog","llmCurrentLog","commonOutputFields","vlLocateParam","llmLocateParam","descriptionForAction","action","locatorSchemaTypeDescription","tab","fields","assert","z","shape","paramLines","getTypeName","field","_actualField__def","unwrapField","f","typeName","actualField","fieldTypeName","ifMidsceneLocatorField","_actualField__def_values","values","option","String","console","getDescription","key","Object","isOptional","keyWithOptional","description","paramLine","systemTemplateOfVLPlanning","actionSpace","vlMode","actionNameList","actionDescriptionList","actionList","bboxDescription","systemTemplateOfLLM","outputTemplate","systemPromptToTaskPlanning","planSchema","generateTaskBackgroundContext","userInstruction","log","userActionContext","automationUserPrompt","PromptTemplate"],"mappings":"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"}
1
+ {"version":3,"file":"ai-model/prompt/llm-planning.mjs","sources":["webpack://@midscene/core/./src/ai-model/prompt/llm-planning.ts"],"sourcesContent":["import assert from 'node:assert';\nimport type { DeviceAction } from '@/types';\nimport { PromptTemplate } from '@langchain/core/prompts';\nimport type { vlLocateMode } from '@midscene/shared/env';\nimport type { ResponseFormatJSONSchema } from 'openai/resources/index';\nimport type { ZodObject, z } from 'zod';\nimport { ifMidsceneLocatorField } from '../common';\nimport { bboxDescription } from './common';\n\n// Note: put the log field first to trigger the CoT\nconst vlCoTLog = `\"what_the_user_wants_to_do_next_by_instruction\": string, // What the user wants to do according to the instruction and previous logs. `;\nconst vlCurrentLog = `\"log\": string, // Log what the next one action (ONLY ONE!) you can do according to the screenshot and the instruction. The typical log looks like \"Now i want to use action '{ action-type }' to do .. first\". If no action should be done, log the reason. \". Use the same language as the user's instruction.`;\nconst llmCurrentLog = `\"log\": string, // Log what the next actions you can do according to the screenshot and the instruction. The typical log looks like \"Now i want to use action '{ action-type }' to do ..\". If no action should be done, log the reason. \". Use the same language as the user's instruction.`;\n\nconst commonOutputFields = `\"error\"?: string, // Error messages about unexpected situations, if any. Only think it is an error when the situation is not foreseeable according to the instruction. Use the same language as the user's instruction.\n \"more_actions_needed_by_instruction\": boolean, // Consider if there is still more action(s) to do after the action in \"Log\" is done, according to the instruction. If so, set this field to true. Otherwise, set it to false.`;\nconst vlLocateParam = () =>\n '{bbox: [number, number, number, number], prompt: string }';\nconst llmLocateParam = () => '{\"id\": string, \"prompt\": string}';\n\nexport const descriptionForAction = (\n action: DeviceAction<any>,\n locatorSchemaTypeDescription: string,\n) => {\n const tab = ' ';\n const fields: string[] = [];\n\n // Add the action type field\n fields.push(`- type: \"${action.name}\"`);\n\n // Handle paramSchema if it exists\n if (action.paramSchema) {\n assert(\n action.paramSchema.constructor.name === 'ZodObject',\n 'paramSchema must be a zod object',\n );\n // Try to extract parameter information from the zod schema\n // For zod object schemas, extract type information and descriptions\n const shape = (action.paramSchema as ZodObject<any>).shape;\n const paramLines: string[] = [];\n\n // Helper function to get type name from zod schema\n const getTypeName = (field: any): string => {\n // Recursively unwrap optional, nullable, and other wrapper types to get the actual inner type\n const unwrapField = (f: any): any => {\n if (!f._def) return f;\n\n const typeName = f._def.typeName;\n\n // Handle wrapper types that have innerType\n if (\n typeName === 'ZodOptional' ||\n typeName === 'ZodNullable' ||\n typeName === 'ZodDefault'\n ) {\n return unwrapField(f._def.innerType);\n }\n\n return f;\n };\n\n const actualField = unwrapField(field);\n const fieldTypeName = actualField._def?.typeName;\n\n if (fieldTypeName === 'ZodString') return 'string';\n if (fieldTypeName === 'ZodNumber') return 'number';\n if (fieldTypeName === 'ZodBoolean') return 'boolean';\n if (fieldTypeName === 'ZodArray') return 'array';\n if (fieldTypeName === 'ZodObject') {\n // Check if this is a passthrough object (like MidsceneLocation)\n if (ifMidsceneLocatorField(actualField)) {\n return locatorSchemaTypeDescription;\n }\n return 'object';\n }\n if (fieldTypeName === 'ZodEnum') {\n const values =\n (actualField._def?.values as unknown[] | undefined)\n ?.map((option: unknown) => String(`'${option}'`))\n .join(', ') ?? 'enum';\n\n return `enum(${values})`;\n }\n\n console.warn(\n 'failed to parse Zod type. This may lead to wrong params from the LLM.\\n',\n actualField._def,\n );\n return actualField.toString();\n };\n\n // Helper function to get description from zod schema\n const getDescription = (field: z.ZodTypeAny): string | null => {\n // Recursively unwrap optional, nullable, and other wrapper types to get the actual inner type\n const unwrapField = (f: any): any => {\n if (!f._def) return f;\n\n const typeName = f._def.typeName;\n\n // Handle wrapper types that have innerType\n if (\n typeName === 'ZodOptional' ||\n typeName === 'ZodNullable' ||\n typeName === 'ZodDefault'\n ) {\n return unwrapField(f._def.innerType);\n }\n\n return f;\n };\n\n // Check for direct description on the original field (wrapper may have description)\n if ('description' in field) {\n return field.description || null;\n }\n\n const actualField = unwrapField(field);\n\n // Check for description on the unwrapped field\n if ('description' in actualField) {\n return actualField.description || null;\n }\n\n // Check for MidsceneLocation fields and add description\n if (actualField._def?.typeName === 'ZodObject') {\n if ('midscene_location_field_flag' in actualField._def.shape()) {\n return 'Location information for the target element';\n }\n }\n\n return null;\n };\n\n for (const [key, field] of Object.entries(shape)) {\n if (field && typeof field === 'object') {\n // Check if field is optional\n const isOptional =\n typeof (field as any).isOptional === 'function' &&\n (field as any).isOptional();\n const keyWithOptional = isOptional ? `${key}?` : key;\n\n // Get the type name\n const typeName = getTypeName(field);\n\n // Get description\n const description = getDescription(field as z.ZodTypeAny);\n\n // Build param line for this field\n let paramLine = `${keyWithOptional}: ${typeName}`;\n if (description) {\n paramLine += ` // ${description}`;\n }\n\n paramLines.push(paramLine);\n }\n }\n\n if (paramLines.length > 0) {\n fields.push('- param:');\n for (const paramLine of paramLines) {\n fields.push(` - ${paramLine}`);\n }\n }\n }\n\n return `- ${action.name}, ${action.description || 'No description provided'}\n${tab}${fields.join(`\\n${tab}`)}\n`.trim();\n};\n\nconst systemTemplateOfVLPlanning = ({\n actionSpace,\n vlMode,\n}: {\n actionSpace: DeviceAction<any>[];\n vlMode: ReturnType<typeof vlLocateMode>;\n}) => {\n const actionNameList = actionSpace.map((action) => action.name).join(', ');\n const actionDescriptionList = actionSpace.map((action) => {\n return descriptionForAction(action, vlLocateParam());\n });\n const actionList = actionDescriptionList.join('\\n');\n\n return `\nTarget: User will give you a screenshot, an instruction and some previous logs indicating what have been done. Please tell what the next one action is (or null if no action should be done) to do the tasks the instruction requires. \n\nRestriction:\n- Don't give extra actions or plans beyond the instruction. ONLY plan for what the instruction requires. For example, don't try to submit the form if the instruction is only to fill something.\n- Always give ONLY ONE action in \\`log\\` field (or null if no action should be done), instead of multiple actions. Supported actions are ${actionNameList}.\n- Don't repeat actions in the previous logs.\n- Bbox is the bounding box of the element to be located. It's an array of 4 numbers, representing ${bboxDescription(vlMode)}.\n\nSupporting actions:\n${actionList}\n\nField description:\n* The \\`prompt\\` field inside the \\`locate\\` field is a short description that could be used to locate the element.\n\nReturn in JSON format:\n{\n ${vlCoTLog}\n ${vlCurrentLog}\n ${commonOutputFields}\n \"action\": \n {\n // one of the supporting actions\n } | null,\n ,\n \"sleep\"?: number, // The sleep time after the action, in milliseconds.\n}\n\nFor example, when the instruction is \"click 'Confirm' button, and click 'Yes' in popup\" and the log is \"I will use action Tap to click 'Confirm' button\", by viewing the screenshot and previous logs, you should consider: We have already clicked the 'Confirm' button, so next we should find and click 'Yes' in popup.\n\nthis and output the JSON:\n\n{\n \"what_the_user_wants_to_do_next_by_instruction\": \"We have already clicked the 'Confirm' button, so next we should find and click 'Yes' in popup\",\n \"log\": \"I will use action Tap to click 'Yes' in popup\",\n \"more_actions_needed_by_instruction\": false,\n \"action\": {\n \"type\": \"Tap\",\n \"param\": {\n \"locate\": {\n \"bbox\": [100, 100, 200, 200],\n \"prompt\": \"The 'Yes' button in popup\"\n }\n }\n }\n}\n`;\n};\n\nconst systemTemplateOfLLM = ({\n actionSpace,\n}: { actionSpace: DeviceAction<any>[] }) => {\n const actionNameList = actionSpace.map((action) => action.name).join(' / ');\n const actionDescriptionList = actionSpace.map((action) => {\n return descriptionForAction(action, llmLocateParam());\n });\n const actionList = actionDescriptionList.join('\\n');\n\n return `\n## Role\n\nYou are a versatile professional in software UI automation. Your outstanding contributions will impact the user experience of billions of users.\n\n## Objective\n\n- Decompose the instruction user asked into a series of actions\n- Locate the target element if possible\n- If the instruction cannot be accomplished, give a further plan.\n\n## Workflow\n\n1. Receive the screenshot, element description of screenshot(if any), user's instruction and previous logs.\n2. Decompose the user's task into a sequence of feasible actions, and place it in the \\`actions\\` field. There are different types of actions (${actionNameList}). The \"About the action\" section below will give you more details.\n3. Consider whether the user's instruction will be accomplished after the actions you composed.\n- If the instruction is accomplished, set \\`more_actions_needed_by_instruction\\` to false.\n- If more actions are needed, set \\`more_actions_needed_by_instruction\\` to true. Get ready to hand over to the next talent people like you. Carefully log what have been done in the \\`log\\` field, he or she will continue the task according to your logs.\n4. If the task is not feasible on this page, set \\`error\\` field to the reason.\n\n## Constraints\n\n- All the actions you composed MUST be feasible, which means all the action fields can be filled with the page context information you get. If not, don't plan this action.\n- Trust the \"What have been done\" field about the task (if any), don't repeat actions in it.\n- Respond only with valid JSON. Do not write an introduction or summary or markdown prefix like \\`\\`\\`json\\`\\`\\`.\n- If the screenshot and the instruction are totally irrelevant, set reason in the \\`error\\` field.\n\n## About the \\`actions\\` field\n\nThe \\`locate\\` param is commonly used in the \\`param\\` field of the action, means to locate the target element to perform the action, it conforms to the following scheme:\n\ntype LocateParam = {\n \"id\": string, // the id of the element found. It should either be the id marked with a rectangle in the screenshot or the id described in the description.\n \"prompt\"?: string // the description of the element to find. It can only be omitted when locate is null.\n} | null // If it's not on the page, the LocateParam should be null\n\n## Supported actions\n\nEach action has a \\`type\\` and corresponding \\`param\\`. To be detailed:\n${actionList}\n\n`.trim();\n};\n\nconst outputTemplate = `\n## Output JSON Format:\n\nThe JSON format is as follows:\n\n{\n \"actions\": [\n // ... some actions\n ],\n ${llmCurrentLog}\n ${commonOutputFields}\n}\n\n## Examples\n\n### Example: Decompose a task\n\nWhen you received the following information:\n\n* Instruction: 'Click the language switch button, wait 1s, click \"English\"'\n* Logs: null\n* Page Context (screenshot and description) shows: There is a language switch button, and the \"English\" option is not shown in the screenshot now.\n\nBy viewing the page screenshot and description, you should consider this and output the JSON:\n\n* The user intent is: tap the switch button, sleep, and tap the 'English' option\n* The language switch button is shown in the screenshot, and can be located by the page description or the id marked with a rectangle. So we can plan a Tap action to do this.\n* Plan a Sleep action to wait for 1 second to ensure the language options are displayed.\n* The \"English\" option button is not shown in the screenshot now, it means it may only show after the previous actions are finished. So don't plan any action to do this.\n* Log what these action do: Click the language switch button to open the language options. Wait for 1 second.\n* The task cannot be accomplished (because the last tapping action is not finished yet), so the \\`more_actions_needed_by_instruction\\` field is true. The \\`error\\` field is null.\n\n{\n \"actions\":[\n {\n \"thought\": \"Click the language switch button to open the language options.\",\n \"type\": \"Tap\", \n \"param\": {\n \"locate\": { id: \"c81c4e9a33\", prompt: \"The language switch button\" }\n }\n },\n {\n \"thought\": \"Wait for 1 second to ensure the language options are displayed.\",\n \"type\": \"Sleep\",\n \"param\": { \"timeMs\": 1000 },\n }\n ],\n \"error\": null,\n \"more_actions_needed_by_instruction\": true,\n \"log\": \"Click the language switch button to open the language options. Wait for 1 second\",\n}\n\n### Example: What NOT to do\nWrong output:\n{\n \"actions\":[\n {\n \"thought\": \"Click the language switch button to open the language options.\",\n \"type\": \"Tap\",\n \"param\": {\n \"locate\": { \"id\": \"c81c4e9a33\" } // WRONG: prompt is missing, this is not a valid LocateParam\n }\n },\n {\n \"thought\": \"Click the English option\",\n \"type\": \"Tap\", \n \"param\": {\n \"locate\": null // WRONG: if the element is not on the page, you should not plan this action\n }\n }\n ],\n \"more_actions_needed_by_instruction\": false, // WRONG: should be true\n \"log\": \"Click the language switch button to open the language options\",\n}\n`;\n\nexport async function systemPromptToTaskPlanning({\n actionSpace,\n vlMode,\n}: {\n actionSpace: DeviceAction<any>[];\n vlMode: ReturnType<typeof vlLocateMode>;\n}) {\n if (vlMode) {\n return systemTemplateOfVLPlanning({ actionSpace, vlMode });\n }\n\n return `${systemTemplateOfLLM({ actionSpace })}\\n\\n${outputTemplate}`;\n}\n\nexport const planSchema: ResponseFormatJSONSchema = {\n type: 'json_schema',\n json_schema: {\n name: 'action_items',\n strict: false,\n schema: {\n type: 'object',\n strict: false,\n properties: {\n actions: {\n type: 'array',\n items: {\n type: 'object',\n strict: false,\n properties: {\n thought: {\n type: 'string',\n description:\n 'Reasons for generating this task, and why this task is feasible on this page',\n },\n type: {\n type: 'string',\n description: 'Type of action',\n },\n param: {\n anyOf: [\n { type: 'null' },\n {\n type: 'object',\n additionalProperties: true,\n },\n ],\n description: 'Parameter of the action',\n },\n locate: {\n type: ['object', 'null'],\n properties: {\n id: { type: 'string' },\n prompt: { type: 'string' },\n },\n required: ['id', 'prompt'],\n additionalProperties: false,\n description: 'Location information for the target element',\n },\n },\n required: ['thought', 'type', 'param', 'locate'],\n additionalProperties: false,\n },\n description: 'List of actions to be performed',\n },\n more_actions_needed_by_instruction: {\n type: 'boolean',\n description:\n 'If all the actions described in the instruction have been covered by this action and logs, set this field to false.',\n },\n log: {\n type: 'string',\n description:\n 'Log what these planned actions do. Do not include further actions that have not been planned.',\n },\n error: {\n type: ['string', 'null'],\n description: 'Error messages about unexpected situations',\n },\n },\n required: [\n 'actions',\n 'more_actions_needed_by_instruction',\n 'log',\n 'error',\n ],\n additionalProperties: false,\n },\n },\n};\n\nexport const generateTaskBackgroundContext = (\n userInstruction: string,\n log?: string,\n userActionContext?: string,\n) => {\n if (log) {\n return `\nHere is the user's instruction:\n\n<instruction>\n <high_priority_knowledge>\n ${userActionContext}\n </high_priority_knowledge>\n\n ${userInstruction}\n</instruction>\n\nThese are the logs from previous executions, which indicate what was done in the previous actions.\nDo NOT repeat these actions.\n<previous_logs>\n${log}\n</previous_logs>\n`;\n }\n\n return `\nHere is the user's instruction:\n<instruction>\n <high_priority_knowledge>\n ${userActionContext}\n </high_priority_knowledge>\n\n ${userInstruction}\n</instruction>\n`;\n};\n\nexport const automationUserPrompt = (\n vlMode: ReturnType<typeof vlLocateMode>,\n) => {\n if (vlMode) {\n return new PromptTemplate({\n template: '{taskBackgroundContext}',\n inputVariables: ['taskBackgroundContext'],\n });\n }\n\n return new PromptTemplate({\n template: `\npageDescription:\n=====================================\n{pageDescription}\n=====================================\n\n{taskBackgroundContext}`,\n inputVariables: ['pageDescription', 'taskBackgroundContext'],\n });\n};\n"],"names":["vlCoTLog","vlCurrentLog","llmCurrentLog","commonOutputFields","vlLocateParam","llmLocateParam","descriptionForAction","action","locatorSchemaTypeDescription","tab","fields","assert","shape","paramLines","getTypeName","field","_actualField__def","unwrapField","f","typeName","actualField","fieldTypeName","ifMidsceneLocatorField","_actualField__def_values","values","option","String","console","getDescription","key","Object","isOptional","keyWithOptional","description","paramLine","systemTemplateOfVLPlanning","actionSpace","vlMode","actionNameList","actionDescriptionList","actionList","bboxDescription","systemTemplateOfLLM","outputTemplate","systemPromptToTaskPlanning","planSchema","generateTaskBackgroundContext","userInstruction","log","userActionContext","automationUserPrompt","PromptTemplate"],"mappings":"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"}
package/dist/es/index.mjs CHANGED
@@ -4,8 +4,8 @@ import insight from "./insight/index.mjs";
4
4
  import { getVersion } from "./utils.mjs";
5
5
  import { AiLocateElement, PointSchema, RectSchema, SizeSchema, TMultimodalPromptSchema, TUserPromptSchema, describeUserPage, getMidsceneLocationSchema, plan } from "./ai-model/index.mjs";
6
6
  import { MIDSCENE_MODEL_NAME } from "@midscene/shared/env";
7
- import { Agent } from "./agent/index.mjs";
7
+ import { Agent, createAgent } from "./agent/index.mjs";
8
8
  const src = insight;
9
- export { Agent, AiLocateElement, Executor, insight as Insight, MIDSCENE_MODEL_NAME, PointSchema, RectSchema, SizeSchema, TMultimodalPromptSchema, TUserPromptSchema, src as default, describeUserPage, getMidsceneLocationSchema, getVersion, plan, z };
9
+ export { Agent, AiLocateElement, Executor, insight as Insight, MIDSCENE_MODEL_NAME, PointSchema, RectSchema, SizeSchema, TMultimodalPromptSchema, TUserPromptSchema, createAgent, src as default, describeUserPage, getMidsceneLocationSchema, getVersion, plan, z };
10
10
 
11
11
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["webpack://@midscene/core/./src/index.ts"],"sourcesContent":["import { z } from 'zod';\nimport { Executor } from './ai-model/action-executor';\nimport Insight from './insight/index';\nimport { getVersion } from './utils';\n\nexport {\n plan,\n describeUserPage,\n AiLocateElement,\n getMidsceneLocationSchema,\n type MidsceneLocationResultType,\n PointSchema,\n SizeSchema,\n RectSchema,\n TMultimodalPromptSchema,\n TUserPromptSchema,\n type TMultimodalPrompt,\n type TUserPrompt,\n} from './ai-model/index';\n\nexport { MIDSCENE_MODEL_NAME } from '@midscene/shared/env';\n\nexport type * from './types';\n\nexport { z };\n\nexport default Insight;\nexport { Executor, Insight, getVersion };\n\nexport type {\n MidsceneYamlScript,\n MidsceneYamlTask,\n MidsceneYamlFlowItem,\n MidsceneYamlFlowItemAIRightClick,\n MidsceneYamlFlowItemAIDoubleClick,\n MidsceneYamlConfigResult,\n LocateOption,\n DetailedLocateParam,\n} from './yaml';\n\nexport { Agent, type AgentOpt } from './agent';\n"],"names":["Insight"],"mappings":";;;;;;;AA0BA,YAAeA"}
1
+ {"version":3,"file":"index.mjs","sources":["webpack://@midscene/core/./src/index.ts"],"sourcesContent":["import { z } from 'zod';\nimport { Executor } from './ai-model/action-executor';\nimport Insight from './insight/index';\nimport { getVersion } from './utils';\n\nexport {\n plan,\n describeUserPage,\n AiLocateElement,\n getMidsceneLocationSchema,\n type MidsceneLocationResultType,\n PointSchema,\n SizeSchema,\n RectSchema,\n TMultimodalPromptSchema,\n TUserPromptSchema,\n type TMultimodalPrompt,\n type TUserPrompt,\n} from './ai-model/index';\n\nexport { MIDSCENE_MODEL_NAME } from '@midscene/shared/env';\n\nexport type * from './types';\n\nexport { z };\n\nexport default Insight;\nexport { Executor, Insight, getVersion };\n\nexport type {\n MidsceneYamlScript,\n MidsceneYamlTask,\n MidsceneYamlFlowItem,\n MidsceneYamlFlowItemAIRightClick,\n MidsceneYamlFlowItemAIDoubleClick,\n MidsceneYamlConfigResult,\n LocateOption,\n DetailedLocateParam,\n} from './yaml';\n\nexport { Agent, type AgentOpt, createAgent } from './agent';\n"],"names":["Insight"],"mappings":";;;;;;;AA0BA,YAAeA"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.mjs","sources":["webpack://@midscene/core/./src/types.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { NodeType } from '@midscene/shared/constants';\nimport type {\n BaseElement,\n ElementTreeNode,\n Rect,\n Size,\n} from '@midscene/shared/types';\nimport type { ChatCompletionMessageParam } from 'openai/resources/index';\nimport type { z } from 'zod';\nimport type { TUserPrompt } from './ai-model/common';\nimport type { DetailedLocateParam, MidsceneYamlFlowItem } from './yaml';\n\nexport type {\n ElementTreeNode,\n BaseElement,\n Rect,\n Size,\n Point,\n} from '@midscene/shared/types';\nexport * from './yaml';\n\nexport type AIUsageInfo = Record<string, any> & {\n prompt_tokens: number | undefined;\n completion_tokens: number | undefined;\n total_tokens: number | undefined;\n time_cost: number | undefined;\n model_name: string | undefined;\n model_description: string | undefined;\n intent: string | undefined;\n};\n\n/**\n * openai\n *\n */\nexport enum AIResponseFormat {\n JSON = 'json_object',\n TEXT = 'text',\n}\n\nexport type AISingleElementResponseById = {\n id: string;\n reason?: string;\n text?: string;\n xpaths?: string[];\n};\n\nexport type AISingleElementResponseByPosition = {\n position?: {\n x: number;\n y: number;\n };\n bbox?: [number, number, number, number];\n reason: string;\n text: string;\n};\n\nexport type AISingleElementResponse = AISingleElementResponseById;\nexport interface AIElementLocatorResponse {\n elements: {\n id: string;\n reason?: string;\n text?: string;\n xpaths?: string[];\n }[];\n bbox?: [number, number, number, number];\n isOrderSensitive?: boolean;\n errors?: string[];\n}\n\nexport interface AIElementCoordinatesResponse {\n bbox: [number, number, number, number];\n isOrderSensitive?: boolean;\n errors?: string[];\n}\n\nexport type AIElementResponse =\n | AIElementLocatorResponse\n | AIElementCoordinatesResponse;\n\nexport interface AIDataExtractionResponse<DataDemand> {\n data: DataDemand;\n errors?: string[];\n thought?: string;\n}\n\nexport interface AISectionLocatorResponse {\n bbox: [number, number, number, number];\n references_bbox?: [number, number, number, number][];\n error?: string;\n}\n\nexport interface AIAssertionResponse {\n pass: boolean;\n thought: string;\n}\n\nexport interface AIDescribeElementResponse {\n description: string;\n error?: string;\n}\n\nexport interface LocatorValidatorOption {\n centerDistanceThreshold?: number;\n}\n\nexport interface LocateValidatorResult {\n pass: boolean;\n rect: Rect;\n center: [number, number];\n centerDistance?: number;\n}\n\nexport interface AgentDescribeElementAtPointResult {\n prompt: string;\n deepThink: boolean;\n verifyResult?: LocateValidatorResult;\n}\n\n/**\n * context\n */\n\nexport abstract class UIContext<ElementType extends BaseElement = BaseElement> {\n abstract screenshotBase64: string;\n\n abstract tree: ElementTreeNode<ElementType>;\n\n abstract size: Size;\n\n abstract _isFrozen?: boolean;\n}\n\n/**\n * insight\n */\n\nexport type CallAIFn = <T>(\n messages: ChatCompletionMessageParam[],\n) => Promise<T>;\n\nexport interface InsightOptions {\n taskInfo?: Omit<InsightTaskInfo, 'durationMs'>;\n aiVendorFn?: CallAIFn;\n}\n\nexport type EnsureObject<T> = { [K in keyof T]: any };\n\nexport type InsightAction = 'locate' | 'extract' | 'assert' | 'describe';\n\nexport type InsightExtractParam = string | Record<string, string>;\n\nexport type LocateResultElement = {\n center: [number, number];\n rect: Rect;\n id: string;\n indexId?: number;\n xpaths: string[];\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n isOrderSensitive?: boolean;\n};\n\nexport interface LocateResult {\n element: LocateResultElement | null;\n rect?: Rect;\n}\n\nexport interface InsightTaskInfo {\n durationMs: number;\n formatResponse?: string;\n rawResponse?: string;\n usage?: AIUsageInfo;\n searchArea?: Rect;\n searchAreaRawResponse?: string;\n searchAreaUsage?: AIUsageInfo;\n}\n\nexport interface DumpMeta {\n sdkVersion: string;\n logTime: number;\n}\n\nexport interface ReportDumpWithAttributes {\n dumpString: string;\n attributes?: Record<string, any>;\n}\n\nexport interface InsightDump extends DumpMeta {\n type: 'locate' | 'extract' | 'assert';\n logId: string;\n userQuery: {\n element?: TUserPrompt;\n dataDemand?: InsightExtractParam;\n assertion?: TUserPrompt;\n };\n matchedElement: BaseElement[];\n matchedRect?: Rect;\n deepThink?: boolean;\n data: any;\n assertionPass?: boolean;\n assertionThought?: string;\n taskInfo: InsightTaskInfo;\n error?: string;\n output?: any;\n}\n\nexport type PartialInsightDumpFromSDK = Omit<\n InsightDump,\n 'sdkVersion' | 'logTime' | 'logId' | 'model_name'\n>;\n\nexport type DumpSubscriber = (dump: InsightDump) => Promise<void> | void;\n\n// intermediate variables to optimize the return value by AI\nexport interface LiteUISection {\n name: string;\n description: string;\n sectionCharacteristics: string;\n textIds: string[];\n}\n\nexport type ElementById = (id: string) => BaseElement | null;\n\nexport type InsightAssertionResponse = AIAssertionResponse & {\n usage?: AIUsageInfo;\n};\n\n/**\n * agent\n */\n\nexport type OnTaskStartTip = (tip: string) => Promise<void> | void;\n\nexport interface AgentWaitForOpt {\n checkIntervalMs?: number;\n timeoutMs?: number;\n}\n\nexport interface AgentAssertOpt {\n keepRawResponse?: boolean;\n}\n\n/**\n * planning\n *\n */\n\nexport interface PlanningLocateParam extends DetailedLocateParam {\n id?: string;\n bbox?: [number, number, number, number];\n}\n\nexport interface PlanningAction<ParamType = any> {\n thought?: string;\n type: string;\n param: ParamType;\n locate?: PlanningLocateParam | null;\n}\n\nexport interface PlanningAIResponse {\n action?: PlanningAction; // this is the qwen mode\n actions?: PlanningAction[];\n more_actions_needed_by_instruction: boolean;\n log: string;\n sleep?: number;\n error?: string;\n usage?: AIUsageInfo;\n rawResponse?: string;\n yamlFlow?: MidsceneYamlFlowItem[];\n yamlString?: string;\n}\n\nexport type PlanningActionParamTap = null;\nexport type PlanningActionParamHover = null;\nexport type PlanningActionParamRightClick = null;\n\nexport interface PlanningActionParamInputOrKeyPress {\n value: string;\n autoDismissKeyboard?: boolean;\n}\n\nexport interface PlanningActionParamSleep {\n timeMs: number;\n}\n\nexport interface PlanningActionParamError {\n thought: string;\n}\n\nexport type PlanningActionParamWaitFor = AgentWaitForOpt & {};\n\nexport interface AndroidLongPressParam {\n duration?: number;\n}\n\nexport interface AndroidPullParam {\n direction: 'up' | 'down';\n distance?: number;\n duration?: number;\n}\n/**\n * misc\n */\n\nexport interface Color {\n name: string;\n hex: string;\n}\n\nexport interface BaseAgentParserOpt {\n selector?: string;\n}\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\nexport interface PuppeteerParserOpt extends BaseAgentParserOpt {}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\nexport interface PlaywrightParserOpt extends BaseAgentParserOpt {}\n\n/*\naction\n*/\nexport interface ExecutionTaskProgressOptions {\n onTaskStart?: (task: ExecutionTask) => Promise<void> | void;\n}\n\nexport interface ExecutionRecorderItem {\n type: 'screenshot';\n ts: number;\n screenshot?: string;\n timing?: string;\n}\n\nexport type ExecutionTaskType =\n | 'Planning'\n | 'Insight'\n | 'Action'\n | 'Assertion'\n | 'Log';\n\nexport interface ExecutorContext {\n task: ExecutionTask;\n element?: LocateResultElement | null;\n}\n\nexport interface ExecutionTaskApply<\n Type extends ExecutionTaskType = any,\n TaskParam = any,\n TaskOutput = any,\n TaskLog = any,\n> {\n type: Type;\n subType?: string;\n param?: TaskParam;\n thought?: string;\n locate?: PlanningLocateParam | null;\n uiContext?: UIContext;\n executor: (\n param: TaskParam,\n context: ExecutorContext,\n ) => // biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\n | Promise<ExecutionTaskReturn<TaskOutput, TaskLog> | undefined | void>\n | undefined\n | void;\n}\n\nexport interface ExecutionTaskHitBy {\n from: string;\n context: Record<string, any>;\n}\n\nexport interface ExecutionTaskReturn<TaskOutput = unknown, TaskLog = unknown> {\n output?: TaskOutput;\n log?: TaskLog;\n recorder?: ExecutionRecorderItem[];\n hitBy?: ExecutionTaskHitBy;\n}\n\nexport type ExecutionTask<\n E extends ExecutionTaskApply<any, any, any> = ExecutionTaskApply<\n any,\n any,\n any\n >,\n> = E &\n ExecutionTaskReturn<\n E extends ExecutionTaskApply<any, any, infer TaskOutput, any>\n ? TaskOutput\n : unknown,\n E extends ExecutionTaskApply<any, any, any, infer TaskLog>\n ? TaskLog\n : unknown\n > & {\n status: 'pending' | 'running' | 'finished' | 'failed' | 'cancelled';\n error?: Error;\n errorMessage?: string;\n errorStack?: string;\n timing?: {\n start: number;\n end?: number;\n cost?: number;\n };\n usage?: AIUsageInfo;\n };\n\nexport interface ExecutionDump extends DumpMeta {\n name: string;\n description?: string;\n tasks: ExecutionTask[];\n}\n\n/*\ntask - insight-locate\n*/\nexport type ExecutionTaskInsightLocateParam = PlanningLocateParam;\n\nexport interface ExecutionTaskInsightLocateOutput {\n element: LocateResultElement | null;\n}\n\nexport interface ExecutionTaskInsightDumpLog {\n dump?: InsightDump;\n}\n\nexport type ExecutionTaskInsightLocateApply = ExecutionTaskApply<\n 'Insight',\n ExecutionTaskInsightLocateParam,\n ExecutionTaskInsightLocateOutput,\n ExecutionTaskInsightDumpLog\n>;\n\nexport type ExecutionTaskInsightLocate =\n ExecutionTask<ExecutionTaskInsightLocateApply>;\n\n/*\ntask - insight-query\n*/\nexport interface ExecutionTaskInsightQueryParam {\n dataDemand: InsightExtractParam;\n}\n\nexport interface ExecutionTaskInsightQueryOutput {\n data: any;\n}\n\nexport type ExecutionTaskInsightQueryApply = ExecutionTaskApply<\n 'Insight',\n ExecutionTaskInsightQueryParam,\n any,\n ExecutionTaskInsightDumpLog\n>;\n\nexport type ExecutionTaskInsightQuery =\n ExecutionTask<ExecutionTaskInsightQueryApply>;\n\n/*\ntask - assertion\n*/\nexport interface ExecutionTaskInsightAssertionParam {\n assertion: string;\n}\n\nexport type ExecutionTaskInsightAssertionApply = ExecutionTaskApply<\n 'Insight',\n ExecutionTaskInsightAssertionParam,\n InsightAssertionResponse,\n ExecutionTaskInsightDumpLog\n>;\n\nexport type ExecutionTaskInsightAssertion =\n ExecutionTask<ExecutionTaskInsightAssertionApply>;\n\n/*\ntask - action (i.e. interact) \n*/\nexport type ExecutionTaskActionApply<ActionParam = any> = ExecutionTaskApply<\n 'Action',\n ActionParam,\n void,\n void\n>;\n\nexport type ExecutionTaskAction = ExecutionTask<ExecutionTaskActionApply>;\n\n/*\ntask - Log\n*/\n\nexport type ExecutionTaskLogApply<\n LogParam = {\n content: string;\n },\n> = ExecutionTaskApply<'Log', LogParam, void, void>;\n\nexport type ExecutionTaskLog = ExecutionTask<ExecutionTaskLogApply>;\n\n/*\ntask - planning\n*/\n\nexport type ExecutionTaskPlanningApply = ExecutionTaskApply<\n 'Planning',\n {\n userInstruction: string;\n log?: string;\n },\n PlanningAIResponse\n>;\n\nexport type ExecutionTaskPlanning = ExecutionTask<ExecutionTaskPlanningApply>;\n\n/*\nGrouped dump\n*/\nexport interface GroupedActionDump {\n groupName: string;\n groupDescription?: string;\n modelBriefs: string[];\n executions: ExecutionDump[];\n}\n\nexport type InterfaceType =\n | 'puppeteer'\n | 'playwright'\n | 'static'\n | 'chrome-extension-proxy'\n | 'android'\n | string;\n\nexport interface StreamingCodeGenerationOptions {\n /** Whether to enable streaming output */\n stream?: boolean;\n /** Callback function to handle streaming chunks */\n onChunk?: StreamingCallback;\n /** Callback function to handle streaming completion */\n onComplete?: (finalCode: string) => void;\n /** Callback function to handle streaming errors */\n onError?: (error: Error) => void;\n}\n\nexport type StreamingCallback = (chunk: CodeGenerationChunk) => void;\n\nexport interface CodeGenerationChunk {\n /** The incremental content chunk */\n content: string;\n /** The reasoning content */\n reasoning_content: string;\n /** The accumulated content so far */\n accumulated: string;\n /** Whether this is the final chunk */\n isComplete: boolean;\n /** Token usage information if available */\n usage?: AIUsageInfo;\n}\n\nexport interface StreamingAIResponse {\n /** The final accumulated content */\n content: string;\n /** Token usage information */\n usage?: AIUsageInfo;\n /** Whether the response was streamed */\n isStreamed: boolean;\n}\n\nexport interface DeviceAction<T = any> {\n name: string;\n description?: string;\n interfaceAlias?: string;\n paramSchema?: z.ZodType<T>;\n call: (param: T, context: ExecutorContext) => Promise<void> | void;\n}\n\n/**\n * Web-specific types\n */\nexport interface WebElementInfo extends BaseElement {\n id: string;\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n}\n\nexport type WebUIContext = UIContext<WebElementInfo>;\n"],"names":["AIResponseFormat","UIContext"],"mappings":";AAqCO,IAAKA,yBAAgBA,WAAAA,GAAAA,SAAhBA,gBAAgB;;;WAAhBA;;AAwFL,MAAeC;AAQtB"}
1
+ {"version":3,"file":"types.mjs","sources":["webpack://@midscene/core/./src/types.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { NodeType } from '@midscene/shared/constants';\nimport type { TModelConfigFn } from '@midscene/shared/env';\nimport type {\n BaseElement,\n ElementTreeNode,\n Rect,\n Size,\n} from '@midscene/shared/types';\nimport type { ChatCompletionMessageParam } from 'openai/resources/index';\nimport type { z } from 'zod';\nimport type { TUserPrompt } from './ai-model/common';\nimport type { DetailedLocateParam, MidsceneYamlFlowItem } from './yaml';\n\nexport type {\n ElementTreeNode,\n BaseElement,\n Rect,\n Size,\n Point,\n} from '@midscene/shared/types';\nexport * from './yaml';\n\nexport type AIUsageInfo = Record<string, any> & {\n prompt_tokens: number | undefined;\n completion_tokens: number | undefined;\n total_tokens: number | undefined;\n time_cost: number | undefined;\n model_name: string | undefined;\n model_description: string | undefined;\n intent: string | undefined;\n};\n\n/**\n * openai\n *\n */\nexport enum AIResponseFormat {\n JSON = 'json_object',\n TEXT = 'text',\n}\n\nexport type AISingleElementResponseById = {\n id: string;\n reason?: string;\n text?: string;\n xpaths?: string[];\n};\n\nexport type AISingleElementResponseByPosition = {\n position?: {\n x: number;\n y: number;\n };\n bbox?: [number, number, number, number];\n reason: string;\n text: string;\n};\n\nexport type AISingleElementResponse = AISingleElementResponseById;\nexport interface AIElementLocatorResponse {\n elements: {\n id: string;\n reason?: string;\n text?: string;\n xpaths?: string[];\n }[];\n bbox?: [number, number, number, number];\n isOrderSensitive?: boolean;\n errors?: string[];\n}\n\nexport interface AIElementCoordinatesResponse {\n bbox: [number, number, number, number];\n isOrderSensitive?: boolean;\n errors?: string[];\n}\n\nexport type AIElementResponse =\n | AIElementLocatorResponse\n | AIElementCoordinatesResponse;\n\nexport interface AIDataExtractionResponse<DataDemand> {\n data: DataDemand;\n errors?: string[];\n thought?: string;\n}\n\nexport interface AISectionLocatorResponse {\n bbox: [number, number, number, number];\n references_bbox?: [number, number, number, number][];\n error?: string;\n}\n\nexport interface AIAssertionResponse {\n pass: boolean;\n thought: string;\n}\n\nexport interface AIDescribeElementResponse {\n description: string;\n error?: string;\n}\n\nexport interface LocatorValidatorOption {\n centerDistanceThreshold?: number;\n}\n\nexport interface LocateValidatorResult {\n pass: boolean;\n rect: Rect;\n center: [number, number];\n centerDistance?: number;\n}\n\nexport interface AgentDescribeElementAtPointResult {\n prompt: string;\n deepThink: boolean;\n verifyResult?: LocateValidatorResult;\n}\n\n/**\n * context\n */\n\nexport abstract class UIContext<ElementType extends BaseElement = BaseElement> {\n abstract screenshotBase64: string;\n\n abstract tree: ElementTreeNode<ElementType>;\n\n abstract size: Size;\n\n abstract _isFrozen?: boolean;\n}\n\n/**\n * insight\n */\n\nexport type CallAIFn = <T>(\n messages: ChatCompletionMessageParam[],\n) => Promise<T>;\n\nexport interface InsightOptions {\n taskInfo?: Omit<InsightTaskInfo, 'durationMs'>;\n aiVendorFn?: CallAIFn;\n}\n\nexport type EnsureObject<T> = { [K in keyof T]: any };\n\nexport type InsightAction = 'locate' | 'extract' | 'assert' | 'describe';\n\nexport type InsightExtractParam = string | Record<string, string>;\n\nexport type LocateResultElement = {\n center: [number, number];\n rect: Rect;\n id: string;\n indexId?: number;\n xpaths: string[];\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n isOrderSensitive?: boolean;\n};\n\nexport interface LocateResult {\n element: LocateResultElement | null;\n rect?: Rect;\n}\n\nexport interface InsightTaskInfo {\n durationMs: number;\n formatResponse?: string;\n rawResponse?: string;\n usage?: AIUsageInfo;\n searchArea?: Rect;\n searchAreaRawResponse?: string;\n searchAreaUsage?: AIUsageInfo;\n}\n\nexport interface DumpMeta {\n sdkVersion: string;\n logTime: number;\n}\n\nexport interface ReportDumpWithAttributes {\n dumpString: string;\n attributes?: Record<string, any>;\n}\n\nexport interface InsightDump extends DumpMeta {\n type: 'locate' | 'extract' | 'assert';\n logId: string;\n userQuery: {\n element?: TUserPrompt;\n dataDemand?: InsightExtractParam;\n assertion?: TUserPrompt;\n };\n matchedElement: BaseElement[];\n matchedRect?: Rect;\n deepThink?: boolean;\n data: any;\n assertionPass?: boolean;\n assertionThought?: string;\n taskInfo: InsightTaskInfo;\n error?: string;\n output?: any;\n}\n\nexport type PartialInsightDumpFromSDK = Omit<\n InsightDump,\n 'sdkVersion' | 'logTime' | 'logId' | 'model_name'\n>;\n\nexport type DumpSubscriber = (dump: InsightDump) => Promise<void> | void;\n\n// intermediate variables to optimize the return value by AI\nexport interface LiteUISection {\n name: string;\n description: string;\n sectionCharacteristics: string;\n textIds: string[];\n}\n\nexport type ElementById = (id: string) => BaseElement | null;\n\nexport type InsightAssertionResponse = AIAssertionResponse & {\n usage?: AIUsageInfo;\n};\n\n/**\n * agent\n */\n\nexport type OnTaskStartTip = (tip: string) => Promise<void> | void;\n\nexport interface AgentWaitForOpt {\n checkIntervalMs?: number;\n timeoutMs?: number;\n}\n\nexport interface AgentAssertOpt {\n keepRawResponse?: boolean;\n}\n\n/**\n * planning\n *\n */\n\nexport interface PlanningLocateParam extends DetailedLocateParam {\n id?: string;\n bbox?: [number, number, number, number];\n}\n\nexport interface PlanningAction<ParamType = any> {\n thought?: string;\n type: string;\n param: ParamType;\n locate?: PlanningLocateParam | null;\n}\n\nexport interface PlanningAIResponse {\n action?: PlanningAction; // this is the qwen mode\n actions?: PlanningAction[];\n more_actions_needed_by_instruction: boolean;\n log: string;\n sleep?: number;\n error?: string;\n usage?: AIUsageInfo;\n rawResponse?: string;\n yamlFlow?: MidsceneYamlFlowItem[];\n yamlString?: string;\n}\n\nexport type PlanningActionParamTap = null;\nexport type PlanningActionParamHover = null;\nexport type PlanningActionParamRightClick = null;\n\nexport interface PlanningActionParamInputOrKeyPress {\n value: string;\n autoDismissKeyboard?: boolean;\n}\n\nexport interface PlanningActionParamSleep {\n timeMs: number;\n}\n\nexport interface PlanningActionParamError {\n thought: string;\n}\n\nexport type PlanningActionParamWaitFor = AgentWaitForOpt & {};\n\nexport interface AndroidLongPressParam {\n duration?: number;\n}\n\nexport interface AndroidPullParam {\n direction: 'up' | 'down';\n distance?: number;\n duration?: number;\n}\n/**\n * misc\n */\n\nexport interface Color {\n name: string;\n hex: string;\n}\n\nexport interface BaseAgentParserOpt {\n selector?: string;\n}\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\nexport interface PuppeteerParserOpt extends BaseAgentParserOpt {}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\nexport interface PlaywrightParserOpt extends BaseAgentParserOpt {}\n\n/*\naction\n*/\nexport interface ExecutionTaskProgressOptions {\n onTaskStart?: (task: ExecutionTask) => Promise<void> | void;\n}\n\nexport interface ExecutionRecorderItem {\n type: 'screenshot';\n ts: number;\n screenshot?: string;\n timing?: string;\n}\n\nexport type ExecutionTaskType =\n | 'Planning'\n | 'Insight'\n | 'Action'\n | 'Assertion'\n | 'Log';\n\nexport interface ExecutorContext {\n task: ExecutionTask;\n element?: LocateResultElement | null;\n}\n\nexport interface ExecutionTaskApply<\n Type extends ExecutionTaskType = any,\n TaskParam = any,\n TaskOutput = any,\n TaskLog = any,\n> {\n type: Type;\n subType?: string;\n param?: TaskParam;\n thought?: string;\n locate?: PlanningLocateParam | null;\n uiContext?: UIContext;\n executor: (\n param: TaskParam,\n context: ExecutorContext,\n ) => // biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\n | Promise<ExecutionTaskReturn<TaskOutput, TaskLog> | undefined | void>\n | undefined\n | void;\n}\n\nexport interface ExecutionTaskHitBy {\n from: string;\n context: Record<string, any>;\n}\n\nexport interface ExecutionTaskReturn<TaskOutput = unknown, TaskLog = unknown> {\n output?: TaskOutput;\n log?: TaskLog;\n recorder?: ExecutionRecorderItem[];\n hitBy?: ExecutionTaskHitBy;\n}\n\nexport type ExecutionTask<\n E extends ExecutionTaskApply<any, any, any> = ExecutionTaskApply<\n any,\n any,\n any\n >,\n> = E &\n ExecutionTaskReturn<\n E extends ExecutionTaskApply<any, any, infer TaskOutput, any>\n ? TaskOutput\n : unknown,\n E extends ExecutionTaskApply<any, any, any, infer TaskLog>\n ? TaskLog\n : unknown\n > & {\n status: 'pending' | 'running' | 'finished' | 'failed' | 'cancelled';\n error?: Error;\n errorMessage?: string;\n errorStack?: string;\n timing?: {\n start: number;\n end?: number;\n cost?: number;\n };\n usage?: AIUsageInfo;\n };\n\nexport interface ExecutionDump extends DumpMeta {\n name: string;\n description?: string;\n tasks: ExecutionTask[];\n}\n\n/*\ntask - insight-locate\n*/\nexport type ExecutionTaskInsightLocateParam = PlanningLocateParam;\n\nexport interface ExecutionTaskInsightLocateOutput {\n element: LocateResultElement | null;\n}\n\nexport interface ExecutionTaskInsightDumpLog {\n dump?: InsightDump;\n}\n\nexport type ExecutionTaskInsightLocateApply = ExecutionTaskApply<\n 'Insight',\n ExecutionTaskInsightLocateParam,\n ExecutionTaskInsightLocateOutput,\n ExecutionTaskInsightDumpLog\n>;\n\nexport type ExecutionTaskInsightLocate =\n ExecutionTask<ExecutionTaskInsightLocateApply>;\n\n/*\ntask - insight-query\n*/\nexport interface ExecutionTaskInsightQueryParam {\n dataDemand: InsightExtractParam;\n}\n\nexport interface ExecutionTaskInsightQueryOutput {\n data: any;\n}\n\nexport type ExecutionTaskInsightQueryApply = ExecutionTaskApply<\n 'Insight',\n ExecutionTaskInsightQueryParam,\n any,\n ExecutionTaskInsightDumpLog\n>;\n\nexport type ExecutionTaskInsightQuery =\n ExecutionTask<ExecutionTaskInsightQueryApply>;\n\n/*\ntask - assertion\n*/\nexport interface ExecutionTaskInsightAssertionParam {\n assertion: string;\n}\n\nexport type ExecutionTaskInsightAssertionApply = ExecutionTaskApply<\n 'Insight',\n ExecutionTaskInsightAssertionParam,\n InsightAssertionResponse,\n ExecutionTaskInsightDumpLog\n>;\n\nexport type ExecutionTaskInsightAssertion =\n ExecutionTask<ExecutionTaskInsightAssertionApply>;\n\n/*\ntask - action (i.e. interact) \n*/\nexport type ExecutionTaskActionApply<ActionParam = any> = ExecutionTaskApply<\n 'Action',\n ActionParam,\n void,\n void\n>;\n\nexport type ExecutionTaskAction = ExecutionTask<ExecutionTaskActionApply>;\n\n/*\ntask - Log\n*/\n\nexport type ExecutionTaskLogApply<\n LogParam = {\n content: string;\n },\n> = ExecutionTaskApply<'Log', LogParam, void, void>;\n\nexport type ExecutionTaskLog = ExecutionTask<ExecutionTaskLogApply>;\n\n/*\ntask - planning\n*/\n\nexport type ExecutionTaskPlanningApply = ExecutionTaskApply<\n 'Planning',\n {\n userInstruction: string;\n log?: string;\n },\n PlanningAIResponse\n>;\n\nexport type ExecutionTaskPlanning = ExecutionTask<ExecutionTaskPlanningApply>;\n\n/*\nGrouped dump\n*/\nexport interface GroupedActionDump {\n groupName: string;\n groupDescription?: string;\n modelBriefs: string[];\n executions: ExecutionDump[];\n}\n\nexport type InterfaceType =\n | 'puppeteer'\n | 'playwright'\n | 'static'\n | 'chrome-extension-proxy'\n | 'android'\n | string;\n\nexport interface StreamingCodeGenerationOptions {\n /** Whether to enable streaming output */\n stream?: boolean;\n /** Callback function to handle streaming chunks */\n onChunk?: StreamingCallback;\n /** Callback function to handle streaming completion */\n onComplete?: (finalCode: string) => void;\n /** Callback function to handle streaming errors */\n onError?: (error: Error) => void;\n}\n\nexport type StreamingCallback = (chunk: CodeGenerationChunk) => void;\n\nexport interface CodeGenerationChunk {\n /** The incremental content chunk */\n content: string;\n /** The reasoning content */\n reasoning_content: string;\n /** The accumulated content so far */\n accumulated: string;\n /** Whether this is the final chunk */\n isComplete: boolean;\n /** Token usage information if available */\n usage?: AIUsageInfo;\n}\n\nexport interface StreamingAIResponse {\n /** The final accumulated content */\n content: string;\n /** Token usage information */\n usage?: AIUsageInfo;\n /** Whether the response was streamed */\n isStreamed: boolean;\n}\n\nexport interface DeviceAction<T = any> {\n name: string;\n description?: string;\n interfaceAlias?: string;\n paramSchema?: z.ZodType<T>;\n call: (param: T, context: ExecutorContext) => Promise<void> | void;\n}\n\n/**\n * Web-specific types\n */\nexport interface WebElementInfo extends BaseElement {\n id: string;\n attributes: {\n nodeType: NodeType;\n [key: string]: string;\n };\n}\n\nexport type WebUIContext = UIContext<WebElementInfo>;\n\n/**\n * Agent\n */\n\nexport interface AgentOpt {\n testId?: string;\n cacheId?: string;\n groupName?: string;\n groupDescription?: string;\n /* if auto generate report, default true */\n generateReport?: boolean;\n /* if auto print report msg, default true */\n autoPrintReportMsg?: boolean;\n onTaskStartTip?: OnTaskStartTip;\n aiActionContext?: string;\n /* custom report file name */\n reportFileName?: string;\n modelConfig?: TModelConfigFn;\n}\n"],"names":["AIResponseFormat","UIContext"],"mappings":";AAsCO,IAAKA,yBAAgBA,WAAAA,GAAAA,SAAhBA,gBAAgB;;;WAAhBA;;AAwFL,MAAeC;AAQtB"}