@midscene/core 1.2.2-beta-20260116094337.0 → 1.2.2-beta-20260116114131.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/utils.mjs +1 -1
- package/dist/es/task-runner.mjs +1 -2
- package/dist/es/task-runner.mjs.map +1 -1
- package/dist/es/utils.mjs +2 -2
- package/dist/lib/agent/utils.js +1 -1
- package/dist/lib/task-runner.js +1 -2
- package/dist/lib/task-runner.js.map +1 -1
- package/dist/lib/utils.js +2 -2
- package/package.json +2 -2
package/dist/es/agent/utils.mjs
CHANGED
|
@@ -103,7 +103,7 @@ async function matchElementFromCache(context, cacheEntry, cachePrompt, cacheable
|
|
|
103
103
|
return;
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
|
-
const getMidsceneVersion = ()=>"1.2.2-beta-
|
|
106
|
+
const getMidsceneVersion = ()=>"1.2.2-beta-20260116114131.0";
|
|
107
107
|
const parsePrompt = (prompt)=>{
|
|
108
108
|
if ('string' == typeof prompt) return {
|
|
109
109
|
textPrompt: prompt,
|
package/dist/es/task-runner.mjs
CHANGED
|
@@ -205,8 +205,7 @@ class TaskRunner {
|
|
|
205
205
|
}
|
|
206
206
|
latestErrorTask() {
|
|
207
207
|
if ('error' !== this.status) return null;
|
|
208
|
-
|
|
209
|
-
if (errorTaskIndex >= 0) return this.tasks[errorTaskIndex];
|
|
208
|
+
for(let i = this.tasks.length - 1; i >= 0; i--)if ('failed' === this.tasks[i].status) return this.tasks[i];
|
|
210
209
|
return null;
|
|
211
210
|
}
|
|
212
211
|
dump() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-runner.mjs","sources":["../../src/task-runner.ts"],"sourcesContent":["import type { ScreenshotItem } from '@/screenshot-item';\nimport {\n ExecutionDump,\n type ExecutionRecorderItem,\n type ExecutionTask,\n type ExecutionTaskActionApply,\n type ExecutionTaskApply,\n type ExecutionTaskPlanningLocateOutput,\n type ExecutionTaskProgressOptions,\n type ExecutionTaskReturn,\n type ExecutorContext,\n type PlanningActionParamError,\n type UIContext,\n} from '@/types';\nimport { getDebug } from '@midscene/shared/logger';\nimport { assert } from '@midscene/shared/utils';\n\nconst debug = getDebug('task-runner');\nconst UI_CONTEXT_CACHE_TTL_MS = 300;\n\ntype TaskRunnerInitOptions = ExecutionTaskProgressOptions & {\n tasks?: ExecutionTaskApply[];\n onTaskUpdate?: (\n runner: TaskRunner,\n error?: TaskExecutionError,\n ) => Promise<void> | void;\n};\n\ntype TaskRunnerOperationOptions = {\n allowWhenError?: boolean;\n};\n\nexport class TaskRunner {\n name: string;\n\n tasks: ExecutionTask[];\n\n // status of runner\n status: 'init' | 'pending' | 'running' | 'completed' | 'error';\n\n onTaskStart?: ExecutionTaskProgressOptions['onTaskStart'];\n\n private readonly uiContextBuilder: () => Promise<UIContext>;\n\n private readonly onTaskUpdate?:\n | ((runner: TaskRunner, error?: TaskExecutionError) => Promise<void> | void)\n | undefined;\n\n constructor(\n name: string,\n uiContextBuilder: () => Promise<UIContext>,\n options?: TaskRunnerInitOptions,\n ) {\n this.status =\n options?.tasks && options.tasks.length > 0 ? 'pending' : 'init';\n this.name = name;\n this.tasks = (options?.tasks || []).map((item) =>\n this.markTaskAsPending(item),\n );\n this.onTaskStart = options?.onTaskStart;\n this.uiContextBuilder = uiContextBuilder;\n this.onTaskUpdate = options?.onTaskUpdate;\n }\n\n private async emitOnTaskUpdate(error?: TaskExecutionError): Promise<void> {\n if (!this.onTaskUpdate) {\n return;\n }\n await this.onTaskUpdate(this, error);\n }\n\n private lastUiContext?: {\n context: UIContext;\n capturedAt: number;\n };\n\n private async getUiContext(options?: { forceRefresh?: boolean }): Promise<\n UIContext | undefined\n > {\n const now = Date.now();\n const shouldReuse =\n !options?.forceRefresh &&\n this.lastUiContext &&\n now - this.lastUiContext.capturedAt <= UI_CONTEXT_CACHE_TTL_MS;\n\n if (shouldReuse && this.lastUiContext?.context) {\n debug(\n `reuse cached uiContext captured ${now - this.lastUiContext.capturedAt}ms ago`,\n );\n return this.lastUiContext?.context;\n }\n\n try {\n const uiContext = await this.uiContextBuilder();\n if (uiContext) {\n this.lastUiContext = {\n context: uiContext,\n capturedAt: Date.now(),\n };\n } else {\n this.lastUiContext = undefined;\n }\n return uiContext;\n } catch (error) {\n this.lastUiContext = undefined;\n throw error;\n }\n }\n\n private async captureScreenshot(): Promise<ScreenshotItem | undefined> {\n try {\n const uiContext = await this.getUiContext({ forceRefresh: true });\n return uiContext?.screenshot;\n } catch (error) {\n console.error('error while capturing screenshot', error);\n }\n return undefined;\n }\n\n private attachRecorderItem(\n task: ExecutionTask,\n screenshot: ScreenshotItem | undefined,\n phase: 'after-calling',\n ): void {\n if (!phase || !screenshot) {\n return;\n }\n\n const recorderItem: ExecutionRecorderItem = {\n type: 'screenshot',\n ts: Date.now(),\n screenshot,\n timing: phase,\n };\n\n if (!task.recorder) {\n task.recorder = [recorderItem];\n return;\n }\n task.recorder.push(recorderItem);\n }\n\n private markTaskAsPending(task: ExecutionTaskApply): ExecutionTask {\n return {\n status: 'pending',\n ...task,\n };\n }\n\n private normalizeStatusFromError(\n options?: TaskRunnerOperationOptions,\n errorMessage?: string,\n ): void {\n if (this.status !== 'error') {\n return;\n }\n assert(\n options?.allowWhenError,\n errorMessage ||\n `task runner is in error state, cannot proceed\\nerror=${this.latestErrorTask()?.error}\\n${this.latestErrorTask()?.errorStack}`,\n );\n // reset runner state so new tasks can run\n this.status = this.tasks.length > 0 ? 'pending' : 'init';\n }\n\n private findPreviousNonSubTaskUIContext(\n currentIndex: number,\n ): UIContext | undefined {\n for (let i = currentIndex - 1; i >= 0; i--) {\n const candidate = this.tasks[i];\n if (!candidate || candidate.subTask) {\n continue;\n }\n if (candidate.uiContext) {\n return candidate.uiContext;\n }\n }\n return undefined;\n }\n\n async append(\n task: ExecutionTaskApply[] | ExecutionTaskApply,\n options?: TaskRunnerOperationOptions,\n ): Promise<void> {\n this.normalizeStatusFromError(\n options,\n `task runner is in error state, cannot append task\\nerror=${this.latestErrorTask()?.error}\\n${this.latestErrorTask()?.errorStack}`,\n );\n if (Array.isArray(task)) {\n this.tasks.push(...task.map((item) => this.markTaskAsPending(item)));\n } else {\n this.tasks.push(this.markTaskAsPending(task));\n }\n if (this.status !== 'running') {\n this.status = 'pending';\n }\n await this.emitOnTaskUpdate();\n }\n\n async appendAndFlush(\n task: ExecutionTaskApply[] | ExecutionTaskApply,\n options?: TaskRunnerOperationOptions,\n ): Promise<{ output: any; thought?: string } | undefined> {\n await this.append(task, options);\n return this.flush(options);\n }\n\n async flush(\n options?: TaskRunnerOperationOptions,\n ): Promise<{ output: any; thought?: string } | undefined> {\n if (this.status === 'init' && this.tasks.length > 0) {\n console.warn(\n 'illegal state for task runner, status is init but tasks are not empty',\n );\n }\n\n this.normalizeStatusFromError(options, 'task runner is in error state');\n assert(this.status !== 'running', 'task runner is already running');\n assert(this.status !== 'completed', 'task runner is already completed');\n\n const nextPendingIndex = this.tasks.findIndex(\n (task) => task.status === 'pending',\n );\n if (nextPendingIndex < 0) {\n // all tasks are completed\n return;\n }\n\n this.status = 'running';\n await this.emitOnTaskUpdate();\n let taskIndex = nextPendingIndex;\n let successfullyCompleted = true;\n\n let previousFindOutput: ExecutionTaskPlanningLocateOutput | undefined;\n\n while (taskIndex < this.tasks.length) {\n const task = this.tasks[taskIndex];\n assert(\n task.status === 'pending',\n `task status should be pending, but got: ${task.status}`,\n );\n task.timing = {\n start: Date.now(),\n };\n try {\n task.status = 'running';\n await this.emitOnTaskUpdate();\n try {\n if (this.onTaskStart) {\n await this.onTaskStart(task);\n }\n } catch (e) {\n console.error('error in onTaskStart', e);\n }\n assert(\n ['Insight', 'Action Space', 'Planning'].indexOf(task.type) >= 0,\n `unsupported task type: ${task.type}`,\n );\n\n const { executor, param } = task;\n assert(executor, `executor is required for task type: ${task.type}`);\n\n let returnValue;\n let uiContext: UIContext | undefined;\n if (task.subTask) {\n uiContext = this.findPreviousNonSubTaskUIContext(taskIndex);\n assert(\n uiContext,\n 'subTask requires uiContext from previous non-subTask task',\n );\n } else {\n uiContext = await this.getUiContext();\n }\n task.uiContext = uiContext;\n const executorContext: ExecutorContext = {\n task,\n element: previousFindOutput?.element,\n uiContext,\n };\n\n if (task.type === 'Insight') {\n assert(\n task.subType === 'Query' ||\n task.subType === 'Assert' ||\n task.subType === 'WaitFor' ||\n task.subType === 'Boolean' ||\n task.subType === 'Number' ||\n task.subType === 'String',\n `unsupported service subType: ${task.subType}`,\n );\n returnValue = await task.executor(param, executorContext);\n } else if (task.type === 'Planning') {\n returnValue = await task.executor(param, executorContext);\n if (task.subType === 'Locate') {\n previousFindOutput = (\n returnValue as ExecutionTaskReturn<ExecutionTaskPlanningLocateOutput>\n )?.output;\n }\n } else if (task.type === 'Action Space') {\n returnValue = await task.executor(param, executorContext);\n } else {\n console.warn(\n `unsupported task type: ${task.type}, will try to execute it directly`,\n );\n returnValue = await task.executor(param, executorContext);\n }\n\n const isLastTask = taskIndex === this.tasks.length - 1;\n\n if (isLastTask) {\n const screenshot = await this.captureScreenshot();\n this.attachRecorderItem(task, screenshot, 'after-calling');\n }\n\n Object.assign(task, returnValue);\n task.status = 'finished';\n task.timing.end = Date.now();\n task.timing.cost = task.timing.end - task.timing.start;\n await this.emitOnTaskUpdate();\n taskIndex++;\n } catch (e: any) {\n successfullyCompleted = false;\n task.error = e;\n task.errorMessage =\n e?.message || (typeof e === 'string' ? e : 'error-without-message');\n task.errorStack = e.stack;\n\n task.status = 'failed';\n task.timing.end = Date.now();\n task.timing.cost = task.timing.end - task.timing.start;\n await this.emitOnTaskUpdate();\n break;\n }\n }\n\n // set all remaining tasks as cancelled\n for (let i = taskIndex + 1; i < this.tasks.length; i++) {\n this.tasks[i].status = 'cancelled';\n }\n if (taskIndex + 1 < this.tasks.length) {\n await this.emitOnTaskUpdate();\n }\n\n let finalizeError: TaskExecutionError | undefined;\n if (!successfullyCompleted) {\n this.status = 'error';\n const errorTask = this.latestErrorTask();\n const messageBase =\n errorTask?.errorMessage ||\n (errorTask?.error ? String(errorTask.error) : 'Task execution failed');\n const stack = errorTask?.errorStack;\n const message = stack ? `${messageBase}\\n${stack}` : messageBase;\n finalizeError = new TaskExecutionError(message, this, errorTask, {\n cause: errorTask?.error,\n });\n await this.emitOnTaskUpdate(finalizeError);\n } else {\n this.status = 'completed';\n await this.emitOnTaskUpdate();\n }\n\n if (finalizeError) {\n throw finalizeError;\n }\n\n if (this.tasks.length) {\n // return the last output\n const outputIndex = Math.min(taskIndex, this.tasks.length - 1);\n const { thought, output } = this.tasks[outputIndex];\n return {\n thought,\n output,\n };\n }\n }\n\n isInErrorState(): boolean {\n return this.status === 'error';\n }\n\n latestErrorTask(): ExecutionTask | null {\n if (this.status !== 'error') {\n return null;\n }\n const errorTaskIndex = this.tasks.findIndex(\n (task) => task.status === 'failed',\n );\n if (errorTaskIndex >= 0) {\n return this.tasks[errorTaskIndex];\n }\n return null;\n }\n\n dump(): ExecutionDump {\n return new ExecutionDump({\n logTime: Date.now(),\n name: this.name,\n tasks: this.tasks,\n });\n }\n\n async appendErrorPlan(errorMsg: string): Promise<{\n output: undefined;\n runner: TaskRunner;\n }> {\n const errorTask: ExecutionTaskActionApply<PlanningActionParamError> = {\n type: 'Action Space',\n subType: 'Error',\n param: {\n thought: errorMsg,\n },\n thought: errorMsg,\n executor: async () => {\n throw new Error(errorMsg || 'error without thought');\n },\n };\n await this.appendAndFlush(errorTask);\n\n return {\n output: undefined,\n runner: this,\n };\n }\n}\n\nexport class TaskExecutionError extends Error {\n runner: TaskRunner;\n\n errorTask: ExecutionTask | null;\n\n constructor(\n message: string,\n runner: TaskRunner,\n errorTask: ExecutionTask | null,\n options?: { cause?: unknown },\n ) {\n super(message, options);\n this.runner = runner;\n this.errorTask = errorTask;\n }\n}\n"],"names":["debug","getDebug","UI_CONTEXT_CACHE_TTL_MS","TaskRunner","error","options","now","Date","shouldReuse","uiContext","undefined","console","task","screenshot","phase","recorderItem","errorMessage","assert","currentIndex","i","candidate","Array","item","nextPendingIndex","taskIndex","successfullyCompleted","previousFindOutput","e","executor","param","returnValue","executorContext","isLastTask","Object","finalizeError","errorTask","messageBase","String","stack","message","TaskExecutionError","outputIndex","Math","thought","output","errorTaskIndex","ExecutionDump","errorMsg","Error","name","uiContextBuilder","runner"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"task-runner.mjs","sources":["../../src/task-runner.ts"],"sourcesContent":["import type { ScreenshotItem } from '@/screenshot-item';\nimport {\n ExecutionDump,\n type ExecutionRecorderItem,\n type ExecutionTask,\n type ExecutionTaskActionApply,\n type ExecutionTaskApply,\n type ExecutionTaskPlanningLocateOutput,\n type ExecutionTaskProgressOptions,\n type ExecutionTaskReturn,\n type ExecutorContext,\n type PlanningActionParamError,\n type UIContext,\n} from '@/types';\nimport { getDebug } from '@midscene/shared/logger';\nimport { assert } from '@midscene/shared/utils';\n\nconst debug = getDebug('task-runner');\nconst UI_CONTEXT_CACHE_TTL_MS = 300;\n\ntype TaskRunnerInitOptions = ExecutionTaskProgressOptions & {\n tasks?: ExecutionTaskApply[];\n onTaskUpdate?: (\n runner: TaskRunner,\n error?: TaskExecutionError,\n ) => Promise<void> | void;\n};\n\ntype TaskRunnerOperationOptions = {\n allowWhenError?: boolean;\n};\n\nexport class TaskRunner {\n name: string;\n\n tasks: ExecutionTask[];\n\n // status of runner\n status: 'init' | 'pending' | 'running' | 'completed' | 'error';\n\n onTaskStart?: ExecutionTaskProgressOptions['onTaskStart'];\n\n private readonly uiContextBuilder: () => Promise<UIContext>;\n\n private readonly onTaskUpdate?:\n | ((runner: TaskRunner, error?: TaskExecutionError) => Promise<void> | void)\n | undefined;\n\n constructor(\n name: string,\n uiContextBuilder: () => Promise<UIContext>,\n options?: TaskRunnerInitOptions,\n ) {\n this.status =\n options?.tasks && options.tasks.length > 0 ? 'pending' : 'init';\n this.name = name;\n this.tasks = (options?.tasks || []).map((item) =>\n this.markTaskAsPending(item),\n );\n this.onTaskStart = options?.onTaskStart;\n this.uiContextBuilder = uiContextBuilder;\n this.onTaskUpdate = options?.onTaskUpdate;\n }\n\n private async emitOnTaskUpdate(error?: TaskExecutionError): Promise<void> {\n if (!this.onTaskUpdate) {\n return;\n }\n await this.onTaskUpdate(this, error);\n }\n\n private lastUiContext?: {\n context: UIContext;\n capturedAt: number;\n };\n\n private async getUiContext(options?: { forceRefresh?: boolean }): Promise<\n UIContext | undefined\n > {\n const now = Date.now();\n const shouldReuse =\n !options?.forceRefresh &&\n this.lastUiContext &&\n now - this.lastUiContext.capturedAt <= UI_CONTEXT_CACHE_TTL_MS;\n\n if (shouldReuse && this.lastUiContext?.context) {\n debug(\n `reuse cached uiContext captured ${now - this.lastUiContext.capturedAt}ms ago`,\n );\n return this.lastUiContext?.context;\n }\n\n try {\n const uiContext = await this.uiContextBuilder();\n if (uiContext) {\n this.lastUiContext = {\n context: uiContext,\n capturedAt: Date.now(),\n };\n } else {\n this.lastUiContext = undefined;\n }\n return uiContext;\n } catch (error) {\n this.lastUiContext = undefined;\n throw error;\n }\n }\n\n private async captureScreenshot(): Promise<ScreenshotItem | undefined> {\n try {\n const uiContext = await this.getUiContext({ forceRefresh: true });\n return uiContext?.screenshot;\n } catch (error) {\n console.error('error while capturing screenshot', error);\n }\n return undefined;\n }\n\n private attachRecorderItem(\n task: ExecutionTask,\n screenshot: ScreenshotItem | undefined,\n phase: 'after-calling',\n ): void {\n if (!phase || !screenshot) {\n return;\n }\n\n const recorderItem: ExecutionRecorderItem = {\n type: 'screenshot',\n ts: Date.now(),\n screenshot,\n timing: phase,\n };\n\n if (!task.recorder) {\n task.recorder = [recorderItem];\n return;\n }\n task.recorder.push(recorderItem);\n }\n\n private markTaskAsPending(task: ExecutionTaskApply): ExecutionTask {\n return {\n status: 'pending',\n ...task,\n };\n }\n\n private normalizeStatusFromError(\n options?: TaskRunnerOperationOptions,\n errorMessage?: string,\n ): void {\n if (this.status !== 'error') {\n return;\n }\n assert(\n options?.allowWhenError,\n errorMessage ||\n `task runner is in error state, cannot proceed\\nerror=${this.latestErrorTask()?.error}\\n${this.latestErrorTask()?.errorStack}`,\n );\n // reset runner state so new tasks can run\n this.status = this.tasks.length > 0 ? 'pending' : 'init';\n }\n\n private findPreviousNonSubTaskUIContext(\n currentIndex: number,\n ): UIContext | undefined {\n for (let i = currentIndex - 1; i >= 0; i--) {\n const candidate = this.tasks[i];\n if (!candidate || candidate.subTask) {\n continue;\n }\n if (candidate.uiContext) {\n return candidate.uiContext;\n }\n }\n return undefined;\n }\n\n async append(\n task: ExecutionTaskApply[] | ExecutionTaskApply,\n options?: TaskRunnerOperationOptions,\n ): Promise<void> {\n this.normalizeStatusFromError(\n options,\n `task runner is in error state, cannot append task\\nerror=${this.latestErrorTask()?.error}\\n${this.latestErrorTask()?.errorStack}`,\n );\n if (Array.isArray(task)) {\n this.tasks.push(...task.map((item) => this.markTaskAsPending(item)));\n } else {\n this.tasks.push(this.markTaskAsPending(task));\n }\n if (this.status !== 'running') {\n this.status = 'pending';\n }\n await this.emitOnTaskUpdate();\n }\n\n async appendAndFlush(\n task: ExecutionTaskApply[] | ExecutionTaskApply,\n options?: TaskRunnerOperationOptions,\n ): Promise<{ output: any; thought?: string } | undefined> {\n await this.append(task, options);\n return this.flush(options);\n }\n\n async flush(\n options?: TaskRunnerOperationOptions,\n ): Promise<{ output: any; thought?: string } | undefined> {\n if (this.status === 'init' && this.tasks.length > 0) {\n console.warn(\n 'illegal state for task runner, status is init but tasks are not empty',\n );\n }\n\n this.normalizeStatusFromError(options, 'task runner is in error state');\n assert(this.status !== 'running', 'task runner is already running');\n assert(this.status !== 'completed', 'task runner is already completed');\n\n const nextPendingIndex = this.tasks.findIndex(\n (task) => task.status === 'pending',\n );\n if (nextPendingIndex < 0) {\n // all tasks are completed\n return;\n }\n\n this.status = 'running';\n await this.emitOnTaskUpdate();\n let taskIndex = nextPendingIndex;\n let successfullyCompleted = true;\n\n let previousFindOutput: ExecutionTaskPlanningLocateOutput | undefined;\n\n while (taskIndex < this.tasks.length) {\n const task = this.tasks[taskIndex];\n assert(\n task.status === 'pending',\n `task status should be pending, but got: ${task.status}`,\n );\n task.timing = {\n start: Date.now(),\n };\n try {\n task.status = 'running';\n await this.emitOnTaskUpdate();\n try {\n if (this.onTaskStart) {\n await this.onTaskStart(task);\n }\n } catch (e) {\n console.error('error in onTaskStart', e);\n }\n assert(\n ['Insight', 'Action Space', 'Planning'].indexOf(task.type) >= 0,\n `unsupported task type: ${task.type}`,\n );\n\n const { executor, param } = task;\n assert(executor, `executor is required for task type: ${task.type}`);\n\n let returnValue;\n let uiContext: UIContext | undefined;\n if (task.subTask) {\n uiContext = this.findPreviousNonSubTaskUIContext(taskIndex);\n assert(\n uiContext,\n 'subTask requires uiContext from previous non-subTask task',\n );\n } else {\n uiContext = await this.getUiContext();\n }\n task.uiContext = uiContext;\n const executorContext: ExecutorContext = {\n task,\n element: previousFindOutput?.element,\n uiContext,\n };\n\n if (task.type === 'Insight') {\n assert(\n task.subType === 'Query' ||\n task.subType === 'Assert' ||\n task.subType === 'WaitFor' ||\n task.subType === 'Boolean' ||\n task.subType === 'Number' ||\n task.subType === 'String',\n `unsupported service subType: ${task.subType}`,\n );\n returnValue = await task.executor(param, executorContext);\n } else if (task.type === 'Planning') {\n returnValue = await task.executor(param, executorContext);\n if (task.subType === 'Locate') {\n previousFindOutput = (\n returnValue as ExecutionTaskReturn<ExecutionTaskPlanningLocateOutput>\n )?.output;\n }\n } else if (task.type === 'Action Space') {\n returnValue = await task.executor(param, executorContext);\n } else {\n console.warn(\n `unsupported task type: ${task.type}, will try to execute it directly`,\n );\n returnValue = await task.executor(param, executorContext);\n }\n\n const isLastTask = taskIndex === this.tasks.length - 1;\n\n if (isLastTask) {\n const screenshot = await this.captureScreenshot();\n this.attachRecorderItem(task, screenshot, 'after-calling');\n }\n\n Object.assign(task, returnValue);\n task.status = 'finished';\n task.timing.end = Date.now();\n task.timing.cost = task.timing.end - task.timing.start;\n await this.emitOnTaskUpdate();\n taskIndex++;\n } catch (e: any) {\n successfullyCompleted = false;\n task.error = e;\n task.errorMessage =\n e?.message || (typeof e === 'string' ? e : 'error-without-message');\n task.errorStack = e.stack;\n\n task.status = 'failed';\n task.timing.end = Date.now();\n task.timing.cost = task.timing.end - task.timing.start;\n await this.emitOnTaskUpdate();\n break;\n }\n }\n\n // set all remaining tasks as cancelled\n for (let i = taskIndex + 1; i < this.tasks.length; i++) {\n this.tasks[i].status = 'cancelled';\n }\n if (taskIndex + 1 < this.tasks.length) {\n await this.emitOnTaskUpdate();\n }\n\n let finalizeError: TaskExecutionError | undefined;\n if (!successfullyCompleted) {\n this.status = 'error';\n const errorTask = this.latestErrorTask();\n const messageBase =\n errorTask?.errorMessage ||\n (errorTask?.error ? String(errorTask.error) : 'Task execution failed');\n const stack = errorTask?.errorStack;\n const message = stack ? `${messageBase}\\n${stack}` : messageBase;\n finalizeError = new TaskExecutionError(message, this, errorTask, {\n cause: errorTask?.error,\n });\n await this.emitOnTaskUpdate(finalizeError);\n } else {\n this.status = 'completed';\n await this.emitOnTaskUpdate();\n }\n\n if (finalizeError) {\n throw finalizeError;\n }\n\n if (this.tasks.length) {\n // return the last output\n const outputIndex = Math.min(taskIndex, this.tasks.length - 1);\n const { thought, output } = this.tasks[outputIndex];\n return {\n thought,\n output,\n };\n }\n }\n\n isInErrorState(): boolean {\n return this.status === 'error';\n }\n\n latestErrorTask(): ExecutionTask | null {\n if (this.status !== 'error') {\n return null;\n }\n // Find the LAST failed task (not the first one)\n // This is important when using allowWhenError to continue after errors\n for (let i = this.tasks.length - 1; i >= 0; i--) {\n if (this.tasks[i].status === 'failed') {\n return this.tasks[i];\n }\n }\n return null;\n }\n\n dump(): ExecutionDump {\n return new ExecutionDump({\n logTime: Date.now(),\n name: this.name,\n tasks: this.tasks,\n });\n }\n\n async appendErrorPlan(errorMsg: string): Promise<{\n output: undefined;\n runner: TaskRunner;\n }> {\n const errorTask: ExecutionTaskActionApply<PlanningActionParamError> = {\n type: 'Action Space',\n subType: 'Error',\n param: {\n thought: errorMsg,\n },\n thought: errorMsg,\n executor: async () => {\n throw new Error(errorMsg || 'error without thought');\n },\n };\n await this.appendAndFlush(errorTask);\n\n return {\n output: undefined,\n runner: this,\n };\n }\n}\n\nexport class TaskExecutionError extends Error {\n runner: TaskRunner;\n\n errorTask: ExecutionTask | null;\n\n constructor(\n message: string,\n runner: TaskRunner,\n errorTask: ExecutionTask | null,\n options?: { cause?: unknown },\n ) {\n super(message, options);\n this.runner = runner;\n this.errorTask = errorTask;\n }\n}\n"],"names":["debug","getDebug","UI_CONTEXT_CACHE_TTL_MS","TaskRunner","error","options","now","Date","shouldReuse","uiContext","undefined","console","task","screenshot","phase","recorderItem","errorMessage","assert","currentIndex","i","candidate","Array","item","nextPendingIndex","taskIndex","successfullyCompleted","previousFindOutput","e","executor","param","returnValue","executorContext","isLastTask","Object","finalizeError","errorTask","messageBase","String","stack","message","TaskExecutionError","outputIndex","Math","thought","output","ExecutionDump","errorMsg","Error","name","uiContextBuilder","runner"],"mappings":"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"}
|