@midscene/core 1.9.1 → 1.9.2-beta-20260605084246.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/agent/agent.mjs +2 -1
- package/dist/es/agent/agent.mjs.map +1 -1
- package/dist/es/agent/task-cache.mjs +43 -8
- package/dist/es/agent/task-cache.mjs.map +1 -1
- package/dist/es/agent/tasks.mjs +18 -3
- package/dist/es/agent/tasks.mjs.map +1 -1
- package/dist/es/agent/ui-utils.mjs +2 -1
- package/dist/es/agent/ui-utils.mjs.map +1 -1
- package/dist/es/agent/utils.mjs +1 -1
- package/dist/es/ai-model/inspect.mjs +8 -60
- package/dist/es/ai-model/inspect.mjs.map +1 -1
- package/dist/es/ai-model/llm-planning.mjs +6 -3
- package/dist/es/ai-model/llm-planning.mjs.map +1 -1
- package/dist/es/ai-model/models/auto-glm/planning.mjs +8 -3
- package/dist/es/ai-model/models/auto-glm/planning.mjs.map +1 -1
- package/dist/es/ai-model/models/ui-tars/planning.mjs +6 -2
- package/dist/es/ai-model/models/ui-tars/planning.mjs.map +1 -1
- package/dist/es/common.mjs +50 -3
- package/dist/es/common.mjs.map +1 -1
- package/dist/es/types.mjs.map +1 -1
- package/dist/es/utils.mjs +2 -2
- package/dist/es/yaml/player.mjs +9 -4
- package/dist/es/yaml/player.mjs.map +1 -1
- package/dist/lib/agent/agent.js +2 -1
- package/dist/lib/agent/agent.js.map +1 -1
- package/dist/lib/agent/task-cache.js +43 -8
- package/dist/lib/agent/task-cache.js.map +1 -1
- package/dist/lib/agent/tasks.js +17 -2
- package/dist/lib/agent/tasks.js.map +1 -1
- package/dist/lib/agent/ui-utils.js +3 -2
- package/dist/lib/agent/ui-utils.js.map +1 -1
- package/dist/lib/agent/utils.js +1 -1
- package/dist/lib/ai-model/inspect.js +7 -59
- package/dist/lib/ai-model/inspect.js.map +1 -1
- package/dist/lib/ai-model/llm-planning.js +6 -3
- package/dist/lib/ai-model/llm-planning.js.map +1 -1
- package/dist/lib/ai-model/models/auto-glm/planning.js +8 -3
- package/dist/lib/ai-model/models/auto-glm/planning.js.map +1 -1
- package/dist/lib/ai-model/models/ui-tars/planning.js +6 -2
- package/dist/lib/ai-model/models/ui-tars/planning.js.map +1 -1
- package/dist/lib/common.js +59 -3
- package/dist/lib/common.js.map +1 -1
- package/dist/lib/types.js.map +1 -1
- package/dist/lib/utils.js +2 -2
- package/dist/lib/yaml/player.js +9 -4
- package/dist/lib/yaml/player.js.map +1 -1
- package/dist/types/agent/agent.d.ts +2 -2
- package/dist/types/agent/task-cache.d.ts +18 -2
- package/dist/types/agent/tasks.d.ts +15 -2
- package/dist/types/ai-model/inspect.d.ts +1 -2
- package/dist/types/ai-model/llm-planning.d.ts +2 -1
- package/dist/types/ai-model/models/auto-glm/planning.d.ts +2 -1
- package/dist/types/ai-model/models/ui-tars/planning.d.ts +2 -1
- package/dist/types/ai-model/workflows/planning/types.d.ts +4 -1
- package/dist/types/common.d.ts +4 -0
- package/dist/types/types.d.ts +1 -1
- package/dist/types/yaml.d.ts +4 -3
- package/package.json +2 -2
package/dist/lib/yaml/player.js
CHANGED
|
@@ -150,10 +150,15 @@ class ScriptPlayer {
|
|
|
150
150
|
const simpleAIKey = Object.keys(aiTaskHandlerMap).find((key)=>Object.prototype.hasOwnProperty.call(flowItemRecord, key));
|
|
151
151
|
if ('aiAct' in flowItem || 'aiAction' in flowItem || 'ai' in flowItem) {
|
|
152
152
|
const actionTask = flowItem;
|
|
153
|
-
const { aiAct, aiAction, ai, ...actionOptions } = actionTask;
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
|
|
153
|
+
const { aiAct, aiAction, ai, instruction, ...actionOptions } = actionTask;
|
|
154
|
+
const actionPrompt = aiAct ?? aiAction ?? ai;
|
|
155
|
+
let promptForAI;
|
|
156
|
+
if ('string' == typeof instruction && instruction) promptForAI = instruction;
|
|
157
|
+
else if (instruction && 'object' == typeof instruction && 'string' == typeof instruction.prompt && instruction.prompt) promptForAI = instruction;
|
|
158
|
+
else if (actionPrompt && 'object' == typeof actionPrompt && 'string' == typeof actionPrompt.prompt && actionPrompt.prompt) promptForAI = actionPrompt;
|
|
159
|
+
else if ('string' == typeof actionPrompt && actionPrompt) promptForAI = actionPrompt;
|
|
160
|
+
(0, utils_namespaceObject.assert)(promptForAI, 'missing prompt for ai (aiAct)');
|
|
161
|
+
await agent.aiAct(promptForAI, actionOptions);
|
|
157
162
|
} else if ('aiAssert' in flowItem) {
|
|
158
163
|
const assertTask = flowItem;
|
|
159
164
|
const { aiAssert: prompt, errorMessage: msg, name, ...restOpts } = assertTask;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yaml/player.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/yaml/player.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { 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 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 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\n // Skip Finalize action from cache - it's a planning-only marker\n if ('Finalize' in flowItemRecord) {\n continue;\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) =>\n Object.prototype.hasOwnProperty.call(flowItemRecord, key),\n );\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, ...actionOptions } = actionTask;\n const prompt = aiAct || aiAction || ai;\n assert(prompt, 'missing prompt for ai (aiAct)');\n await agent.aiAct(prompt, actionOptions);\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(\n locatePrompt,\n keyboardPressTask,\n ),\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 continue;\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 this.reportFile = agent.reportFile;\n await this.flushUnstableLogContent();\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\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\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":["__webpack_require__","definition","key","Object","obj","prop","Symbol","debug","getDebug","aiTaskHandlerMap","isStringParamSchema","schema","schemaDef","z","options","Array","option","buildShortcutActionParam","actionName","interfaceAlias","value","ScriptPlayer","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","simpleAIKey","actionTask","aiAct","aiAction","ai","actionOptions","prompt","assertTask","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","fn","script","setupAgent","onTaskStatusChange","scriptPath","resolvedAiActContext","ifInBrowser","ifInWorker","scriptName","basename","join","getMidsceneRunSubDir","Date","task"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"yaml/player.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/yaml/player.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { 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 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 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\n // Skip Finalize action from cache - it's a planning-only marker\n if ('Finalize' in flowItemRecord) {\n continue;\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) =>\n Object.prototype.hasOwnProperty.call(flowItemRecord, key),\n );\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 ('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(\n locatePrompt,\n keyboardPressTask,\n ),\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 continue;\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 this.reportFile = agent.reportFile;\n await this.flushUnstableLogContent();\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\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\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":["__webpack_require__","definition","key","Object","obj","prop","Symbol","debug","getDebug","aiTaskHandlerMap","isStringParamSchema","schema","schemaDef","z","options","Array","option","buildShortcutActionParam","actionName","interfaceAlias","value","ScriptPlayer","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","simpleAIKey","actionTask","aiAct","aiAction","ai","instruction","actionOptions","actionPrompt","promptForAI","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","fn","script","setupAgent","onTaskStatusChange","scriptPath","resolvedAiActContext","ifInBrowser","ifInWorker","scriptName","basename","join","getMidsceneRunSubDir","Date","task"],"mappings":"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"}
|
|
@@ -131,11 +131,11 @@ export declare class Agent<InterfaceType extends AbstractInterface = AbstractInt
|
|
|
131
131
|
duration?: number;
|
|
132
132
|
}): Promise<void>;
|
|
133
133
|
aiClearInput(locatePrompt: TUserPrompt, opt?: LocateOption): Promise<void>;
|
|
134
|
-
aiAct(taskPrompt:
|
|
134
|
+
aiAct(taskPrompt: TUserPrompt, opt?: AiActOptions): Promise<string | undefined>;
|
|
135
135
|
/**
|
|
136
136
|
* @deprecated Use {@link Agent.aiAct} instead.
|
|
137
137
|
*/
|
|
138
|
-
aiAction(taskPrompt:
|
|
138
|
+
aiAction(taskPrompt: TUserPrompt, opt?: AiActOptions): Promise<string | undefined>;
|
|
139
139
|
aiQuery<ReturnType = any>(demand: ServiceExtractParam, opt?: ServiceExtractOption): Promise<ReturnType>;
|
|
140
140
|
aiBoolean(prompt: TUserPrompt, opt?: ServiceExtractOption): Promise<boolean>;
|
|
141
141
|
aiNumber(prompt: TUserPrompt, opt?: ServiceExtractOption): Promise<number>;
|
|
@@ -3,7 +3,7 @@ import type { ElementCacheFeature } from '../types';
|
|
|
3
3
|
export declare const debug: import("@midscene/shared/logger").DebugFunction;
|
|
4
4
|
export interface PlanningCache {
|
|
5
5
|
type: 'plan';
|
|
6
|
-
prompt:
|
|
6
|
+
prompt: TUserPrompt;
|
|
7
7
|
yamlWorkflow: string;
|
|
8
8
|
}
|
|
9
9
|
export interface LocateCache {
|
|
@@ -33,18 +33,34 @@ export declare class TaskCache {
|
|
|
33
33
|
readOnlyMode: boolean;
|
|
34
34
|
writeOnlyMode: boolean;
|
|
35
35
|
private matchedCacheIndices;
|
|
36
|
+
private consumedCacheIndices;
|
|
37
|
+
private staleCacheIndices;
|
|
36
38
|
constructor(cacheId: string, isCacheResultUsed: boolean, cacheFilePath?: string, options?: {
|
|
37
39
|
readOnly?: boolean;
|
|
38
40
|
writeOnly?: boolean;
|
|
39
41
|
cacheDir?: string;
|
|
40
42
|
});
|
|
41
43
|
matchCache(prompt: TUserPrompt, type: 'plan' | 'locate'): MatchCacheResult<PlanningCache | LocateCache> | undefined;
|
|
42
|
-
matchPlanCache(prompt:
|
|
44
|
+
matchPlanCache(prompt: TUserPrompt): MatchCacheResult<PlanningCache> | undefined;
|
|
43
45
|
matchLocateCache(prompt: TUserPrompt): MatchCacheResult<LocateCache> | undefined;
|
|
44
46
|
appendCache(cache: PlanningCache | LocateCache): void;
|
|
45
47
|
loadCacheFromFile(): CacheFileContent | undefined;
|
|
46
48
|
flushCacheToFile(options?: {
|
|
47
49
|
cleanUnused?: boolean;
|
|
48
50
|
}): void;
|
|
51
|
+
private promptKey;
|
|
52
|
+
private applyRecordInto;
|
|
49
53
|
updateOrAppendCacheRecord(newRecord: PlanningCache | LocateCache, cachedRecord?: MatchCacheResult<PlanningCache | LocateCache>): void;
|
|
54
|
+
/**
|
|
55
|
+
* Mark the most recently consumed locate cache entry for `prompt` as stale.
|
|
56
|
+
* Call this when an action that used the cache-hit element failed and the run
|
|
57
|
+
* is about to replan: the subsequent re-locate then replaces this entry in
|
|
58
|
+
* place instead of appending a duplicate, which would otherwise be matched
|
|
59
|
+
* first on the next run and re-trigger replanning forever (#2529).
|
|
60
|
+
*
|
|
61
|
+
* No-op when nothing was consumed for the prompt, so a plain first-time miss
|
|
62
|
+
* (and any repeated prompt that never failed) still appends normally.
|
|
63
|
+
*/
|
|
64
|
+
markLocateCacheStale(prompt: TUserPrompt): void;
|
|
65
|
+
private replaceCacheRecord;
|
|
50
66
|
}
|
|
@@ -54,14 +54,27 @@ export declare class TaskExecutor {
|
|
|
54
54
|
}): Promise<{
|
|
55
55
|
tasks: ExecutionTaskApply[];
|
|
56
56
|
}>;
|
|
57
|
-
loadYamlFlowAsPlanning(userInstruction:
|
|
57
|
+
loadYamlFlowAsPlanning(userInstruction: TUserPrompt, yamlString: string): Promise<{
|
|
58
58
|
runner: TaskRunner;
|
|
59
59
|
}>;
|
|
60
60
|
runPlans(title: string, plans: PlanningAction[], planningModel: ModelRuntime, defaultModel: ModelRuntime): Promise<ExecutionResult>;
|
|
61
|
-
action(userPrompt:
|
|
61
|
+
action(userPrompt: TUserPrompt, planningModel: ModelRuntime, defaultModel: ModelRuntime, includeLocateInPlanning: boolean, aiActContext?: string, cacheable?: boolean, replanningCycleLimitOverride?: number, imagesIncludeCount?: number, deepThink?: boolean, fileChooserAccept?: string[], deepLocate?: boolean, abortSignal?: AbortSignal): Promise<ExecutionResult<{
|
|
62
62
|
yamlFlow?: MidsceneYamlFlowItem[];
|
|
63
63
|
output?: string;
|
|
64
64
|
} | undefined>>;
|
|
65
|
+
/**
|
|
66
|
+
* Called when the task is about to replan. Marks every cache-hit locate task
|
|
67
|
+
* in the just-run batch (tasks at index >= fromIndex) as stale: that batch
|
|
68
|
+
* did not finish the task, so the element each cache hit produced is suspect.
|
|
69
|
+
* The upcoming re-locate of the same prompt then replaces the bad entry in
|
|
70
|
+
* place instead of appending a duplicate that would re-poison the cache on the
|
|
71
|
+
* next run (#2529).
|
|
72
|
+
*
|
|
73
|
+
* Marking a locate that was actually fine is harmless: the step is only ever
|
|
74
|
+
* replaced if the same prompt is located again (i.e. the step is redone),
|
|
75
|
+
* which does not happen for a locate that already succeeded.
|
|
76
|
+
*/
|
|
77
|
+
private invalidateFailedCacheHitLocates;
|
|
65
78
|
private runAction;
|
|
66
79
|
private createTypeQueryTask;
|
|
67
80
|
createTypeQueryExecution<T>(type: 'Query' | 'Boolean' | 'Number' | 'String' | 'Assert', demand: ServiceExtractParam, modelRuntime: ModelRuntime, opt?: ServiceExtractOption, multimodalPrompt?: TMultimodalPrompt): Promise<ExecutionResult<T>>;
|
|
@@ -7,12 +7,11 @@ export type InspectAIArgs = [
|
|
|
7
7
|
ChatCompletionSystemMessageParam,
|
|
8
8
|
...ChatCompletionUserMessageParam[]
|
|
9
9
|
];
|
|
10
|
+
export { userPromptToString as extraTextFromUserPrompt, multimodalPromptToChatMessages as promptsToChatParam, } from '../common';
|
|
10
11
|
export declare function buildSearchAreaConfig(options: {
|
|
11
12
|
context: UIContext;
|
|
12
13
|
baseRect: Rect;
|
|
13
14
|
}): Promise<SearchAreaConfig>;
|
|
14
|
-
export declare const extraTextFromUserPrompt: (prompt: TUserPrompt) => string;
|
|
15
|
-
export declare const promptsToChatParam: (multimodalPrompt: TMultimodalPrompt) => Promise<ChatCompletionUserMessageParam[]>;
|
|
16
15
|
export declare function AiLocateElement(options: LocateOptions & {
|
|
17
16
|
targetElementDescription: TUserPrompt;
|
|
18
17
|
}): Promise<LocateResult>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type TUserPrompt } from '../common';
|
|
1
2
|
import type { PlanningAIResponse, RawResponsePlanningAIResponse } from '../types';
|
|
2
3
|
import type { JsonParser } from './service-caller/json';
|
|
3
4
|
import type { PlanOptions } from './workflows/planning/types';
|
|
@@ -5,4 +6,4 @@ import type { PlanOptions } from './workflows/planning/types';
|
|
|
5
6
|
* Parse XML response from LLM and convert to RawResponsePlanningAIResponse.
|
|
6
7
|
*/
|
|
7
8
|
export declare function parseXMLPlanningResponse(xmlString: string, jsonParser: JsonParser): RawResponsePlanningAIResponse;
|
|
8
|
-
export declare function plan(userInstruction:
|
|
9
|
+
export declare function plan(userInstruction: TUserPrompt, opts: PlanOptions): Promise<PlanningAIResponse>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type TUserPrompt } from '../../../common';
|
|
1
2
|
import type { PlanningAIResponse } from '../../../types';
|
|
2
3
|
import type { PlanOptions } from '../../workflows/planning/types';
|
|
3
|
-
export declare function autoGlmPlanning(userInstruction:
|
|
4
|
+
export declare function autoGlmPlanning(userInstruction: TUserPrompt, options: PlanOptions, getSystemPrompt: () => string): Promise<PlanningAIResponse>;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { type TUserPrompt } from '../../../common';
|
|
1
2
|
import type { PlanningAIResponse } from '../../../types';
|
|
2
3
|
import type { UITarsModelVersion } from '@midscene/shared/env';
|
|
3
4
|
import type { PlanOptions } from '../../workflows/planning/types';
|
|
4
5
|
type ActionType = 'click' | 'left_double' | 'right_single' | 'drag' | 'type' | 'hotkey' | 'finished' | 'scroll' | 'wait';
|
|
5
|
-
export declare function uiTarsPlanning(userInstruction:
|
|
6
|
+
export declare function uiTarsPlanning(userInstruction: TUserPrompt, options: PlanOptions, uiTarsModelVersion: UITarsModelVersion): Promise<PlanningAIResponse>;
|
|
6
7
|
interface BaseAction {
|
|
7
8
|
action_type: ActionType;
|
|
8
9
|
action_inputs: Record<string, any>;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import type { TUserPrompt } from '../../../common';
|
|
1
2
|
import type { DeviceAction, PlanningAIResponse, UIContext } from '../../../types';
|
|
3
|
+
import type { ChatCompletionUserMessageParam } from 'openai/resources/index';
|
|
2
4
|
import type { ConversationHistory } from '../../conversation-history';
|
|
3
5
|
import type { ModelRuntime } from '../../models';
|
|
4
6
|
export interface PlanOptions {
|
|
@@ -10,6 +12,7 @@ export interface PlanOptions {
|
|
|
10
12
|
includeLocateInPlanning: boolean;
|
|
11
13
|
imagesIncludeCount?: number;
|
|
12
14
|
deepThink?: boolean;
|
|
15
|
+
referenceImageMessages?: ChatCompletionUserMessageParam[];
|
|
13
16
|
abortSignal?: AbortSignal;
|
|
14
17
|
}
|
|
15
|
-
export type PlanFn = (userInstruction:
|
|
18
|
+
export type PlanFn = (userInstruction: TUserPrompt, options: PlanOptions) => Promise<PlanningAIResponse>;
|
package/dist/types/common.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { BaseElement, DeviceAction, ElementTreeNode, MidsceneYamlFlowItem, PlanningAction, Rect, Size } from './types';
|
|
2
|
+
import type { ChatCompletionUserMessageParam } from 'openai/resources/index';
|
|
2
3
|
import { z } from 'zod';
|
|
3
4
|
/**
|
|
4
5
|
* Expand the search area to at least 400 x 400 pixels
|
|
@@ -117,6 +118,9 @@ export declare const TUserPromptSchema: z.ZodUnion<[z.ZodString, z.ZodIntersecti
|
|
|
117
118
|
}>>]>;
|
|
118
119
|
export type TMultimodalPrompt = z.infer<typeof TMultimodalPromptSchema>;
|
|
119
120
|
export type TUserPrompt = z.infer<typeof TUserPromptSchema>;
|
|
121
|
+
export declare const userPromptToString: (prompt: TUserPrompt) => string;
|
|
122
|
+
export declare const userPromptToMultimodalPrompt: (prompt: TUserPrompt) => TMultimodalPrompt | undefined;
|
|
123
|
+
export declare const multimodalPromptToChatMessages: (multimodalPrompt?: TMultimodalPrompt) => Promise<ChatCompletionUserMessageParam[]>;
|
|
120
124
|
/**
|
|
121
125
|
* Returns the schema for locator fields.
|
|
122
126
|
* This now returns the input schema which is more permissive and suitable for validation.
|
package/dist/types/types.d.ts
CHANGED
|
@@ -360,7 +360,7 @@ export type ExecutionTaskLogApply<LogParam = {
|
|
|
360
360
|
}> = ExecutionTaskApply<'Log', LogParam, void, void>;
|
|
361
361
|
export type ExecutionTaskLog = ExecutionTask<ExecutionTaskLogApply>;
|
|
362
362
|
export interface ExecutionTaskPlanningParam {
|
|
363
|
-
userInstruction:
|
|
363
|
+
userInstruction: TUserPrompt;
|
|
364
364
|
aiActContext?: string;
|
|
365
365
|
imagesIncludeCount?: number;
|
|
366
366
|
deepThink?: DeepThinkOption;
|
package/dist/types/yaml.d.ts
CHANGED
|
@@ -144,9 +144,10 @@ export interface MidsceneYamlScriptComputerEnv extends MidsceneYamlScriptConfig
|
|
|
144
144
|
}
|
|
145
145
|
export type MidsceneYamlScriptEnv = MidsceneYamlScriptWebEnv | MidsceneYamlScriptAndroidEnv | MidsceneYamlScriptIOSEnv | MidsceneYamlScriptHarmonyEnv | MidsceneYamlScriptComputerEnv;
|
|
146
146
|
export interface MidsceneYamlFlowItemAIAction {
|
|
147
|
-
aiAction?:
|
|
148
|
-
ai?:
|
|
149
|
-
aiAct?:
|
|
147
|
+
aiAction?: TUserPrompt | null;
|
|
148
|
+
ai?: TUserPrompt | null;
|
|
149
|
+
aiAct?: TUserPrompt | null;
|
|
150
|
+
instruction?: TUserPrompt;
|
|
150
151
|
aiActionProgressTips?: string[];
|
|
151
152
|
cacheable?: boolean;
|
|
152
153
|
[key: string]: unknown;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@midscene/core",
|
|
3
3
|
"description": "Automate browser actions, extract data, and perform assertions using AI. It offers JavaScript SDK, Chrome extension, and support for scripting in YAML. See https://midscenejs.com/ for details.",
|
|
4
|
-
"version": "1.9.
|
|
4
|
+
"version": "1.9.2-beta-20260605084246.0",
|
|
5
5
|
"repository": "https://github.com/web-infra-dev/midscene",
|
|
6
6
|
"homepage": "https://midscenejs.com/",
|
|
7
7
|
"main": "./dist/lib/index.js",
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
"semver": "7.5.2",
|
|
98
98
|
"undici": "^6.0.0",
|
|
99
99
|
"zod": "^3.25.1",
|
|
100
|
-
"@midscene/shared": "1.9.
|
|
100
|
+
"@midscene/shared": "1.9.2-beta-20260605084246.0"
|
|
101
101
|
},
|
|
102
102
|
"devDependencies": {
|
|
103
103
|
"@rslib/core": "^0.18.3",
|