{"version":3,"file":"yaml/player.mjs","sources":["../../../src/yaml/player.ts"],"sourcesContent":["import { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { basename, dirname, join, resolve } from 'node:path';\nimport { assert, ifInBrowser, ifInWorker } from '@midscene/shared/utils';\nimport { type ZodTypeAny, z } from 'zod';\n\n// previous defined yaml flow, as a helper\ninterface MidsceneYamlFlowItemAIInput extends LocateOption {\n  // previous version\n  // aiInput: string; // value to input\n  // locate: TUserPrompt; // where to input\n  aiInput: TUserPrompt | undefined; // where to input\n  value: string | number; // value to input\n}\n\ninterface MidsceneYamlFlowItemAIKeyboardPress extends LocateOption {\n  // previous version\n  // aiKeyboardPress: string;\n  // locate?: TUserPrompt; // where to press, optional\n  aiKeyboardPress: TUserPrompt | undefined; // where to press\n  keyName: string; // key to press\n}\n\ninterface MidsceneYamlFlowItemAIScroll extends LocateOption, ScrollParam {\n  // previous version\n  // aiScroll: null;\n  // locate?: TUserPrompt; // which area to scroll, optional\n  aiScroll: TUserPrompt | undefined; // which area to scroll\n}\n\ntype RuntimeYamlFlowItem =\n  | MidsceneYamlFlowItem\n  | MidsceneYamlFlowItemAIInput\n  | MidsceneYamlFlowItemAIKeyboardPress\n  | MidsceneYamlFlowItemAIScroll;\n\nimport type { Agent } from '@/agent/agent';\nimport type { TUserPrompt } from '@/common';\nimport type {\n  DeviceAction,\n  FreeFn,\n  LocateOption,\n  MidsceneYamlFlowItem,\n  MidsceneYamlFlowItemAIAction,\n  MidsceneYamlFlowItemAIAssert,\n  MidsceneYamlFlowItemAIWaitFor,\n  MidsceneYamlFlowItemEvaluateJavaScript,\n  MidsceneYamlFlowItemLogScreenshot,\n  MidsceneYamlFlowItemRunGherkinScenario,\n  MidsceneYamlFlowItemSleep,\n  MidsceneYamlScript,\n  MidsceneYamlScriptEnv,\n  ScriptPlayerStatusValue,\n  ScriptPlayerTaskStatus,\n  ScrollParam,\n} from '@/types';\nimport { getMidsceneRunSubDir } from '@midscene/shared/common';\nimport { getDebug } from '@midscene/shared/logger';\nimport {\n  buildDetailedLocateParam,\n  buildDetailedLocateParamAndRestParams,\n} from './utils';\n\nconst debug = getDebug('yaml-player');\n\nconst aiTaskHandlerMap = {\n  aiQuery: 'aiQuery',\n  aiNumber: 'aiNumber',\n  aiString: 'aiString',\n  aiBoolean: 'aiBoolean',\n  aiAsk: 'aiAsk',\n  aiLocate: 'aiLocate',\n} as const;\n\ntype AISimpleTaskKey = keyof typeof aiTaskHandlerMap;\n\nconst isStringParamSchema = (schema?: ZodTypeAny): boolean => {\n  if (!schema) {\n    return false;\n  }\n\n  const schemaDef = (schema as any)?._def;\n  if (!schemaDef?.typeName) {\n    return false;\n  }\n\n  switch (schemaDef.typeName) {\n    case z.ZodFirstPartyTypeKind.ZodString:\n    case z.ZodFirstPartyTypeKind.ZodEnum:\n    case z.ZodFirstPartyTypeKind.ZodNativeEnum:\n      return true;\n    case z.ZodFirstPartyTypeKind.ZodLiteral:\n      return typeof schemaDef.value === 'string';\n    case z.ZodFirstPartyTypeKind.ZodOptional:\n    case z.ZodFirstPartyTypeKind.ZodNullable:\n    case z.ZodFirstPartyTypeKind.ZodDefault:\n      return isStringParamSchema(schemaDef.innerType);\n    case z.ZodFirstPartyTypeKind.ZodEffects:\n      return isStringParamSchema(schemaDef.schema);\n    case z.ZodFirstPartyTypeKind.ZodPipeline:\n      return isStringParamSchema(schemaDef.out);\n    case z.ZodFirstPartyTypeKind.ZodUnion: {\n      const options = schemaDef.options as ZodTypeAny[] | undefined;\n      return Array.isArray(options)\n        ? options.every((option) => isStringParamSchema(option))\n        : false;\n    }\n    default:\n      return false;\n  }\n};\n\nconst buildShortcutActionParam = (\n  actionName: string,\n  interfaceAlias: string | undefined,\n  value: string,\n) => {\n  if (actionName === 'Launch' || interfaceAlias === 'launch') {\n    return { uri: value };\n  }\n\n  if (actionName === 'Terminate' || interfaceAlias === 'terminate') {\n    return { uri: value };\n  }\n\n  if (\n    actionName === 'RunAdbShell' ||\n    interfaceAlias === 'runAdbShell' ||\n    actionName === 'RunHdcShell' ||\n    interfaceAlias === 'runHdcShell'\n  ) {\n    return { command: value };\n  }\n\n  return undefined;\n};\nexport class ScriptPlayer<T extends MidsceneYamlScriptEnv> {\n  public currentTaskIndex?: number;\n  public taskStatusList: ScriptPlayerTaskStatus[] = [];\n  public status: ScriptPlayerStatusValue = 'init';\n  public reportFile?: string | null;\n  public result: Record<string, any>;\n  private unnamedResultIndex = 0;\n  public output?: string | null;\n  public unstableLogContent?: string | null;\n  public errorInSetup?: Error;\n  private interfaceAgent: Agent | null = null;\n  public agentStatusTip?: string;\n  public target?: MidsceneYamlScriptEnv;\n  private actionSpace: DeviceAction[] = [];\n  private scriptPath?: string;\n  private failedReportExecutionInCurrentStep = false;\n  constructor(\n    private script: MidsceneYamlScript,\n    private setupAgent: (platform: T) => Promise<{\n      agent: Agent;\n      freeFn: FreeFn[];\n    }>,\n    public onTaskStatusChange?: (taskStatus: ScriptPlayerTaskStatus) => void,\n    scriptPath?: string,\n  ) {\n    this.scriptPath = scriptPath;\n    this.result = {};\n    const resolvedAiActContext =\n      script.agent?.aiActContext ?? script.agent?.aiActionContext;\n\n    if (resolvedAiActContext !== undefined && script.agent) {\n      if (\n        script.agent.aiActContext === undefined &&\n        script.agent.aiActionContext !== undefined\n      ) {\n        console.warn(\n          'agent.aiActionContext is deprecated, please use agent.aiActContext instead. The legacy name is still accepted for backward compatibility.',\n        );\n      }\n\n      script.agent.aiActContext = resolvedAiActContext;\n    }\n\n    this.target =\n      script.target ||\n      script.web ||\n      script.android ||\n      script.ios ||\n      script.computer ||\n      script.config;\n\n    if (ifInBrowser || ifInWorker) {\n      this.output = undefined;\n      debug('output is undefined in browser or worker');\n    } else if (this.target?.output) {\n      this.output = resolve(process.cwd(), this.target.output);\n      debug('setting output by config.output', this.output);\n    } else {\n      const scriptName = this.scriptPath\n        ? basename(this.scriptPath, '.yaml').replace(/\\.(ya?ml)$/i, '')\n        : 'script';\n      this.output = join(\n        getMidsceneRunSubDir('output'),\n        `${scriptName}-${Date.now()}.json`,\n      );\n      debug('setting output by script path', this.output);\n    }\n\n    if (ifInBrowser || ifInWorker) {\n      this.unstableLogContent = undefined;\n    } else if (typeof this.target?.unstableLogContent === 'string') {\n      this.unstableLogContent = resolve(\n        process.cwd(),\n        this.target.unstableLogContent,\n      );\n    } else if (this.target?.unstableLogContent === true) {\n      this.unstableLogContent = join(\n        getMidsceneRunSubDir('output'),\n        'unstableLogContent.json',\n      );\n    }\n\n    this.taskStatusList = (script.tasks || []).map((task, taskIndex) => ({\n      ...task,\n      index: taskIndex,\n      status: 'init',\n      totalSteps: task.flow?.length || 0,\n    }));\n  }\n\n  private setResult(key: string | undefined, value: any) {\n    const keyToUse = key || this.unnamedResultIndex++;\n    if (this.result[keyToUse]) {\n      console.warn(`result key ${keyToUse} already exists, will overwrite`);\n    }\n    this.result[keyToUse] = value;\n\n    return this.flushResult();\n  }\n\n  private setPlayerStatus(status: ScriptPlayerStatusValue, error?: Error) {\n    this.status = status;\n    this.errorInSetup = error;\n  }\n\n  private notifyCurrentTaskStatusChange(taskIndex?: number) {\n    const taskIndexToNotify =\n      typeof taskIndex === 'number' ? taskIndex : this.currentTaskIndex;\n\n    if (typeof taskIndexToNotify !== 'number') {\n      return;\n    }\n\n    const taskStatus = this.taskStatusList[taskIndexToNotify];\n    if (this.onTaskStatusChange) {\n      this.onTaskStatusChange(taskStatus);\n    }\n  }\n\n  private async setTaskStatus(\n    index: number,\n    statusValue: ScriptPlayerStatusValue,\n    error?: Error,\n  ) {\n    this.taskStatusList[index].status = statusValue;\n    if (error) {\n      this.taskStatusList[index].error = error;\n    }\n\n    this.notifyCurrentTaskStatusChange(index);\n  }\n\n  private setTaskIndex(taskIndex: number) {\n    this.currentTaskIndex = taskIndex;\n  }\n\n  private flushResult() {\n    if (this.output) {\n      const output = resolve(process.cwd(), this.output);\n      const outputDir = dirname(output);\n      if (!existsSync(outputDir)) {\n        mkdirSync(outputDir, { recursive: true });\n      }\n      writeFileSync(output, JSON.stringify(this.result || {}, undefined, 2));\n    }\n  }\n\n  private flushUnstableLogContent() {\n    if (this.unstableLogContent) {\n      const content = this.interfaceAgent?._unstableLogContent();\n      const filePath = resolve(process.cwd(), this.unstableLogContent);\n      const outputDir = dirname(filePath);\n      if (!existsSync(outputDir)) {\n        mkdirSync(outputDir, { recursive: true });\n      }\n      writeFileSync(filePath, JSON.stringify(content, null, 2));\n    }\n  }\n\n  async playTask(taskStatus: ScriptPlayerTaskStatus, agent: Agent) {\n    const { flow } = taskStatus;\n    assert(flow, 'missing flow in task');\n\n    for (const flowItemIndex in flow) {\n      const currentStep = Number.parseInt(flowItemIndex, 10);\n      taskStatus.currentStep = currentStep;\n      const flowItem = flow[flowItemIndex] as RuntimeYamlFlowItem;\n      const flowItemRecord = flowItem as Record<string, unknown>;\n      const executionCountBeforeStep = agent.dump?.executions?.length ?? 0;\n      this.failedReportExecutionInCurrentStep = false;\n\n      try {\n        await this.playFlowItem(agent, flowItem, flowItemRecord, flowItemIndex);\n      } catch (error) {\n        this.failedReportExecutionInCurrentStep =\n          this.hasFailedReportExecutionSince(agent, executionCountBeforeStep);\n        throw error;\n      }\n    }\n    this.reportFile = agent.reportFile;\n    await this.flushUnstableLogContent();\n  }\n\n  private hasFailedReportExecutionSince(\n    agent: Agent,\n    executionCountBefore: number,\n  ) {\n    return (agent.dump?.executions ?? [])\n      .slice(executionCountBefore)\n      .some((execution) =>\n        execution.tasks.some(\n          (task) =>\n            task.status === 'failed' ||\n            Boolean(task.error || task.errorMessage),\n        ),\n      );\n  }\n\n  private async playFlowItem(\n    agent: Agent,\n    flowItem: RuntimeYamlFlowItem,\n    flowItemRecord: Record<string, unknown>,\n    flowItemIndex: string,\n  ) {\n    // Skip Finalize action from cache - it's a planning-only marker\n    if ('Finalize' in flowItemRecord) {\n      return;\n    }\n\n    debug(\n      `playing step ${flowItemIndex}, flowItem=${JSON.stringify(flowItem)}`,\n    );\n    const simpleAIKey = (\n      Object.keys(aiTaskHandlerMap) as AISimpleTaskKey[]\n    ).find((key) => Object.prototype.hasOwnProperty.call(flowItemRecord, key));\n    if (\n      'aiAct' in (flowItem as MidsceneYamlFlowItemAIAction) ||\n      'aiAction' in (flowItem as MidsceneYamlFlowItemAIAction) ||\n      'ai' in (flowItem as MidsceneYamlFlowItemAIAction)\n    ) {\n      const actionTask = flowItem as MidsceneYamlFlowItemAIAction;\n      const { aiAct, aiAction, ai, instruction, ...actionOptions } =\n        actionTask as any;\n      const actionPrompt = aiAct ?? aiAction ?? ai;\n      let promptForAI: TUserPrompt | undefined;\n\n      if (typeof instruction === 'string' && instruction) {\n        promptForAI = instruction;\n      } else if (\n        instruction &&\n        typeof instruction === 'object' &&\n        typeof (instruction as { prompt?: unknown }).prompt === 'string' &&\n        (instruction as { prompt?: string }).prompt\n      ) {\n        promptForAI = instruction as TUserPrompt;\n      } else if (\n        actionPrompt &&\n        typeof actionPrompt === 'object' &&\n        typeof (actionPrompt as { prompt?: unknown }).prompt === 'string' &&\n        (actionPrompt as { prompt?: string }).prompt\n      ) {\n        promptForAI = actionPrompt as TUserPrompt;\n      } else if (typeof actionPrompt === 'string' && actionPrompt) {\n        promptForAI = actionPrompt;\n      }\n\n      assert(promptForAI, 'missing prompt for ai (aiAct)');\n      await agent.aiAct(promptForAI, actionOptions);\n    } else if (\n      'runGherkinScenario' in\n      (flowItem as MidsceneYamlFlowItemRunGherkinScenario)\n    ) {\n      const gherkinScenarioTask =\n        flowItem as MidsceneYamlFlowItemRunGherkinScenario;\n      const { runGherkinScenario } = gherkinScenarioTask;\n      assert(runGherkinScenario, 'missing scenario for runGherkinScenario');\n      await agent.runGherkinScenario(runGherkinScenario, {\n        cacheable: false,\n      });\n    } else if ('aiAssert' in (flowItem as MidsceneYamlFlowItemAIAssert)) {\n      const assertTask = flowItem as MidsceneYamlFlowItemAIAssert;\n      const {\n        aiAssert: prompt,\n        errorMessage: msg,\n        name,\n        ...restOpts\n      } = assertTask;\n      assert(prompt, 'missing prompt for aiAssert');\n      const { pass, thought, message } =\n        (await agent.aiAssert(prompt, msg, {\n          ...restOpts,\n          keepRawResponse: true,\n        })) || {};\n\n      this.setResult(name, {\n        pass,\n        thought,\n        message,\n      });\n\n      if (!pass) {\n        throw new Error(message);\n      }\n    } else if (simpleAIKey) {\n      const {\n        [simpleAIKey]: prompt,\n        name,\n        ...options\n      } = flowItem as Record<string, any>;\n      assert(prompt, `missing prompt for ${simpleAIKey}`);\n      const agentMethod = (agent as any)[aiTaskHandlerMap[simpleAIKey]];\n      assert(\n        typeof agentMethod === 'function',\n        `missing agent method for ${simpleAIKey}`,\n      );\n      const aiResult = await agentMethod.call(agent, prompt, options);\n      this.setResult(name, aiResult);\n    } else if ('aiWaitFor' in (flowItem as MidsceneYamlFlowItemAIWaitFor)) {\n      const waitForTask = flowItem as MidsceneYamlFlowItemAIWaitFor;\n      const { aiWaitFor, timeout, ...restWaitForOpts } = waitForTask;\n      const prompt = aiWaitFor;\n      assert(prompt, 'missing prompt for aiWaitFor');\n      const waitForOptions = {\n        ...restWaitForOpts,\n        ...(timeout !== undefined ? { timeout, timeoutMs: timeout } : {}),\n      };\n      await agent.aiWaitFor(prompt, waitForOptions);\n    } else if ('sleep' in flowItem) {\n      const sleepTask = flowItem as unknown as MidsceneYamlFlowItemSleep;\n      const ms = sleepTask.sleep;\n      let msNumber = ms;\n      if (typeof ms === 'string') {\n        msNumber = Number.parseInt(ms, 10);\n      }\n      assert(\n        msNumber && msNumber > 0,\n        `ms for sleep must be greater than 0, but got ${ms}`,\n      );\n      await new Promise((resolve) => setTimeout(resolve, msNumber));\n    } else if ('javascript' in flowItem) {\n      const evaluateJavaScriptTask =\n        flowItem as unknown as MidsceneYamlFlowItemEvaluateJavaScript;\n\n      const result = await agent.evaluateJavaScript(\n        evaluateJavaScriptTask.javascript,\n      );\n      this.setResult(evaluateJavaScriptTask.name, result);\n    } else if (\n      'logScreenshot' in (flowItem as MidsceneYamlFlowItemLogScreenshot) ||\n      'recordToReport' in (flowItem as MidsceneYamlFlowItemLogScreenshot)\n    ) {\n      const recordTask = flowItem as MidsceneYamlFlowItemLogScreenshot;\n      const title =\n        recordTask.recordToReport ?? recordTask.logScreenshot ?? 'untitled';\n      const content = recordTask.content || '';\n      await agent.recordToReport(title, { content });\n    } else if ('aiInput' in flowItem) {\n      // may be input empty string ''\n      const {\n        aiInput,\n        value: rawValue,\n        ...inputTask\n      } = flowItem as unknown as MidsceneYamlFlowItemAIInput;\n\n      // Compatibility with previous version:\n      // Old format: { aiInput: string (value), locate: TUserPrompt }\n      // New format - 1: { aiInput: TUserPrompt, value: string | number }\n      // New format - 2: { aiInput: undefined, locate: TUserPrompt, value: string | number }\n      let locatePrompt: TUserPrompt | undefined;\n      let value: string | number | undefined;\n      if ((inputTask as any).locate) {\n        // Old format - aiInput is the value, locate is the prompt\n        // Keep backward compatibility: empty string is treated as no value\n        value = (aiInput as string | number) || rawValue;\n        locatePrompt = (inputTask as any).locate;\n      } else {\n        // New format - aiInput is the prompt, value is the value\n        locatePrompt = aiInput || '';\n        value = rawValue;\n      }\n\n      // Convert value to string for Input action\n      await agent.callActionInActionSpace('Input', {\n        ...inputTask,\n        ...(value !== undefined ? { value: String(value) } : {}),\n        ...(locatePrompt\n          ? { locate: buildDetailedLocateParam(locatePrompt, inputTask) }\n          : {}),\n      });\n    } else if ('aiKeyboardPress' in flowItem) {\n      const { aiKeyboardPress, ...keyboardPressTask } =\n        flowItem as unknown as MidsceneYamlFlowItemAIKeyboardPress;\n\n      // Compatibility with previous version:\n      // Old format: { aiKeyboardPress: string (key), locate?: TUserPrompt }\n      // New format - 1: { aiKeyboardPress: TUserPrompt, keyName: string }\n      // New format - 2: { aiKeyboardPress: , locate?: TUserPrompt, keyName: string }\n      let locatePrompt: TUserPrompt | undefined;\n      let keyName: string | undefined;\n      if ((keyboardPressTask as any).locate) {\n        // Old format - aiKeyboardPress is the key, locate is the prompt\n        keyName = aiKeyboardPress as string;\n        locatePrompt = (keyboardPressTask as any).locate;\n      } else if (keyboardPressTask.keyName) {\n        // New format - aiKeyboardPress is the prompt, key is the key\n        keyName = keyboardPressTask.keyName;\n        locatePrompt = aiKeyboardPress;\n      } else {\n        keyName = aiKeyboardPress as string;\n      }\n\n      await agent.callActionInActionSpace('KeyboardPress', {\n        ...keyboardPressTask,\n        ...(keyName ? { keyName } : {}),\n        ...(locatePrompt\n          ? {\n              locate: buildDetailedLocateParam(locatePrompt, keyboardPressTask),\n            }\n          : {}),\n      });\n    } else if ('aiScroll' in flowItem) {\n      const { aiScroll, ...scrollTask } =\n        flowItem as unknown as MidsceneYamlFlowItemAIScroll;\n\n      // Compatibility with previous version:\n      // Old format: { aiScroll: null, locate?: TUserPrompt, direction, scrollType, distance? }\n      // New format - 1: { aiScroll: TUserPrompt, direction, scrollType, distance? }\n      // New format - 2: { aiScroll: undefined, locate: TUserPrompt, direction, scrollType, distance? }\n      const { locate, ...scrollOptions } = scrollTask as any;\n      const locatePrompt: TUserPrompt | undefined =\n        locate ?? aiScroll ?? undefined;\n\n      await agent.aiScroll(locatePrompt, scrollOptions);\n    } else if ('aiTap' in flowItem) {\n      const { aiTap, prompt, locate, ...tapOptions } = flowItem as any;\n\n      let locatePrompt: TUserPrompt;\n      let opts = tapOptions;\n      // Support both formats:\n      // 1. { aiTap: null, locate: { prompt, images, ... } }  (locate as sibling key)\n      // 2. { aiTap: { locate: { prompt, images, ... } } }    (locate nested in aiTap)\n      const locateObj =\n        locate ??\n        (typeof aiTap === 'object' && aiTap !== null\n          ? aiTap.locate\n          : undefined);\n\n      if (typeof aiTap === 'string' && aiTap) {\n        // User YAML: aiTap: 'search input box'\n        locatePrompt = aiTap;\n      } else if (typeof locateObj === 'object' && locateObj?.prompt) {\n        // buildYamlFlowFromPlans: { aiTap: '', locate: { prompt, deepLocate, cacheable } }\n        const { prompt: lp, ...locateOpts } = locateObj;\n        locatePrompt = lp;\n        opts = { ...locateOpts, ...tapOptions };\n      } else {\n        // User YAML: aiTap: { prompt: '...' } or aiTap: null + prompt: '...'\n        locatePrompt = aiTap?.prompt || prompt || locateObj;\n      }\n\n      assert(locatePrompt, 'missing prompt for aiTap');\n      await agent.aiTap(locatePrompt, opts);\n    } else {\n      // generic action, find the action in actionSpace\n\n      /* for aiRightClick, the parameters are a flattened data for the 'locate', these are all valid data\n\n        - aiRightClick: 'search input box'\n        - aiRightClick: 'search input box'\n          deepLocate: true\n          cacheable: false\n        - aiRightClick:\n          prompt: 'search input box'\n        - aiRightClick:\n          prompt: 'search input box'\n          deepLocate: true\n          cacheable: false\n        */\n\n      const actionSpace = this.actionSpace;\n      let locatePromptShortcut: string | undefined;\n      let actionParamForMatchedAction: unknown;\n      const matchedAction = actionSpace.find((action) => {\n        const actionInterfaceAlias = action.interfaceAlias;\n        if (\n          actionInterfaceAlias &&\n          Object.prototype.hasOwnProperty.call(flowItem, actionInterfaceAlias)\n        ) {\n          actionParamForMatchedAction =\n            flowItem[actionInterfaceAlias as keyof typeof flowItem];\n          if (typeof actionParamForMatchedAction === 'string') {\n            locatePromptShortcut = actionParamForMatchedAction;\n          }\n          return true;\n        }\n\n        const keyOfActionInActionSpace = action.name;\n        if (\n          Object.prototype.hasOwnProperty.call(\n            flowItem,\n            keyOfActionInActionSpace,\n          )\n        ) {\n          actionParamForMatchedAction =\n            flowItem[keyOfActionInActionSpace as keyof typeof flowItem];\n          if (typeof actionParamForMatchedAction === 'string') {\n            locatePromptShortcut = actionParamForMatchedAction;\n          }\n          return true;\n        }\n\n        return false;\n      });\n\n      assert(\n        matchedAction,\n        `unknown flowItem in yaml: ${JSON.stringify(flowItem)}`,\n      );\n\n      const schemaIsStringParam = isStringParamSchema(\n        matchedAction.paramSchema,\n      );\n      let stringParamToCall: string | undefined;\n      const resultName = (flowItem as any).name;\n      const timeout = (flowItem as any).timeout;\n      const hasRunAdbShellAlias = Object.prototype.hasOwnProperty.call(\n        flowItem,\n        'runAdbShell',\n      );\n\n      if (\n        hasRunAdbShellAlias &&\n        typeof actionParamForMatchedAction === 'string' &&\n        typeof timeout === 'number' &&\n        typeof (agent as any).runAdbShell === 'function'\n      ) {\n        const result = await (agent as any).runAdbShell(\n          actionParamForMatchedAction,\n          { timeout },\n        );\n        if (result !== undefined) {\n          this.setResult(resultName, result);\n        }\n        return;\n      }\n\n      const specialActionParamToCall =\n        typeof actionParamForMatchedAction === 'string'\n          ? buildShortcutActionParam(\n              matchedAction.name,\n              matchedAction.interfaceAlias,\n              actionParamForMatchedAction,\n            )\n          : undefined;\n      if (specialActionParamToCall) {\n        debug(\n          `matchedAction: ${matchedAction.name}`,\n          `flowParams: ${JSON.stringify(specialActionParamToCall)}`,\n        );\n        const result = await agent.callActionInActionSpace(\n          matchedAction.name,\n          specialActionParamToCall,\n        );\n\n        if (result !== undefined) {\n          this.setResult(resultName, result);\n        }\n      } else if (\n        typeof actionParamForMatchedAction === 'string' &&\n        schemaIsStringParam\n      ) {\n        if (matchedAction.paramSchema) {\n          const parseResult = matchedAction.paramSchema.safeParse(\n            actionParamForMatchedAction,\n          );\n          if (parseResult.success && typeof parseResult.data === 'string') {\n            stringParamToCall = parseResult.data;\n          } else if (!parseResult.success) {\n            debug(\n              `parse failed for action ${matchedAction.name} with string param`,\n              parseResult.error,\n            );\n            stringParamToCall = actionParamForMatchedAction;\n          }\n        } else {\n          stringParamToCall = actionParamForMatchedAction;\n        }\n\n        if (stringParamToCall !== undefined) {\n          debug(\n            `matchedAction: ${matchedAction.name}`,\n            `flowParams: ${JSON.stringify(stringParamToCall)}`,\n          );\n          const result = await agent.callActionInActionSpace(\n            matchedAction.name,\n            stringParamToCall,\n          );\n\n          // Store result if there's a name property in flowItem\n          const resultName = (flowItem as any).name;\n          if (result !== undefined) {\n            this.setResult(resultName, result);\n          }\n        }\n      } else {\n        // Determine the source for parameter extraction:\n        // - If we have a locatePromptShortcut, use the flowItem (for actions like aiTap with prompt)\n        // - Otherwise, use actionParamForMatchedAction (for actions like runWdaRequest with structured params)\n        const sourceForParams =\n          locatePromptShortcut &&\n          typeof actionParamForMatchedAction === 'string'\n            ? { ...flowItem, prompt: locatePromptShortcut }\n            : typeof actionParamForMatchedAction === 'object' &&\n                actionParamForMatchedAction !== null\n              ? actionParamForMatchedAction\n              : flowItem;\n\n        const { locateParam, restParams } =\n          buildDetailedLocateParamAndRestParams(\n            locatePromptShortcut || '',\n            sourceForParams as LocateOption,\n            [\n              matchedAction.name,\n              matchedAction.interfaceAlias || '_never_mind_',\n            ],\n          );\n\n        const flowParams = {\n          ...restParams,\n          locate: locateParam,\n        };\n\n        debug(\n          `matchedAction: ${matchedAction.name}`,\n          `flowParams: ${JSON.stringify(flowParams, null, 2)}`,\n        );\n        const result = await agent.callActionInActionSpace(\n          matchedAction.name,\n          flowParams,\n        );\n\n        // Store result if there's a name property in flowItem\n        const resultName = (flowItem as any).name;\n        if (result !== undefined) {\n          this.setResult(resultName, result);\n        }\n      }\n    }\n  }\n\n  async run() {\n    const { target, web, android, ios, harmony, computer, tasks } = this.script;\n    const webEnv = web || target;\n    const androidEnv = android;\n    const iosEnv = ios;\n    const harmonyEnv = harmony;\n    const computerEnv = computer;\n    const platform =\n      webEnv || androidEnv || iosEnv || harmonyEnv || computerEnv;\n\n    this.setPlayerStatus('running');\n\n    let agent: Agent | null = null;\n    let freeFn: FreeFn[] = [];\n    try {\n      const { agent: newAgent, freeFn: newFreeFn } = await this.setupAgent(\n        platform as T,\n      );\n      this.actionSpace = await newAgent.getActionSpace();\n      agent = newAgent;\n      const originalOnTaskStartTip = agent.onTaskStartTip;\n      agent.onTaskStartTip = (tip) => {\n        if (this.status === 'running') {\n          this.agentStatusTip = tip;\n        }\n        originalOnTaskStartTip?.(tip);\n      };\n      freeFn = [\n        ...(newFreeFn || []),\n        {\n          name: 'restore-agent-onTaskStartTip',\n          fn: () => {\n            if (agent) {\n              agent.onTaskStartTip = originalOnTaskStartTip;\n            }\n          },\n        },\n      ];\n    } catch (e) {\n      this.setPlayerStatus('error', e as Error);\n      return;\n    }\n    this.interfaceAgent = agent;\n\n    let taskIndex = 0;\n    this.setPlayerStatus('running');\n    let errorFlag = false;\n    while (taskIndex < tasks.length) {\n      const taskStatus = this.taskStatusList[taskIndex];\n      this.setTaskStatus(taskIndex, 'running' as any);\n      this.setTaskIndex(taskIndex);\n      this.failedReportExecutionInCurrentStep = false;\n\n      try {\n        await this.playTask(taskStatus, this.interfaceAgent);\n        this.setTaskStatus(taskIndex, 'done' as any);\n      } catch (e) {\n        this.setTaskStatus(taskIndex, 'error' as any, e as Error);\n        const recordErrorToReport = (agent as any).recordErrorToReport;\n        if (\n          !this.failedReportExecutionInCurrentStep &&\n          typeof recordErrorToReport === 'function'\n        ) {\n          try {\n            await recordErrorToReport.call(\n              agent,\n              `YAML task failed - ${taskStatus.name}`,\n              {\n                error: e as Error,\n                content: `Step ${taskStatus.currentStep ?? 0} failed while running YAML task \"${taskStatus.name}\".`,\n              },\n            );\n          } catch (reportError) {\n            debug('failed to record yaml error to report', reportError);\n          }\n        }\n\n        if (taskStatus.continueOnError) {\n          // nothing more to do\n        } else {\n          this.reportFile = agent.reportFile;\n          errorFlag = true;\n          break;\n        }\n      }\n      this.reportFile = agent?.reportFile;\n      taskIndex++;\n    }\n\n    if (errorFlag) {\n      this.setPlayerStatus('error');\n    } else {\n      this.setPlayerStatus('done');\n    }\n    this.agentStatusTip = '';\n\n    // free the resources\n    for (const fn of freeFn) {\n      try {\n        // console.log('freeing', fn.name);\n        await fn.fn();\n        // console.log('freed', fn.name);\n      } catch (e) {\n        // console.error('error freeing', fn.name, e);\n      }\n    }\n  }\n}\n"],"names":["debug","getDebug","aiTaskHandlerMap","isStringParamSchema","schema","schemaDef","z","options","Array","option","buildShortcutActionParam","actionName","interfaceAlias","value","ScriptPlayer","key","keyToUse","console","status","error","taskIndex","taskIndexToNotify","taskStatus","index","statusValue","output","resolve","process","outputDir","dirname","existsSync","mkdirSync","writeFileSync","JSON","undefined","content","filePath","agent","flow","assert","flowItemIndex","currentStep","Number","flowItem","flowItemRecord","executionCountBeforeStep","executionCountBefore","execution","task","Boolean","simpleAIKey","Object","actionTask","aiAct","aiAction","ai","instruction","actionOptions","actionPrompt","promptForAI","gherkinScenarioTask","runGherkinScenario","assertTask","prompt","msg","name","restOpts","pass","thought","message","Error","agentMethod","aiResult","waitForTask","aiWaitFor","timeout","restWaitForOpts","waitForOptions","sleepTask","ms","msNumber","Promise","setTimeout","evaluateJavaScriptTask","result","recordTask","title","aiInput","rawValue","inputTask","locatePrompt","String","buildDetailedLocateParam","aiKeyboardPress","keyboardPressTask","keyName","aiScroll","scrollTask","locate","scrollOptions","aiTap","tapOptions","opts","locateObj","lp","locateOpts","actionSpace","locatePromptShortcut","actionParamForMatchedAction","matchedAction","action","actionInterfaceAlias","keyOfActionInActionSpace","schemaIsStringParam","stringParamToCall","resultName","hasRunAdbShellAlias","specialActionParamToCall","parseResult","sourceForParams","locateParam","restParams","buildDetailedLocateParamAndRestParams","flowParams","target","web","android","ios","harmony","computer","tasks","webEnv","androidEnv","iosEnv","harmonyEnv","computerEnv","platform","freeFn","newAgent","newFreeFn","originalOnTaskStartTip","tip","e","errorFlag","recordErrorToReport","reportError","fn","script","setupAgent","onTaskStatusChange","scriptPath","resolvedAiActContext","ifInBrowser","ifInWorker","scriptName","basename","join","getMidsceneRunSubDir","Date"],"mappings":"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"}