@midscene/core 0.27.1-beta-20250822053848.0 → 0.27.1-beta-20250822094725.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/dist/es/agent/agent.mjs +518 -0
  2. package/dist/es/agent/agent.mjs.map +1 -0
  3. package/dist/es/agent/index.mjs +6 -0
  4. package/dist/es/agent/task-cache.mjs +149 -0
  5. package/dist/es/agent/task-cache.mjs.map +1 -0
  6. package/dist/es/agent/tasks.mjs +767 -0
  7. package/dist/es/agent/tasks.mjs.map +1 -0
  8. package/dist/es/agent/ui-utils.mjs +89 -0
  9. package/dist/es/agent/ui-utils.mjs.map +1 -0
  10. package/dist/es/agent/utils.mjs +337 -0
  11. package/dist/es/agent/utils.mjs.map +1 -0
  12. package/dist/es/device/index.mjs +20 -0
  13. package/dist/es/device/index.mjs.map +1 -0
  14. package/dist/es/index.mjs +2 -1
  15. package/dist/es/index.mjs.map +1 -1
  16. package/dist/es/types.mjs.map +1 -1
  17. package/dist/es/utils.mjs +2 -2
  18. package/dist/es/yaml/builder.mjs +13 -0
  19. package/dist/es/yaml/builder.mjs.map +1 -0
  20. package/dist/es/yaml/index.mjs +3 -0
  21. package/dist/es/yaml/player.mjs +375 -0
  22. package/dist/es/yaml/player.mjs.map +1 -0
  23. package/dist/es/yaml/utils.mjs +39 -0
  24. package/dist/es/yaml/utils.mjs.map +1 -0
  25. package/dist/lib/agent/agent.js +562 -0
  26. package/dist/lib/agent/agent.js.map +1 -0
  27. package/dist/lib/agent/index.js +90 -0
  28. package/dist/lib/agent/index.js.map +1 -0
  29. package/dist/lib/agent/task-cache.js +201 -0
  30. package/dist/lib/agent/task-cache.js.map +1 -0
  31. package/dist/lib/agent/tasks.js +804 -0
  32. package/dist/lib/agent/tasks.js.map +1 -0
  33. package/dist/lib/agent/ui-utils.js +141 -0
  34. package/dist/lib/agent/ui-utils.js.map +1 -0
  35. package/dist/lib/agent/utils.js +417 -0
  36. package/dist/lib/agent/utils.js.map +1 -0
  37. package/dist/lib/device/index.js +54 -0
  38. package/dist/lib/device/index.js.map +1 -0
  39. package/dist/lib/index.js +5 -1
  40. package/dist/lib/index.js.map +1 -1
  41. package/dist/lib/types.js.map +1 -1
  42. package/dist/lib/utils.js +2 -2
  43. package/dist/lib/yaml/builder.js +57 -0
  44. package/dist/lib/yaml/builder.js.map +1 -0
  45. package/dist/lib/yaml/index.js +80 -0
  46. package/dist/lib/yaml/index.js.map +1 -0
  47. package/dist/lib/yaml/player.js +409 -0
  48. package/dist/lib/yaml/player.js.map +1 -0
  49. package/dist/lib/yaml/utils.js +86 -0
  50. package/dist/lib/yaml/utils.js.map +1 -0
  51. package/dist/types/agent/agent.d.ts +123 -0
  52. package/dist/types/agent/index.d.ts +9 -0
  53. package/dist/types/agent/task-cache.d.ts +38 -0
  54. package/dist/types/agent/tasks.d.ts +56 -0
  55. package/dist/types/agent/ui-utils.d.ts +11 -0
  56. package/dist/types/agent/utils.d.ts +54 -0
  57. package/dist/types/device/index.d.ts +55 -0
  58. package/dist/types/index.d.ts +1 -0
  59. package/dist/types/types.d.ts +1 -0
  60. package/dist/types/yaml/builder.d.ts +2 -0
  61. package/dist/types/yaml/index.d.ts +3 -0
  62. package/dist/types/yaml/player.d.ts +34 -0
  63. package/dist/types/yaml/utils.d.ts +3 -0
  64. package/package.json +27 -3
@@ -0,0 +1,804 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, definition)=>{
5
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
+ enumerable: true,
7
+ get: definition[key]
8
+ });
9
+ };
10
+ })();
11
+ (()=>{
12
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
13
+ })();
14
+ (()=>{
15
+ __webpack_require__.r = (exports1)=>{
16
+ if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
17
+ value: 'Module'
18
+ });
19
+ Object.defineProperty(exports1, '__esModule', {
20
+ value: true
21
+ });
22
+ };
23
+ })();
24
+ var __webpack_exports__ = {};
25
+ __webpack_require__.r(__webpack_exports__);
26
+ __webpack_require__.d(__webpack_exports__, {
27
+ locatePlanForLocate: ()=>locatePlanForLocate,
28
+ PageTaskExecutor: ()=>PageTaskExecutor
29
+ });
30
+ const index_js_namespaceObject = require("../ai-model/index.js");
31
+ const external_index_js_namespaceObject = require("../index.js");
32
+ const external_utils_js_namespaceObject = require("../utils.js");
33
+ const constants_namespaceObject = require("@midscene/shared/constants");
34
+ const env_namespaceObject = require("@midscene/shared/env");
35
+ const logger_namespaceObject = require("@midscene/shared/logger");
36
+ const utils_namespaceObject = require("@midscene/shared/utils");
37
+ const external_ui_utils_js_namespaceObject = require("./ui-utils.js");
38
+ const external_utils_js_namespaceObject_1 = require("./utils.js");
39
+ function _define_property(obj, key, value) {
40
+ if (key in obj) Object.defineProperty(obj, key, {
41
+ value: value,
42
+ enumerable: true,
43
+ configurable: true,
44
+ writable: true
45
+ });
46
+ else obj[key] = value;
47
+ return obj;
48
+ }
49
+ const debug = (0, logger_namespaceObject.getDebug)('device-task-executor');
50
+ const defaultReplanningCycleLimit = 10;
51
+ function locatePlanForLocate(param) {
52
+ const locate = 'string' == typeof param ? {
53
+ prompt: param
54
+ } : param;
55
+ const locatePlan = {
56
+ type: 'Locate',
57
+ locate,
58
+ param: locate,
59
+ thought: ''
60
+ };
61
+ return locatePlan;
62
+ }
63
+ class PageTaskExecutor {
64
+ async recordScreenshot(timing) {
65
+ const base64 = await this.page.screenshotBase64();
66
+ const item = {
67
+ type: 'screenshot',
68
+ ts: Date.now(),
69
+ screenshot: base64,
70
+ timing
71
+ };
72
+ return item;
73
+ }
74
+ async getElementXpath(pageContext, element) {
75
+ var _element_attributes;
76
+ if (!this.page.getXpathsByPoint) return void debug('getXpathsByPoint is not supported for this page');
77
+ let elementId = null == element ? void 0 : element.id;
78
+ if ((null == element ? void 0 : element.isOrderSensitive) !== void 0) {
79
+ const xpaths = await this.page.getXpathsByPoint({
80
+ left: element.center[0],
81
+ top: element.center[1]
82
+ }, null == element ? void 0 : element.isOrderSensitive);
83
+ return xpaths;
84
+ }
85
+ if ((null == element ? void 0 : null == (_element_attributes = element.attributes) ? void 0 : _element_attributes.nodeType) === constants_namespaceObject.NodeType.POSITION) {
86
+ await this.insight.contextRetrieverFn('locate');
87
+ const info = (0, index_js_namespaceObject.elementByPositionWithElementInfo)(pageContext.tree, {
88
+ x: element.center[0],
89
+ y: element.center[1]
90
+ }, {
91
+ requireStrictDistance: false,
92
+ filterPositionElements: true
93
+ });
94
+ if (null == info ? void 0 : info.id) elementId = info.id;
95
+ else debug('no element id found for position node, will not update cache', element);
96
+ }
97
+ if (!elementId) return;
98
+ try {
99
+ const result = await this.page.getXpathsById(elementId);
100
+ return result;
101
+ } catch (error) {
102
+ debug('getXpathsById error: ', error);
103
+ }
104
+ }
105
+ prependExecutorWithScreenshot(taskApply, appendAfterExecution = false) {
106
+ const taskWithScreenshot = {
107
+ ...taskApply,
108
+ executor: async (param, context, ...args)=>{
109
+ const recorder = [];
110
+ const { task } = context;
111
+ task.recorder = recorder;
112
+ const shot = await this.recordScreenshot(`before ${task.type}`);
113
+ recorder.push(shot);
114
+ const result = await taskApply.executor(param, context, ...args);
115
+ if ('Action' === taskApply.type) await Promise.all([
116
+ (async ()=>{
117
+ await (0, external_utils_js_namespaceObject.sleep)(100);
118
+ if (this.page.beforeAction) {
119
+ debug('will call "beforeAction" for page');
120
+ await this.page.beforeAction();
121
+ }
122
+ })(),
123
+ (0, external_utils_js_namespaceObject.sleep)(200)
124
+ ]);
125
+ if (appendAfterExecution) {
126
+ const shot2 = await this.recordScreenshot('after Action');
127
+ recorder.push(shot2);
128
+ }
129
+ return result;
130
+ }
131
+ };
132
+ return taskWithScreenshot;
133
+ }
134
+ async convertPlanToExecutable(plans) {
135
+ const tasks = [];
136
+ const taskForLocatePlan = (plan, detailedLocateParam, onResult)=>{
137
+ if ('string' == typeof detailedLocateParam) detailedLocateParam = {
138
+ prompt: detailedLocateParam
139
+ };
140
+ const taskFind = {
141
+ type: 'Insight',
142
+ subType: 'Locate',
143
+ param: detailedLocateParam,
144
+ thought: plan.thought,
145
+ executor: async (param, taskContext)=>{
146
+ var _this_taskCache, _locateCacheRecord_cacheContent;
147
+ const { task } = taskContext;
148
+ (0, utils_namespaceObject.assert)((null == param ? void 0 : param.prompt) || (null == param ? void 0 : param.id) || (null == param ? void 0 : param.bbox), `No prompt or id or position or bbox to locate, param=${JSON.stringify(param)}`);
149
+ let insightDump;
150
+ let usage;
151
+ const dumpCollector = (dump)=>{
152
+ var _dump_taskInfo;
153
+ insightDump = dump;
154
+ usage = null == dump ? void 0 : null == (_dump_taskInfo = dump.taskInfo) ? void 0 : _dump_taskInfo.usage;
155
+ task.log = {
156
+ dump: insightDump
157
+ };
158
+ task.usage = usage;
159
+ };
160
+ this.insight.onceDumpUpdatedFn = dumpCollector;
161
+ const shotTime = Date.now();
162
+ const pageContext = await this.insight.contextRetrieverFn('locate');
163
+ task.pageContext = pageContext;
164
+ const recordItem = {
165
+ type: 'screenshot',
166
+ ts: shotTime,
167
+ screenshot: pageContext.screenshotBase64,
168
+ timing: 'before Insight'
169
+ };
170
+ task.recorder = [
171
+ recordItem
172
+ ];
173
+ const elementFromXpath = param.xpath && this.page.getElementInfoByXpath ? await this.page.getElementInfoByXpath(param.xpath) : void 0;
174
+ const userExpectedPathHitFlag = !!elementFromXpath;
175
+ const cachePrompt = param.prompt;
176
+ const locateCacheRecord = null == (_this_taskCache = this.taskCache) ? void 0 : _this_taskCache.matchLocateCache(cachePrompt);
177
+ const xpaths = null == locateCacheRecord ? void 0 : null == (_locateCacheRecord_cacheContent = locateCacheRecord.cacheContent) ? void 0 : _locateCacheRecord_cacheContent.xpaths;
178
+ const elementFromCache = userExpectedPathHitFlag ? null : await (0, external_utils_js_namespaceObject_1.matchElementFromCache)(this, xpaths, cachePrompt, param.cacheable);
179
+ const cacheHitFlag = !!elementFromCache;
180
+ const elementFromPlan = userExpectedPathHitFlag || cacheHitFlag ? void 0 : (0, external_utils_js_namespaceObject_1.matchElementFromPlan)(param, pageContext.tree);
181
+ const planHitFlag = !!elementFromPlan;
182
+ const elementFromAiLocate = userExpectedPathHitFlag || cacheHitFlag || planHitFlag ? void 0 : (await this.insight.locate(param, {
183
+ context: pageContext
184
+ })).element;
185
+ const aiLocateHitFlag = !!elementFromAiLocate;
186
+ const element = elementFromXpath || elementFromCache || elementFromPlan || elementFromAiLocate;
187
+ let currentXpaths;
188
+ if (element && this.taskCache && !cacheHitFlag && (null == param ? void 0 : param.cacheable) !== false) {
189
+ const elementXpaths = await this.getElementXpath(pageContext, element);
190
+ if (null == elementXpaths ? void 0 : elementXpaths.length) {
191
+ currentXpaths = elementXpaths;
192
+ this.taskCache.updateOrAppendCacheRecord({
193
+ type: 'locate',
194
+ prompt: cachePrompt,
195
+ xpaths: elementXpaths
196
+ }, locateCacheRecord);
197
+ } else debug('no xpaths found, will not update cache', cachePrompt, elementXpaths);
198
+ }
199
+ if (!element) throw new Error(`Element not found: ${param.prompt}`);
200
+ let hitBy;
201
+ if (userExpectedPathHitFlag) hitBy = {
202
+ from: 'User expected path',
203
+ context: {
204
+ xpath: param.xpath
205
+ }
206
+ };
207
+ else if (cacheHitFlag) hitBy = {
208
+ from: 'Cache',
209
+ context: {
210
+ xpathsFromCache: xpaths,
211
+ xpathsToSave: currentXpaths
212
+ }
213
+ };
214
+ else if (planHitFlag) hitBy = {
215
+ from: 'Planning',
216
+ context: {
217
+ id: null == elementFromPlan ? void 0 : elementFromPlan.id,
218
+ bbox: null == elementFromPlan ? void 0 : elementFromPlan.bbox
219
+ }
220
+ };
221
+ else if (aiLocateHitFlag) hitBy = {
222
+ from: 'AI model',
223
+ context: {
224
+ prompt: param.prompt
225
+ }
226
+ };
227
+ null == onResult || onResult(element);
228
+ return {
229
+ output: {
230
+ element
231
+ },
232
+ pageContext,
233
+ hitBy
234
+ };
235
+ }
236
+ };
237
+ return taskFind;
238
+ };
239
+ for (const plan of plans)if ('Locate' === plan.type) {
240
+ var _plan_locate, _plan_locate1;
241
+ if (!plan.locate || null === plan.locate || (null == (_plan_locate = plan.locate) ? void 0 : _plan_locate.id) === null || (null == (_plan_locate1 = plan.locate) ? void 0 : _plan_locate1.id) === 'null') {
242
+ debug('Locate action with id is null, will be ignored', plan);
243
+ continue;
244
+ }
245
+ const taskLocate = taskForLocatePlan(plan, plan.locate);
246
+ tasks.push(taskLocate);
247
+ } else if ('Error' === plan.type) {
248
+ var _plan_param;
249
+ const taskActionError = {
250
+ type: 'Action',
251
+ subType: 'Error',
252
+ param: plan.param,
253
+ thought: plan.thought || (null == (_plan_param = plan.param) ? void 0 : _plan_param.thought),
254
+ locate: plan.locate,
255
+ executor: async ()=>{
256
+ var _plan_param;
257
+ throw new Error((null == plan ? void 0 : plan.thought) || (null == (_plan_param = plan.param) ? void 0 : _plan_param.thought) || 'error without thought');
258
+ }
259
+ };
260
+ tasks.push(taskActionError);
261
+ } else if ('Finished' === plan.type) {
262
+ const taskActionFinished = {
263
+ type: 'Action',
264
+ subType: 'Finished',
265
+ param: null,
266
+ thought: plan.thought,
267
+ locate: plan.locate,
268
+ executor: async (param)=>{}
269
+ };
270
+ tasks.push(taskActionFinished);
271
+ } else if ('Sleep' === plan.type) {
272
+ const taskActionSleep = {
273
+ type: 'Action',
274
+ subType: 'Sleep',
275
+ param: plan.param,
276
+ thought: plan.thought,
277
+ locate: plan.locate,
278
+ executor: async (taskParam)=>{
279
+ await (0, external_utils_js_namespaceObject.sleep)((null == taskParam ? void 0 : taskParam.timeMs) || 3000);
280
+ }
281
+ };
282
+ tasks.push(taskActionSleep);
283
+ } else if ('Drag' === plan.type) {
284
+ const taskActionDrag = {
285
+ type: 'Action',
286
+ subType: 'Drag',
287
+ param: plan.param,
288
+ thought: plan.thought,
289
+ locate: plan.locate,
290
+ executor: async (taskParam)=>{
291
+ (0, utils_namespaceObject.assert)((null == taskParam ? void 0 : taskParam.start_box) && (null == taskParam ? void 0 : taskParam.end_box), 'No start_box or end_box to drag');
292
+ await this.page.mouse.drag(taskParam.start_box, taskParam.end_box);
293
+ }
294
+ };
295
+ tasks.push(taskActionDrag);
296
+ } else {
297
+ const planType = plan.type;
298
+ const actionSpace = await this.page.actionSpace();
299
+ const action = actionSpace.find((action)=>action.name === planType);
300
+ const param = plan.param;
301
+ if (!action) throw new Error(`Action type '${planType}' not found`);
302
+ const locateFields = action ? (0, index_js_namespaceObject.findAllMidsceneLocatorField)(action.paramSchema) : [];
303
+ const requiredLocateFields = action ? (0, index_js_namespaceObject.findAllMidsceneLocatorField)(action.paramSchema, true) : [];
304
+ locateFields.forEach((field)=>{
305
+ if (param[field]) {
306
+ const locatePlan = locatePlanForLocate(param[field]);
307
+ debug('will prepend locate param for field', `action.type=${planType}`, `param=${JSON.stringify(param[field])}`, `locatePlan=${JSON.stringify(locatePlan)}`);
308
+ const locateTask = taskForLocatePlan(locatePlan, param[field], (result)=>{
309
+ param[field] = result;
310
+ });
311
+ tasks.push(locateTask);
312
+ } else {
313
+ (0, utils_namespaceObject.assert)(!requiredLocateFields.includes(field), `Required locate field '${field}' is not provided for action ${planType}`);
314
+ debug(`field '${field}' is not provided for action ${planType}`);
315
+ }
316
+ });
317
+ const task = {
318
+ type: 'Action',
319
+ subType: planType,
320
+ thought: plan.thought,
321
+ param: plan.param,
322
+ executor: async (param, context)=>{
323
+ var _context_element;
324
+ debug('executing action', planType, param, `context.element.center: ${null == (_context_element = context.element) ? void 0 : _context_element.center}`);
325
+ const pageContext = await this.insight.contextRetrieverFn('locate');
326
+ context.task.pageContext = pageContext;
327
+ requiredLocateFields.forEach((field)=>{
328
+ (0, utils_namespaceObject.assert)(param[field], `field '${field}' is required for action ${planType} but not provided. Cannot execute action ${planType}.`);
329
+ });
330
+ const actionFn = action.call.bind(this.page);
331
+ await actionFn(param, context);
332
+ return {
333
+ output: {
334
+ success: true,
335
+ action: planType,
336
+ param: param
337
+ }
338
+ };
339
+ }
340
+ };
341
+ tasks.push(task);
342
+ }
343
+ const wrappedTasks = tasks.map((task, index)=>{
344
+ if ('Action' === task.type) return this.prependExecutorWithScreenshot(task, index === tasks.length - 1);
345
+ return task;
346
+ });
347
+ return {
348
+ tasks: wrappedTasks
349
+ };
350
+ }
351
+ async setupPlanningContext(executorContext) {
352
+ const shotTime = Date.now();
353
+ const pageContext = await this.insight.contextRetrieverFn('locate');
354
+ const recordItem = {
355
+ type: 'screenshot',
356
+ ts: shotTime,
357
+ screenshot: pageContext.screenshotBase64,
358
+ timing: 'before Planning'
359
+ };
360
+ executorContext.task.recorder = [
361
+ recordItem
362
+ ];
363
+ executorContext.task.pageContext = pageContext;
364
+ return {
365
+ pageContext
366
+ };
367
+ }
368
+ async loadYamlFlowAsPlanning(userInstruction, yamlString) {
369
+ const taskExecutor = new external_index_js_namespaceObject.Executor((0, external_ui_utils_js_namespaceObject.taskTitleStr)('Action', userInstruction), {
370
+ onTaskStart: this.onTaskStartCallback
371
+ });
372
+ const task = {
373
+ type: 'Planning',
374
+ subType: 'LoadYaml',
375
+ locate: null,
376
+ param: {
377
+ userInstruction
378
+ },
379
+ executor: async (param, executorContext)=>{
380
+ await this.setupPlanningContext(executorContext);
381
+ return {
382
+ output: {
383
+ actions: [],
384
+ more_actions_needed_by_instruction: false,
385
+ log: '',
386
+ yamlString
387
+ },
388
+ cache: {
389
+ hit: true
390
+ },
391
+ hitBy: {
392
+ from: 'Cache',
393
+ context: {
394
+ yamlString
395
+ }
396
+ }
397
+ };
398
+ }
399
+ };
400
+ await taskExecutor.append(task);
401
+ await taskExecutor.flush();
402
+ return {
403
+ executor: taskExecutor
404
+ };
405
+ }
406
+ planningTaskFromPrompt(userInstruction, log, actionContext) {
407
+ const task = {
408
+ type: 'Planning',
409
+ subType: 'Plan',
410
+ locate: null,
411
+ param: {
412
+ userInstruction,
413
+ log
414
+ },
415
+ executor: async (param, executorContext)=>{
416
+ const startTime = Date.now();
417
+ const { pageContext } = await this.setupPlanningContext(executorContext);
418
+ (0, utils_namespaceObject.assert)(this.page.actionSpace, 'actionSpace for device is not implemented');
419
+ const actionSpace = await this.page.actionSpace();
420
+ debug('actionSpace for page is:', actionSpace.map((action)=>action.name).join(', '));
421
+ (0, utils_namespaceObject.assert)(Array.isArray(actionSpace), 'actionSpace must be an array');
422
+ if (0 === actionSpace.length) console.warn(`ActionSpace for ${this.page.pageType} is empty. This may lead to unexpected behavior.`);
423
+ const planResult = await (0, external_index_js_namespaceObject.plan)(param.userInstruction, {
424
+ context: pageContext,
425
+ log: param.log,
426
+ actionContext,
427
+ pageType: this.page.pageType,
428
+ actionSpace
429
+ });
430
+ const { actions, log, more_actions_needed_by_instruction, error, usage, rawResponse, sleep } = planResult;
431
+ executorContext.task.log = {
432
+ ...executorContext.task.log || {},
433
+ rawResponse
434
+ };
435
+ executorContext.task.usage = usage;
436
+ const finalActions = actions || [];
437
+ if (sleep) {
438
+ const timeNow = Date.now();
439
+ const timeRemaining = sleep - (timeNow - startTime);
440
+ if (timeRemaining > 0) finalActions.push({
441
+ type: 'Sleep',
442
+ param: {
443
+ timeMs: timeRemaining
444
+ },
445
+ locate: null
446
+ });
447
+ }
448
+ if (0 === finalActions.length) (0, utils_namespaceObject.assert)(!more_actions_needed_by_instruction || sleep, error ? `Failed to plan: ${error}` : 'No plan found');
449
+ return {
450
+ output: {
451
+ actions: finalActions,
452
+ more_actions_needed_by_instruction,
453
+ log,
454
+ yamlFlow: planResult.yamlFlow
455
+ },
456
+ cache: {
457
+ hit: false
458
+ },
459
+ pageContext
460
+ };
461
+ }
462
+ };
463
+ return task;
464
+ }
465
+ planningTaskToGoal(userInstruction, modelPreferences) {
466
+ const task = {
467
+ type: 'Planning',
468
+ subType: 'Plan',
469
+ locate: null,
470
+ param: {
471
+ userInstruction
472
+ },
473
+ executor: async (param, executorContext)=>{
474
+ var _actions_;
475
+ const { pageContext } = await this.setupPlanningContext(executorContext);
476
+ const imagePayload = await (0, index_js_namespaceObject.resizeImageForUiTars)(pageContext.screenshotBase64, pageContext.size, modelPreferences);
477
+ this.appendConversationHistory({
478
+ role: 'user',
479
+ content: [
480
+ {
481
+ type: 'image_url',
482
+ image_url: {
483
+ url: imagePayload
484
+ }
485
+ }
486
+ ]
487
+ });
488
+ const planResult = await (0, index_js_namespaceObject.vlmPlanning)({
489
+ userInstruction: param.userInstruction,
490
+ conversationHistory: this.conversationHistory,
491
+ size: pageContext.size,
492
+ modelPreferences
493
+ });
494
+ const { actions, action_summary, usage } = planResult;
495
+ executorContext.task.log = {
496
+ ...executorContext.task.log || {},
497
+ rawResponse: planResult.rawResponse
498
+ };
499
+ executorContext.task.usage = usage;
500
+ this.appendConversationHistory({
501
+ role: 'assistant',
502
+ content: action_summary
503
+ });
504
+ return {
505
+ output: {
506
+ actions,
507
+ thought: null == (_actions_ = actions[0]) ? void 0 : _actions_.thought,
508
+ actionType: actions[0].type,
509
+ more_actions_needed_by_instruction: true,
510
+ log: '',
511
+ yamlFlow: planResult.yamlFlow
512
+ },
513
+ cache: {
514
+ hit: false
515
+ }
516
+ };
517
+ }
518
+ };
519
+ return task;
520
+ }
521
+ async runPlans(title, plans) {
522
+ const taskExecutor = new external_index_js_namespaceObject.Executor(title, {
523
+ onTaskStart: this.onTaskStartCallback
524
+ });
525
+ const { tasks } = await this.convertPlanToExecutable(plans);
526
+ await taskExecutor.append(tasks);
527
+ const result = await taskExecutor.flush();
528
+ const { output } = result;
529
+ return {
530
+ output,
531
+ executor: taskExecutor
532
+ };
533
+ }
534
+ async action(userPrompt, actionContext) {
535
+ const taskExecutor = new external_index_js_namespaceObject.Executor((0, external_ui_utils_js_namespaceObject.taskTitleStr)('Action', userPrompt), {
536
+ onTaskStart: this.onTaskStartCallback
537
+ });
538
+ let planningTask = this.planningTaskFromPrompt(userPrompt, void 0, actionContext);
539
+ let replanCount = 0;
540
+ const logList = [];
541
+ const yamlFlow = [];
542
+ const replanningCycleLimit = (0, env_namespaceObject.getAIConfigInNumber)(env_namespaceObject.MIDSCENE_REPLANNING_CYCLE_LIMIT) || defaultReplanningCycleLimit;
543
+ while(planningTask){
544
+ if (replanCount > replanningCycleLimit) {
545
+ const errorMsg = 'Replanning too many times, please split the task into multiple steps';
546
+ return this.appendErrorPlan(taskExecutor, errorMsg);
547
+ }
548
+ await taskExecutor.append(planningTask);
549
+ const result = await taskExecutor.flush();
550
+ const planResult = null == result ? void 0 : result.output;
551
+ if (taskExecutor.isInErrorState()) return {
552
+ output: planResult,
553
+ executor: taskExecutor
554
+ };
555
+ const plans = planResult.actions || [];
556
+ yamlFlow.push(...planResult.yamlFlow || []);
557
+ let executables;
558
+ try {
559
+ executables = await this.convertPlanToExecutable(plans);
560
+ taskExecutor.append(executables.tasks);
561
+ } catch (error) {
562
+ return this.appendErrorPlan(taskExecutor, `Error converting plans to executable tasks: ${error}, plans: ${JSON.stringify(plans)}`);
563
+ }
564
+ await taskExecutor.flush();
565
+ if (taskExecutor.isInErrorState()) return {
566
+ output: void 0,
567
+ executor: taskExecutor
568
+ };
569
+ if (null == planResult ? void 0 : planResult.log) logList.push(planResult.log);
570
+ if (!planResult.more_actions_needed_by_instruction) {
571
+ planningTask = null;
572
+ break;
573
+ }
574
+ planningTask = this.planningTaskFromPrompt(userPrompt, logList.length > 0 ? `- ${logList.join('\n- ')}` : void 0, actionContext);
575
+ replanCount++;
576
+ }
577
+ return {
578
+ output: {
579
+ yamlFlow
580
+ },
581
+ executor: taskExecutor
582
+ };
583
+ }
584
+ async actionToGoal(userPrompt) {
585
+ const taskExecutor = new external_index_js_namespaceObject.Executor((0, external_ui_utils_js_namespaceObject.taskTitleStr)('Action', userPrompt), {
586
+ onTaskStart: this.onTaskStartCallback
587
+ });
588
+ this.conversationHistory = [];
589
+ const isCompleted = false;
590
+ let currentActionCount = 0;
591
+ const maxActionNumber = 40;
592
+ const yamlFlow = [];
593
+ while(!isCompleted && currentActionCount < maxActionNumber){
594
+ currentActionCount++;
595
+ debug('actionToGoal, currentActionCount:', currentActionCount, 'userPrompt:', userPrompt);
596
+ const planningTask = this.planningTaskToGoal(userPrompt, {
597
+ intent: 'planning'
598
+ });
599
+ await taskExecutor.append(planningTask);
600
+ const result = await taskExecutor.flush();
601
+ if (taskExecutor.isInErrorState()) return {
602
+ output: void 0,
603
+ executor: taskExecutor
604
+ };
605
+ if (!result) throw new Error('result of taskExecutor.flush() is undefined in function actionToGoal');
606
+ const { output } = result;
607
+ const plans = output.actions;
608
+ yamlFlow.push(...output.yamlFlow || []);
609
+ let executables;
610
+ try {
611
+ executables = await this.convertPlanToExecutable(plans);
612
+ taskExecutor.append(executables.tasks);
613
+ } catch (error) {
614
+ return this.appendErrorPlan(taskExecutor, `Error converting plans to executable tasks: ${error}, plans: ${JSON.stringify(plans)}`);
615
+ }
616
+ await taskExecutor.flush();
617
+ if (taskExecutor.isInErrorState()) return {
618
+ output: void 0,
619
+ executor: taskExecutor
620
+ };
621
+ if ('Finished' === plans[0].type) break;
622
+ }
623
+ return {
624
+ output: {
625
+ yamlFlow
626
+ },
627
+ executor: taskExecutor
628
+ };
629
+ }
630
+ createTypeQueryTask(type, demand, opt, multimodalPrompt) {
631
+ const queryTask = {
632
+ type: 'Insight',
633
+ subType: type,
634
+ locate: null,
635
+ param: {
636
+ dataDemand: multimodalPrompt ? {
637
+ demand,
638
+ multimodalPrompt
639
+ } : demand
640
+ },
641
+ executor: async (param, taskContext)=>{
642
+ const { task } = taskContext;
643
+ let insightDump;
644
+ const dumpCollector = (dump)=>{
645
+ insightDump = dump;
646
+ };
647
+ this.insight.onceDumpUpdatedFn = dumpCollector;
648
+ const shotTime = Date.now();
649
+ const pageContext = await this.insight.contextRetrieverFn('extract');
650
+ task.pageContext = pageContext;
651
+ const recordItem = {
652
+ type: 'screenshot',
653
+ ts: shotTime,
654
+ screenshot: pageContext.screenshotBase64,
655
+ timing: 'before Extract'
656
+ };
657
+ task.recorder = [
658
+ recordItem
659
+ ];
660
+ const ifTypeRestricted = 'Query' !== type;
661
+ let demandInput = demand;
662
+ if (ifTypeRestricted) {
663
+ const returnType = 'Assert' === type ? 'Boolean' : type;
664
+ demandInput = {
665
+ result: `${returnType}, ${demand}`
666
+ };
667
+ }
668
+ const { data, usage, thought } = await this.insight.extract(demandInput, opt, multimodalPrompt);
669
+ let outputResult = data;
670
+ if (ifTypeRestricted) {
671
+ (0, utils_namespaceObject.assert)((null == data ? void 0 : data.result) !== void 0, 'No result in query data');
672
+ outputResult = data.result;
673
+ }
674
+ return {
675
+ output: outputResult,
676
+ log: {
677
+ dump: insightDump,
678
+ isWaitForAssert: null == opt ? void 0 : opt.isWaitForAssert
679
+ },
680
+ usage,
681
+ thought
682
+ };
683
+ }
684
+ };
685
+ return queryTask;
686
+ }
687
+ async createTypeQueryExecution(type, demand, opt, multimodalPrompt) {
688
+ const taskExecutor = new external_index_js_namespaceObject.Executor((0, external_ui_utils_js_namespaceObject.taskTitleStr)(type, 'string' == typeof demand ? demand : JSON.stringify(demand)), {
689
+ onTaskStart: this.onTaskStartCallback
690
+ });
691
+ const queryTask = await this.createTypeQueryTask(type, demand, opt, multimodalPrompt);
692
+ await taskExecutor.append(this.prependExecutorWithScreenshot(queryTask));
693
+ const result = await taskExecutor.flush();
694
+ if (!result) throw new Error('result of taskExecutor.flush() is undefined in function createTypeQueryTask');
695
+ const { output, thought } = result;
696
+ return {
697
+ output,
698
+ thought,
699
+ executor: taskExecutor
700
+ };
701
+ }
702
+ async assert(assertion, opt) {
703
+ const { textPrompt, multimodalPrompt } = (0, external_utils_js_namespaceObject_1.parsePrompt)(assertion);
704
+ return await this.createTypeQueryExecution('Assert', textPrompt, opt, multimodalPrompt);
705
+ }
706
+ appendConversationHistory(conversationHistory) {
707
+ if ('user' === conversationHistory.role) {
708
+ const userImgItems = this.conversationHistory.filter((item)=>'user' === item.role);
709
+ if (userImgItems.length >= 4 && 'user' === conversationHistory.role) {
710
+ const firstUserImgIndex = this.conversationHistory.findIndex((item)=>'user' === item.role);
711
+ if (firstUserImgIndex >= 0) this.conversationHistory.splice(firstUserImgIndex, 1);
712
+ }
713
+ }
714
+ this.conversationHistory.push(conversationHistory);
715
+ }
716
+ async appendErrorPlan(taskExecutor, errorMsg) {
717
+ const errorPlan = {
718
+ type: 'Error',
719
+ param: {
720
+ thought: errorMsg
721
+ },
722
+ locate: null
723
+ };
724
+ const { tasks } = await this.convertPlanToExecutable([
725
+ errorPlan
726
+ ]);
727
+ await taskExecutor.append(this.prependExecutorWithScreenshot(tasks[0]));
728
+ await taskExecutor.flush();
729
+ return {
730
+ output: void 0,
731
+ executor: taskExecutor
732
+ };
733
+ }
734
+ async waitFor(assertion, opt) {
735
+ const { textPrompt, multimodalPrompt } = (0, external_utils_js_namespaceObject_1.parsePrompt)(assertion);
736
+ const description = `waitFor: ${textPrompt}`;
737
+ const taskExecutor = new external_index_js_namespaceObject.Executor((0, external_ui_utils_js_namespaceObject.taskTitleStr)('WaitFor', description), {
738
+ onTaskStart: this.onTaskStartCallback
739
+ });
740
+ const { timeoutMs, checkIntervalMs } = opt;
741
+ (0, utils_namespaceObject.assert)(assertion, 'No assertion for waitFor');
742
+ (0, utils_namespaceObject.assert)(timeoutMs, 'No timeoutMs for waitFor');
743
+ (0, utils_namespaceObject.assert)(checkIntervalMs, 'No checkIntervalMs for waitFor');
744
+ (0, utils_namespaceObject.assert)(checkIntervalMs <= timeoutMs, `wrong config for waitFor: checkIntervalMs must be less than timeoutMs, config: {checkIntervalMs: ${checkIntervalMs}, timeoutMs: ${timeoutMs}}`);
745
+ const overallStartTime = Date.now();
746
+ let startTime = Date.now();
747
+ let errorThought = '';
748
+ while(Date.now() - overallStartTime < timeoutMs){
749
+ startTime = Date.now();
750
+ const queryTask = await this.createTypeQueryTask('Assert', textPrompt, {
751
+ isWaitForAssert: true,
752
+ returnThought: true,
753
+ doNotThrowError: true
754
+ }, multimodalPrompt);
755
+ await taskExecutor.append(this.prependExecutorWithScreenshot(queryTask));
756
+ const result = await taskExecutor.flush();
757
+ if (!result) throw new Error('result of taskExecutor.flush() is undefined in function waitFor');
758
+ if (null == result ? void 0 : result.output) return {
759
+ output: void 0,
760
+ executor: taskExecutor
761
+ };
762
+ errorThought = (null == result ? void 0 : result.thought) || `unknown error when waiting for assertion: ${textPrompt}`;
763
+ const now = Date.now();
764
+ if (now - startTime < checkIntervalMs) {
765
+ const timeRemaining = checkIntervalMs - (now - startTime);
766
+ const sleepPlan = {
767
+ type: 'Sleep',
768
+ param: {
769
+ timeMs: timeRemaining
770
+ },
771
+ locate: null
772
+ };
773
+ const { tasks: sleepTasks } = await this.convertPlanToExecutable([
774
+ sleepPlan
775
+ ]);
776
+ await taskExecutor.append(this.prependExecutorWithScreenshot(sleepTasks[0]));
777
+ await taskExecutor.flush();
778
+ }
779
+ }
780
+ return this.appendErrorPlan(taskExecutor, `waitFor timeout: ${errorThought}`);
781
+ }
782
+ constructor(page, insight, opts){
783
+ _define_property(this, "page", void 0);
784
+ _define_property(this, "insight", void 0);
785
+ _define_property(this, "taskCache", void 0);
786
+ _define_property(this, "conversationHistory", []);
787
+ _define_property(this, "onTaskStartCallback", void 0);
788
+ this.page = page;
789
+ this.insight = insight;
790
+ this.taskCache = opts.taskCache;
791
+ this.onTaskStartCallback = null == opts ? void 0 : opts.onTaskStart;
792
+ }
793
+ }
794
+ exports.PageTaskExecutor = __webpack_exports__.PageTaskExecutor;
795
+ exports.locatePlanForLocate = __webpack_exports__.locatePlanForLocate;
796
+ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
797
+ "PageTaskExecutor",
798
+ "locatePlanForLocate"
799
+ ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
800
+ Object.defineProperty(exports, '__esModule', {
801
+ value: true
802
+ });
803
+
804
+ //# sourceMappingURL=tasks.js.map