@midscene/core 1.16.0 → 1.16.2

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 (147) hide show
  1. package/dist/es/agent/agent-options.mjs +36 -0
  2. package/dist/es/agent/agent-options.mjs.map +1 -0
  3. package/dist/es/agent/agent-report-manager.mjs +323 -0
  4. package/dist/es/agent/agent-report-manager.mjs.map +1 -0
  5. package/dist/es/agent/agent.mjs +112 -228
  6. package/dist/es/agent/agent.mjs.map +1 -1
  7. package/dist/es/agent/cache-config.mjs +21 -1
  8. package/dist/es/agent/cache-config.mjs.map +1 -1
  9. package/dist/es/agent/tasks.mjs +3 -1
  10. package/dist/es/agent/tasks.mjs.map +1 -1
  11. package/dist/es/agent/utils.mjs +4 -4
  12. package/dist/es/agent/utils.mjs.map +1 -1
  13. package/dist/es/ai-model/models/auto-glm/parser.mjs +1 -1
  14. package/dist/es/ai-model/models/auto-glm/parser.mjs.map +1 -1
  15. package/dist/es/ai-model/models/kimi.mjs +1 -1
  16. package/dist/es/ai-model/models/kimi.mjs.map +1 -1
  17. package/dist/es/ai-model/service-caller/call-ai.mjs +10 -1
  18. package/dist/es/ai-model/service-caller/call-ai.mjs.map +1 -1
  19. package/dist/es/ai-model/service-caller/openai/call-openai.mjs +7 -2
  20. package/dist/es/ai-model/service-caller/openai/call-openai.mjs.map +1 -1
  21. package/dist/es/ai-model/shared/model-locate-result/errors.mjs +1 -1
  22. package/dist/es/ai-model/shared/model-locate-result/errors.mjs.map +1 -1
  23. package/dist/es/ai-model/shared/model-locate-result/parse.mjs +6 -2
  24. package/dist/es/ai-model/shared/model-locate-result/parse.mjs.map +1 -1
  25. package/dist/es/device/index.mjs +9 -8
  26. package/dist/es/device/index.mjs.map +1 -1
  27. package/dist/es/report-generator.mjs +76 -36
  28. package/dist/es/report-generator.mjs.map +1 -1
  29. package/dist/es/report-html-template.mjs +1 -1
  30. package/dist/es/test-run-report.mjs.map +1 -1
  31. package/dist/es/test-runner/engine/document-runtime.mjs +30 -24
  32. package/dist/es/test-runner/engine/document-runtime.mjs.map +1 -1
  33. package/dist/es/test-runner/engine/project-runtime.mjs +17 -11
  34. package/dist/es/test-runner/engine/project-runtime.mjs.map +1 -1
  35. package/dist/es/test-runner/engine/resource-operations.mjs +33 -8
  36. package/dist/es/test-runner/engine/resource-operations.mjs.map +1 -1
  37. package/dist/es/test-runner/engine/run-collected-case.mjs +1 -0
  38. package/dist/es/test-runner/engine/run-collected-case.mjs.map +1 -1
  39. package/dist/es/test-runner/engine/run-workflow-document.mjs +3 -0
  40. package/dist/es/test-runner/engine/run-workflow-document.mjs.map +1 -1
  41. package/dist/es/test-runner/engine/setup-timeout.mjs +37 -0
  42. package/dist/es/test-runner/engine/setup-timeout.mjs.map +1 -0
  43. package/dist/es/test-runner/reporting/merge-report.mjs +3 -1
  44. package/dist/es/test-runner/reporting/merge-report.mjs.map +1 -1
  45. package/dist/es/test-runner/reporting/metrics.mjs +39 -2
  46. package/dist/es/test-runner/reporting/metrics.mjs.map +1 -1
  47. package/dist/es/utils.mjs +1 -1
  48. package/dist/es/yaml/execution-session.mjs +2 -1
  49. package/dist/es/yaml/execution-session.mjs.map +1 -1
  50. package/dist/es/yaml/legacy-yaml-report.mjs +1 -1
  51. package/dist/es/yaml/legacy-yaml-report.mjs.map +1 -1
  52. package/dist/es/yaml/player.mjs +17 -3
  53. package/dist/es/yaml/player.mjs.map +1 -1
  54. package/dist/lib/agent/agent-options.js +73 -0
  55. package/dist/lib/agent/agent-options.js.map +1 -0
  56. package/dist/lib/agent/agent-report-manager.js +357 -0
  57. package/dist/lib/agent/agent-report-manager.js.map +1 -0
  58. package/dist/lib/agent/agent.js +110 -226
  59. package/dist/lib/agent/agent.js.map +1 -1
  60. package/dist/lib/agent/cache-config.js +23 -0
  61. package/dist/lib/agent/cache-config.js.map +1 -1
  62. package/dist/lib/agent/tasks.js +3 -1
  63. package/dist/lib/agent/tasks.js.map +1 -1
  64. package/dist/lib/agent/utils.js +2 -2
  65. package/dist/lib/agent/utils.js.map +1 -1
  66. package/dist/lib/ai-model/models/auto-glm/parser.js +1 -1
  67. package/dist/lib/ai-model/models/auto-glm/parser.js.map +1 -1
  68. package/dist/lib/ai-model/models/kimi.js +1 -1
  69. package/dist/lib/ai-model/models/kimi.js.map +1 -1
  70. package/dist/lib/ai-model/service-caller/call-ai.js +10 -1
  71. package/dist/lib/ai-model/service-caller/call-ai.js.map +1 -1
  72. package/dist/lib/ai-model/service-caller/openai/call-openai.js +7 -2
  73. package/dist/lib/ai-model/service-caller/openai/call-openai.js.map +1 -1
  74. package/dist/lib/ai-model/shared/model-locate-result/errors.js +1 -1
  75. package/dist/lib/ai-model/shared/model-locate-result/errors.js.map +1 -1
  76. package/dist/lib/ai-model/shared/model-locate-result/parse.js +6 -2
  77. package/dist/lib/ai-model/shared/model-locate-result/parse.js.map +1 -1
  78. package/dist/lib/device/index.js +9 -8
  79. package/dist/lib/device/index.js.map +1 -1
  80. package/dist/lib/report-generator.js +75 -35
  81. package/dist/lib/report-generator.js.map +1 -1
  82. package/dist/lib/report-html-template.js +1 -1
  83. package/dist/lib/test-run-report.js.map +1 -1
  84. package/dist/lib/test-runner/engine/document-runtime.js +30 -24
  85. package/dist/lib/test-runner/engine/document-runtime.js.map +1 -1
  86. package/dist/lib/test-runner/engine/project-runtime.js +17 -11
  87. package/dist/lib/test-runner/engine/project-runtime.js.map +1 -1
  88. package/dist/lib/test-runner/engine/resource-operations.js +36 -8
  89. package/dist/lib/test-runner/engine/resource-operations.js.map +1 -1
  90. package/dist/lib/test-runner/engine/run-collected-case.js +1 -0
  91. package/dist/lib/test-runner/engine/run-collected-case.js.map +1 -1
  92. package/dist/lib/test-runner/engine/run-workflow-document.js +3 -0
  93. package/dist/lib/test-runner/engine/run-workflow-document.js.map +1 -1
  94. package/dist/lib/test-runner/engine/setup-timeout.js +71 -0
  95. package/dist/lib/test-runner/engine/setup-timeout.js.map +1 -0
  96. package/dist/lib/test-runner/reporting/merge-report.js +3 -1
  97. package/dist/lib/test-runner/reporting/merge-report.js.map +1 -1
  98. package/dist/lib/test-runner/reporting/metrics.js +39 -2
  99. package/dist/lib/test-runner/reporting/metrics.js.map +1 -1
  100. package/dist/lib/utils.js +1 -1
  101. package/dist/lib/yaml/execution-session.js +4 -0
  102. package/dist/lib/yaml/execution-session.js.map +1 -1
  103. package/dist/lib/yaml/legacy-yaml-report.js +1 -1
  104. package/dist/lib/yaml/legacy-yaml-report.js.map +1 -1
  105. package/dist/lib/yaml/player.js +16 -2
  106. package/dist/lib/yaml/player.js.map +1 -1
  107. package/dist/types/agent/agent-options.d.ts +4 -0
  108. package/dist/types/agent/agent-options.d.ts.map +1 -0
  109. package/dist/types/agent/agent-report-manager.d.ts +92 -0
  110. package/dist/types/agent/agent-report-manager.d.ts.map +1 -0
  111. package/dist/types/agent/agent.d.ts +31 -24
  112. package/dist/types/agent/agent.d.ts.map +1 -1
  113. package/dist/types/agent/cache-config.d.ts +10 -0
  114. package/dist/types/agent/cache-config.d.ts.map +1 -1
  115. package/dist/types/agent/tasks.d.ts +1 -0
  116. package/dist/types/agent/tasks.d.ts.map +1 -1
  117. package/dist/types/ai-model/models/auto-glm/parser.d.ts.map +1 -1
  118. package/dist/types/ai-model/service-caller/openai/call-openai.d.ts.map +1 -1
  119. package/dist/types/ai-model/shared/model-locate-result/errors.d.ts +1 -1
  120. package/dist/types/ai-model/shared/model-locate-result/errors.d.ts.map +1 -1
  121. package/dist/types/ai-model/shared/model-locate-result/parse.d.ts.map +1 -1
  122. package/dist/types/device/index.d.ts +7 -7
  123. package/dist/types/device/index.d.ts.map +1 -1
  124. package/dist/types/report-generator.d.ts +5 -1
  125. package/dist/types/report-generator.d.ts.map +1 -1
  126. package/dist/types/test-run-report.d.ts +4 -1
  127. package/dist/types/test-run-report.d.ts.map +1 -1
  128. package/dist/types/test-runner/engine/document-runtime.d.ts.map +1 -1
  129. package/dist/types/test-runner/engine/project-runtime.d.ts.map +1 -1
  130. package/dist/types/test-runner/engine/resource-operations.d.ts +5 -0
  131. package/dist/types/test-runner/engine/resource-operations.d.ts.map +1 -1
  132. package/dist/types/test-runner/engine/run-collected-case.d.ts.map +1 -1
  133. package/dist/types/test-runner/engine/run-workflow-document.d.ts.map +1 -1
  134. package/dist/types/test-runner/engine/setup-timeout.d.ts +3 -0
  135. package/dist/types/test-runner/engine/setup-timeout.d.ts.map +1 -0
  136. package/dist/types/test-runner/engine/types.d.ts +7 -0
  137. package/dist/types/test-runner/engine/types.d.ts.map +1 -1
  138. package/dist/types/test-runner/parser/types.d.ts +5 -0
  139. package/dist/types/test-runner/parser/types.d.ts.map +1 -1
  140. package/dist/types/test-runner/project.d.ts +22 -0
  141. package/dist/types/test-runner/project.d.ts.map +1 -1
  142. package/dist/types/test-runner/reporting/merge-report.d.ts.map +1 -1
  143. package/dist/types/test-runner/reporting/metrics.d.ts.map +1 -1
  144. package/dist/types/yaml/execution-session.d.ts +2 -0
  145. package/dist/types/yaml/execution-session.d.ts.map +1 -1
  146. package/dist/types/yaml/player.d.ts.map +1 -1
  147. package/package.json +2 -2
@@ -38,20 +38,14 @@ __webpack_require__.d(__webpack_exports__, {
38
38
  });
39
39
  const task_routing_js_namespaceObject = require("../ai-model/models/task-routing.js");
40
40
  const index_js_namespaceObject = require("../ai-model/service-caller/index.js");
41
- const external_constants_js_namespaceObject = require("../constants.js");
42
41
  const external_js_yaml_namespaceObject = require("js-yaml");
43
42
  var external_js_yaml_default = /*#__PURE__*/ __webpack_require__.n(external_js_yaml_namespaceObject);
44
- const html_utils_js_namespaceObject = require("../dump/html-utils.js");
45
43
  const external_screenshot_item_js_namespaceObject = require("../screenshot-item.js");
46
44
  const external_service_index_js_namespaceObject = require("../service/index.js");
47
45
  var external_service_index_js_default = /*#__PURE__*/ __webpack_require__.n(external_service_index_js_namespaceObject);
48
46
  const resource_operations_js_namespaceObject = require("../test-runner/engine/resource-operations.js");
49
- const agent_report_js_namespaceObject = require("../test-runner/reporting/agent-report.js");
50
- const execution_record_js_namespaceObject = require("../test-runner/reporting/execution-record.js");
51
47
  const external_types_js_namespaceObject = require("../types.js");
52
48
  const execution_session_js_namespaceObject = require("../yaml/execution-session.js");
53
- const external_report_generator_js_namespaceObject = require("../report-generator.js");
54
- const external_utils_js_namespaceObject = require("../utils.js");
55
49
  const external_yaml_index_js_namespaceObject = require("../yaml/index.js");
56
50
  const promises_namespaceObject = require("node:fs/promises");
57
51
  const external_node_path_namespaceObject = require("node:path");
@@ -63,6 +57,8 @@ const logger_namespaceObject = require("@midscene/shared/logger");
63
57
  const utils_namespaceObject = require("@midscene/shared/utils");
64
58
  const external_device_index_js_namespaceObject = require("../device/index.js");
65
59
  const external_action_readiness_js_namespaceObject = require("./action-readiness.js");
60
+ const external_agent_options_js_namespaceObject = require("./agent-options.js");
61
+ const external_agent_report_manager_js_namespaceObject = require("./agent-report-manager.js");
66
62
  const external_cache_config_js_namespaceObject = require("./cache-config.js");
67
63
  const external_file_chooser_js_namespaceObject = require("./file-chooser.js");
68
64
  const external_insight_js_namespaceObject = require("./insight.js");
@@ -77,7 +73,7 @@ const external_tasks_js_namespaceObject = require("./tasks.js");
77
73
  const external_test_runner_nodes_js_namespaceObject = require("./test-runner-nodes.js");
78
74
  const external_ui_observer_js_namespaceObject = require("./ui-observer.js");
79
75
  const external_ui_utils_js_namespaceObject = require("./ui-utils.js");
80
- const external_utils_js_namespaceObject_1 = require("./utils.js");
76
+ const external_utils_js_namespaceObject = require("./utils.js");
81
77
  function _define_property(obj, key, value) {
82
78
  if (key in obj) Object.defineProperty(obj, key, {
83
79
  value: value,
@@ -107,66 +103,38 @@ class Agent {
107
103
  static getTestRunnerNodeDefinitions() {
108
104
  return external_test_runner_nodes_js_namespaceObject.commonAgentTestRunnerNodeDefinitions;
109
105
  }
106
+ get dump() {
107
+ return this.reportManager.dump;
108
+ }
109
+ set dump(value) {
110
+ this.reportManager.dump = value;
111
+ }
112
+ get reportFile() {
113
+ return this.reportManager.reportFile;
114
+ }
115
+ set reportFile(value) {
116
+ this.reportManager.reportFile = value;
117
+ }
118
+ get reportFileName() {
119
+ return this.reportManager.reportFileName;
120
+ }
121
+ set reportFileName(value) {
122
+ this.reportManager.reportFileName = value;
123
+ }
110
124
  _prepareForTestRunner() {
111
- this.reportGenerator.enableSourceSnapshots?.();
125
+ this.reportManager._prepareForTestRunner();
112
126
  }
113
127
  async _createReportSource(scopeId, executionIds) {
114
- return this.reportGenerator.createSourceSnapshot?.(scopeId, executionIds);
128
+ return this.reportManager._createReportSource(scopeId, executionIds);
115
129
  }
116
130
  async _writeYamlExecutionReport(record) {
117
- const existingIndex = this.yamlExecutionRecords.findIndex((entry)=>entry.runId === record.runId);
118
- const recordIndex = existingIndex < 0 ? this.yamlExecutionRecords.length : existingIndex;
119
- this.yamlExecutionRecords[recordIndex] = record;
120
- try {
121
- const path = await this.reportGenerator.writeRunnerReport?.(this.buildYamlReportInput(), this.yamlReportScopeId, this.getReportMeta());
122
- this.reportFile = path ?? this.reportFile;
123
- return path;
124
- } catch (error) {
125
- this.yamlExecutionRecords[recordIndex] = Object.freeze({
126
- ...record,
127
- status: 'failed',
128
- reportError: error
129
- });
130
- throw error;
131
- }
132
- }
133
- buildYamlReportInput() {
134
- const scopedRecords = this.yamlExecutionRecords.map((entry)=>({
135
- ...entry,
136
- ...entry.execution ? {
137
- execution: {
138
- document: {
139
- ...entry.execution.document,
140
- reportScopeId: this.yamlReportScopeId
141
- },
142
- cases: entry.execution.cases.map((outcome)=>({
143
- ...outcome,
144
- ...outcome.run ? {
145
- run: {
146
- ...outcome.run,
147
- reportScopeId: this.yamlReportScopeId
148
- }
149
- } : {},
150
- ...outcome.attempts ? {
151
- attempts: outcome.attempts.map((attempt)=>({
152
- ...attempt,
153
- reportScopeId: this.yamlReportScopeId
154
- }))
155
- } : {}
156
- }))
157
- }
158
- } : {}
159
- }));
160
- return (0, execution_record_js_namespaceObject.executionRecordsToReportInput)(scopedRecords, {
161
- runId: this.yamlReportScopeId
162
- });
131
+ return this.reportManager._writeYamlExecutionReport(record);
163
132
  }
164
133
  get onDumpUpdate() {
165
- return this.dumpUpdateListeners[0];
134
+ return this.reportManager.onDumpUpdate;
166
135
  }
167
136
  set onDumpUpdate(callback) {
168
- this.dumpUpdateListeners = [];
169
- if (callback) this.dumpUpdateListeners.push(callback);
137
+ this.reportManager.onDumpUpdate = callback;
170
138
  }
171
139
  get aiContexts() {
172
140
  if (!this.opts.aiContexts) this.opts.aiContexts = {};
@@ -211,7 +179,9 @@ class Agent {
211
179
  };
212
180
  }
213
181
  createInsight(getUIContext) {
214
- return new external_insight_js_namespaceObject.Insight(this.taskExecutor, (task)=>this.resolveModelRuntime('insight', task), (apiName, callContext)=>this.resolveUserContext(apiName, callContext), getUIContext);
182
+ return new external_insight_js_namespaceObject.Insight({
183
+ createTypeQueryExecution: (...args)=>this.withReportOperation(()=>this.taskExecutor.createTypeQueryExecution(...args))
184
+ }, (task)=>this.resolveModelRuntime('insight', task), (apiName, callContext)=>this.resolveUserContext(apiName, callContext), getUIContext);
215
185
  }
216
186
  async getActionSpace() {
217
187
  return this.fullActionSpace;
@@ -227,7 +197,7 @@ class Agent {
227
197
  }
228
198
  const maxRetries = Agent.CONTEXT_RETRY_MAX;
229
199
  for(let attempt = 0;; attempt++)try {
230
- return await (0, external_utils_js_namespaceObject_1.commonContextParser)(this.interface, {
200
+ return await (0, external_utils_js_namespaceObject.commonContextParser)(this.interface, {
231
201
  uploadServerUrl: this.modelConfigManager.getUploadTestServerUrl(),
232
202
  screenshotShrinkFactor: this.opts.screenshotShrinkFactor
233
203
  });
@@ -244,6 +214,7 @@ class Agent {
244
214
  return await this.getUIContext('locate');
245
215
  }
246
216
  async startObserving(opt) {
217
+ this.assertReportWritable();
247
218
  (0, utils_namespaceObject.assert)(!this.frozenUIContext, 'startObserving() cannot be used while the UI context is frozen (call unfreezePageContext() first)');
248
219
  (0, utils_namespaceObject.assert)(!this.activeObserver, "An observation window is already active on this agent. Stop the existing observer first (await observer.stop()) before starting a new one.");
249
220
  const observer = new external_ui_observer_js_namespaceObject.UIObserverImpl({
@@ -291,31 +262,20 @@ class Agent {
291
262
  this.opts.aiActionContext = context;
292
263
  }
293
264
  }
294
- resetDump() {
295
- this.dump = new external_types_js_namespaceObject.ReportActionDump({
296
- sdkVersion: (0, external_utils_js_namespaceObject.getVersion)(),
297
- groupName: this.opts.groupName,
298
- groupDescription: this.opts.groupDescription,
299
- executions: [],
300
- modelBriefs: [],
301
- deviceType: this.interface.interfaceType
302
- });
303
- this.executionDumpIndexByRunner = new WeakMap();
304
- return this.dump;
265
+ assertReportWritable() {
266
+ this.reportManager.assertReportWritable();
267
+ }
268
+ async withReportOperation(operation) {
269
+ return this.reportManager.withReportOperation(operation);
270
+ }
271
+ async resetDump() {
272
+ return this.reportManager.resetDump();
273
+ }
274
+ async finalizeReport() {
275
+ return this.reportManager.finalizeReport();
305
276
  }
306
277
  appendExecutionDump(execution, runner) {
307
- const currentDump = this.dump;
308
- if (runner) {
309
- const existingIndex = this.executionDumpIndexByRunner.get(runner);
310
- if (void 0 !== existingIndex) {
311
- currentDump.executions[existingIndex] = execution;
312
- return;
313
- }
314
- currentDump.executions.push(execution);
315
- this.executionDumpIndexByRunner.set(runner, currentDump.executions.length - 1);
316
- return;
317
- }
318
- currentDump.executions.push(execution);
278
+ this.reportManager.appendExecutionDump(execution, runner);
319
279
  }
320
280
  collectUsageMetrics(execution) {
321
281
  for (const task of execution.tasks){
@@ -340,50 +300,16 @@ class Agent {
340
300
  return this.metricsCollector.snapshot();
341
301
  }
342
302
  dumpDataString(opt) {
343
- this.dump.groupName = this.opts.groupName;
344
- this.dump.groupDescription = this.opts.groupDescription;
345
- if (utils_namespaceObject.ifInBrowser || opt?.inlineScreenshots) return this.dump.serializeWithInlineScreenshots();
346
- return this.dump.serialize();
303
+ return this.reportManager.dumpDataString(opt);
347
304
  }
348
305
  reportHTMLString(opt) {
349
- if (external_constants_js_namespaceObject.IS_REPORT_BUILD) return '';
350
- const dumpString = this.dumpDataString(opt);
351
- if (!this.yamlExecutionRecords.length) return (0, external_utils_js_namespaceObject.reportHTMLContent)(dumpString);
352
- const reportId = this.yamlReportScopeId;
353
- const runnerDump = (0, agent_report_js_namespaceObject.buildAgentTestRunReportDump)(this.buildYamlReportInput(), this.dump, {
354
- reportId,
355
- scopeId: this.yamlReportScopeId,
356
- sourcePath: this.reportFile ?? '<inline-agent-report>'
357
- });
358
- return `${(0, external_utils_js_namespaceObject.reportHTMLContent)({
359
- dumpString,
360
- attributes: {
361
- 'data-group-id': reportId,
362
- 'data-report-id': reportId
363
- }
364
- })}\n${(0, html_utils_js_namespaceObject.generateTestRunReportScriptTag)(runnerDump)}`;
306
+ return this.reportManager.reportHTMLString(()=>this.dumpDataString(opt));
365
307
  }
366
308
  writeOutActionDumps(executionDump) {
367
- const exec = executionDump || this.lastExecutionDump;
368
- if (exec) {
369
- this.lastExecutionDump = exec;
370
- this.reportGenerator.onExecutionUpdate(exec, this.getReportMeta(), this.opts.reportAttributes);
371
- }
372
- this.reportFile = this.reportGenerator.getReportPath();
309
+ this.reportManager.writeOutActionDumps(executionDump);
373
310
  }
374
311
  async flushReport() {
375
- this.writeOutActionDumps();
376
- await this.reportGenerator.flush();
377
- return this.lastExecutionDump ? this.reportFile ?? void 0 : void 0;
378
- }
379
- getReportMeta() {
380
- return {
381
- groupName: this.dump.groupName,
382
- groupDescription: this.dump.groupDescription,
383
- sdkVersion: this.dump.sdkVersion,
384
- modelBriefs: this.dump.modelBriefs,
385
- deviceType: this.dump.deviceType
386
- };
312
+ return this.reportManager.flushReport();
387
313
  }
388
314
  async callbackOnTaskStartTip(task) {
389
315
  const param = (0, external_ui_utils_js_namespaceObject.paramStr)(task);
@@ -394,6 +320,9 @@ class Agent {
394
320
  return async (param)=>await this.callActionInActionSpace(name, param);
395
321
  }
396
322
  async callActionInActionSpace(type, opt, abortSignal) {
323
+ return this.withReportOperation(()=>this.executeActionInActionSpace(type, opt, abortSignal));
324
+ }
325
+ async executeActionInActionSpace(type, opt, abortSignal) {
397
326
  debug('callActionInActionSpace', type, ',', opt);
398
327
  const clonedActionParam = opt && 'object' == typeof opt && !Array.isArray(opt) ? {
399
328
  ...opt
@@ -416,12 +345,14 @@ class Agent {
416
345
  return output;
417
346
  }
418
347
  async aiTap(locatePrompt, opt) {
419
- (0, utils_namespaceObject.assert)(locatePrompt, 'missing locate prompt for tap');
420
- const detailedLocateParam = (0, external_yaml_index_js_namespaceObject.buildDetailedLocateParam)(locatePrompt, this.withContext('aiTap', opt));
421
- const fileChooserAccept = opt?.fileChooserAccept ? this.normalizeFileInput(opt.fileChooserAccept) : void 0;
422
- await (0, external_tasks_js_namespaceObject.withFileChooser)(this.interface, fileChooserAccept, async ()=>{
423
- await this.callActionInActionSpace('Tap', {
424
- locate: detailedLocateParam
348
+ await this.withReportOperation(async ()=>{
349
+ (0, utils_namespaceObject.assert)(locatePrompt, 'missing locate prompt for tap');
350
+ const detailedLocateParam = (0, external_yaml_index_js_namespaceObject.buildDetailedLocateParam)(locatePrompt, this.withContext('aiTap', opt));
351
+ const fileChooserAccept = opt?.fileChooserAccept ? this.normalizeFileInput(opt.fileChooserAccept) : void 0;
352
+ await (0, external_tasks_js_namespaceObject.withFileChooser)(this.interface, fileChooserAccept, async ()=>{
353
+ await this.callActionInActionSpace('Tap', {
354
+ locate: detailedLocateParam
355
+ });
425
356
  });
426
357
  });
427
358
  }
@@ -517,7 +448,7 @@ class Agent {
517
448
  };
518
449
  }
519
450
  if (opt) {
520
- const normalizedScrollType = (0, external_utils_js_namespaceObject_1.normalizeScrollType)(opt.scrollType);
451
+ const normalizedScrollType = (0, external_utils_js_namespaceObject.normalizeScrollType)(opt.scrollType);
521
452
  if (normalizedScrollType !== opt.scrollType) opt = {
522
453
  ...opt || {},
523
454
  scrollType: normalizedScrollType
@@ -552,6 +483,9 @@ class Agent {
552
483
  });
553
484
  }
554
485
  async aiAct(taskPrompt, opt) {
486
+ return this.withReportOperation(()=>this.executeAiAct(taskPrompt, opt));
487
+ }
488
+ async executeAiAct(taskPrompt, opt) {
555
489
  const internalOptions = opt;
556
490
  const internalReportDisplay = internalOptions?._internalReportDisplay;
557
491
  const taskPromptText = 'string' == typeof taskPrompt ? taskPrompt : taskPrompt.prompt;
@@ -659,6 +593,9 @@ class Agent {
659
593
  return result;
660
594
  }
661
595
  async runMarkdown(markdownPath, opt) {
596
+ return this.withReportOperation(()=>this.executeMarkdown(markdownPath, opt));
597
+ }
598
+ async executeMarkdown(markdownPath, opt) {
662
599
  const markdown = await (0, promises_namespaceObject.readFile)(markdownPath, 'utf-8');
663
600
  const { prompt } = await (0, external_run_markdown_js_namespaceObject.markdownToAiActPrompt)(markdown, markdownPath);
664
601
  return this.aiAct(prompt, {
@@ -670,7 +607,7 @@ class Agent {
670
607
  });
671
608
  }
672
609
  async runGherkinScenario(scenarioText, opt) {
673
- return (0, external_run_gherkin_scenario_js_namespaceObject.runGherkinScenario)(this, scenarioText, opt);
610
+ return this.withReportOperation(()=>(0, external_run_gherkin_scenario_js_namespaceObject.runGherkinScenario)(this, scenarioText, opt));
674
611
  }
675
612
  async aiAction(taskPrompt, opt) {
676
613
  return this.aiAct(taskPrompt, opt);
@@ -691,6 +628,9 @@ class Agent {
691
628
  return this.createInsight().aiAsk(prompt, opt);
692
629
  }
693
630
  async aiLocate(prompt, opt) {
631
+ return this.withReportOperation(()=>this.executeLocate(prompt, opt));
632
+ }
633
+ async executeLocate(prompt, opt) {
694
634
  const locateParam = (0, external_yaml_index_js_namespaceObject.buildDetailedLocateParam)(prompt, this.withContext('aiLocate', opt));
695
635
  (0, utils_namespaceObject.assert)(locateParam, 'cannot get locate param for aiLocate');
696
636
  const locatePlan = (0, external_tasks_js_namespaceObject.locatePlanForLocate)(locateParam);
@@ -720,16 +660,19 @@ class Agent {
720
660
  async aiWaitFor(assertion, opt) {
721
661
  const modelRuntime = this.resolveModelRuntime('insight', 'boolean');
722
662
  const options = this.withContext('aiWaitFor', opt);
723
- await this.taskExecutor.waitFor(assertion, {
724
- ...options,
725
- timeoutMs: options?.timeoutMs || 15000,
726
- checkIntervalMs: options?.checkIntervalMs || 3000
727
- }, modelRuntime);
663
+ await this.withReportOperation(()=>this.taskExecutor.waitFor(assertion, {
664
+ ...options,
665
+ timeoutMs: options?.timeoutMs || 15000,
666
+ checkIntervalMs: options?.checkIntervalMs || 3000
667
+ }, modelRuntime));
728
668
  }
729
669
  async ai(...args) {
730
670
  return this.aiAct(...args);
731
671
  }
732
672
  async runYaml(yamlScriptContent, options) {
673
+ return this.withReportOperation(()=>this.executeYaml(yamlScriptContent, options));
674
+ }
675
+ async executeYaml(yamlScriptContent, options) {
733
676
  if (this.destroyed) throw new Error('Cannot run YAML using a destroyed Agent.');
734
677
  const script = (0, external_yaml_index_js_namespaceObject.parseYamlScript)(yamlScriptContent, 'yaml');
735
678
  const player = new external_yaml_index_js_namespaceObject.ScriptPlayer(script, async ()=>({
@@ -749,20 +692,16 @@ class Agent {
749
692
  }
750
693
  async evaluateJavaScript(script) {
751
694
  (0, utils_namespaceObject.assert)(this.interface.evaluateJavaScript, 'evaluateJavaScript is not supported in current agent');
752
- return this.interface.evaluateJavaScript(script);
695
+ return this.withReportOperation(()=>this.interface.evaluateJavaScript(script));
753
696
  }
754
697
  addDumpUpdateListener(listener) {
755
- this.dumpUpdateListeners.push(listener);
756
- return ()=>{
757
- this.removeDumpUpdateListener(listener);
758
- };
698
+ return this.reportManager.addDumpUpdateListener(listener);
759
699
  }
760
700
  removeDumpUpdateListener(listener) {
761
- const index = this.dumpUpdateListeners.indexOf(listener);
762
- if (index > -1) this.dumpUpdateListeners.splice(index, 1);
701
+ this.reportManager.removeDumpUpdateListener(listener);
763
702
  }
764
703
  clearDumpUpdateListeners() {
765
- this.dumpUpdateListeners = [];
704
+ this.reportManager.clearDumpUpdateListeners();
766
705
  }
767
706
  addProgressListener(listener) {
768
707
  return this.progressBus.subscribe(listener);
@@ -774,17 +713,13 @@ class Agent {
774
713
  this.progressBus.clear();
775
714
  }
776
715
  notifyDumpUpdateListeners(executionDump) {
777
- const dumpString = this.dumpDataString();
778
- for (const listener of this.dumpUpdateListeners)try {
779
- listener(dumpString, executionDump);
780
- } catch (error) {
781
- console.error('Error in onDumpUpdate listener', error);
782
- }
716
+ this.reportManager.notifyDumpUpdateListeners(executionDump);
783
717
  }
784
718
  async destroy() {
785
719
  if (this.destroyed) return;
786
720
  this.destroyed = true;
787
721
  await (0, resource_operations_js_namespaceObject.waitForResourceIdle)(this);
722
+ await this.reportManager.waitForOperations();
788
723
  for (const observer of this.ownedObservers)try {
789
724
  await observer.dispose();
790
725
  } catch (error) {
@@ -798,17 +733,18 @@ class Agent {
798
733
  } catch (error) {
799
734
  interfaceDestroyError = error;
800
735
  }
801
- await this.reportGenerator.flush();
802
- const finalPath = await this.reportGenerator.finalize();
803
- this.reportFile = finalPath;
804
- this.resetDump();
736
+ await this.reportManager.waitForReset();
737
+ if (!(0, execution_session_js_namespaceObject.hasActiveYamlExecution)(this)) await this.finalizeReport();
805
738
  if (interfaceDestroyError) throw interfaceDestroyError;
806
739
  }
807
740
  async sleep(ms, options) {
808
741
  options?.abortSignal?.throwIfAborted();
809
- await this.taskExecutor.sleep(ms, options?.abortSignal);
742
+ await this.withReportOperation(()=>this.taskExecutor.sleep(ms, options?.abortSignal));
810
743
  }
811
744
  async recordToReport(title, opt) {
745
+ return this.withReportOperation(()=>this.writeRecordToReport(title, opt));
746
+ }
747
+ async writeRecordToReport(title, opt) {
812
748
  const now = Date.now();
813
749
  const screenshots = opt?.screenshots;
814
750
  const screenshotBase64 = opt?.screenshotBase64;
@@ -866,10 +802,13 @@ class Agent {
866
802
  });
867
803
  this.appendExecutionDump(executionDump);
868
804
  this.writeOutActionDumps(executionDump);
869
- await this.reportGenerator.flush();
805
+ await this.reportManager.flushPendingWrites();
870
806
  this.notifyDumpUpdateListeners(executionDump);
871
807
  }
872
808
  async recordErrorToReport(title, opt) {
809
+ return this.withReportOperation(()=>this.writeErrorToReport(title, opt));
810
+ }
811
+ async writeErrorToReport(title, opt) {
873
812
  const now = Date.now();
874
813
  const error = (0, error_formatter_namespaceObject.serializeError)(opt.error);
875
814
  const recorder = [];
@@ -909,7 +848,7 @@ class Agent {
909
848
  });
910
849
  this.appendExecutionDump(executionDump);
911
850
  this.writeOutActionDumps(executionDump);
912
- await this.reportGenerator.flush();
851
+ await this.reportManager.flushPendingWrites();
913
852
  this.notifyDumpUpdateListeners(executionDump);
914
853
  }
915
854
  async logScreenshot(title, opt) {
@@ -935,30 +874,11 @@ class Agent {
935
874
  this.frozenUIContext = void 0;
936
875
  debug('Page context unfrozen successfully');
937
876
  }
938
- processCacheConfig(opts) {
939
- (0, external_cache_config_js_namespaceObject.validateAgentCacheInput)(opts.cache);
940
- const cacheConfig = (0, external_utils_js_namespaceObject.processCacheConfig)(opts.cache, opts.cacheId || 'default');
941
- if (!cacheConfig) return null;
942
- if ('object' == typeof cacheConfig && null !== cacheConfig) {
943
- const id = cacheConfig.id;
944
- const strategyValue = cacheConfig.strategy ?? 'read-write';
945
- const isReadOnly = 'read-only' === strategyValue;
946
- const isWriteOnly = 'write-only' === strategyValue;
947
- return {
948
- id,
949
- enabled: !isWriteOnly,
950
- readOnly: isReadOnly,
951
- writeOnly: isWriteOnly,
952
- cacheDir: cacheConfig.cacheDir?.trim()
953
- };
954
- }
955
- return null;
956
- }
957
877
  normalizeFileInput(files) {
958
878
  const filesArray = Array.isArray(files) ? files : [
959
879
  files
960
880
  ];
961
- return (0, external_utils_js_namespaceObject_1.normalizeFilePaths)(filesArray);
881
+ return (0, external_utils_js_namespaceObject.normalizeFilePaths)(filesArray);
962
882
  }
963
883
  async flushCache(options) {
964
884
  if (!this.taskCache) throw new Error('Cache is not configured');
@@ -967,11 +887,7 @@ class Agent {
967
887
  constructor(interfaceInstance, opts){
968
888
  _define_property(this, "interface", void 0);
969
889
  _define_property(this, "service", void 0);
970
- _define_property(this, "dump", void 0);
971
- _define_property(this, "reportFile", void 0);
972
- _define_property(this, "reportFileName", void 0);
973
- _define_property(this, "yamlReportScopeId", (0, utils_namespaceObject.uuid)());
974
- _define_property(this, "yamlExecutionRecords", []);
890
+ _define_property(this, "reportManager", void 0);
975
891
  _define_property(this, "taskExecutor", void 0);
976
892
  _define_property(this, "opts", void 0);
977
893
  _define_property(this, "dryMode", false);
@@ -980,7 +896,6 @@ class Agent {
980
896
  _define_property(this, "metricsCollector", new external_metrics_js_namespaceObject.MetricsCollector());
981
897
  _define_property(this, "usageCallCounter", 0);
982
898
  _define_property(this, "countedUsageKeys", new Set());
983
- _define_property(this, "dumpUpdateListeners", []);
984
899
  _define_property(this, "progressBus", new external_progress_index_js_namespaceObject.AgentProgressBus());
985
900
  _define_property(this, "destroyed", false);
986
901
  _define_property(this, "actionReadiness", void 0);
@@ -988,44 +903,17 @@ class Agent {
988
903
  _define_property(this, "frozenUIContext", void 0);
989
904
  _define_property(this, "activeObserver", null);
990
905
  _define_property(this, "ownedObservers", new Set());
991
- _define_property(this, "executionDumpIndexByRunner", new WeakMap());
992
906
  _define_property(this, "fullActionSpace", void 0);
993
907
  _define_property(this, "activeFileChooserAccepter", void 0);
994
908
  _define_property(this, "activeFileChooserAllowedDir", void 0);
995
- _define_property(this, "reportGenerator", void 0);
996
- _define_property(this, "lastExecutionDump", void 0);
997
909
  this.interface = interfaceInstance;
998
- this.opts = Object.assign({
999
- generateReport: true,
1000
- persistExecutionDump: false,
1001
- autoPrintReportMsg: true,
1002
- groupName: 'Midscene Report',
1003
- groupDescription: ''
1004
- }, opts || {});
1005
- (0, external_report_generator_js_namespaceObject.assertReportGenerationOptions)(this.opts);
910
+ this.opts = (0, external_agent_options_js_namespaceObject.withAgentDefaults)(opts);
1006
911
  if (void 0 !== this.opts.waitForActionReady) this.actionReadiness = new external_action_readiness_js_namespaceObject.ActionReadiness(this.opts.waitForActionReady);
1007
- if (void 0 !== this.opts.aiContexts && ('object' != typeof this.opts.aiContexts || null === this.opts.aiContexts || Array.isArray(this.opts.aiContexts))) throw new TypeError('opts.aiContexts must be a plain object');
1008
- for (const [key, value] of Object.entries(this.opts.aiContexts ?? {})){
1009
- if (!(0, agent_context_namespaceObject.isAgentAIContextKey)(key)) throw new TypeError(`Unknown Agent context key: ${key}`);
1010
- if (void 0 !== value && 'string' != typeof value) throw new TypeError(`Agent context "${key}" must be a string`);
1011
- }
1012
- const deprecatedAiActContextOption = void 0 !== this.opts.aiActContext ? 'aiActContext' : void 0 !== this.opts.aiActionContext ? 'aiActionContext' : void 0;
1013
- if (deprecatedAiActContextOption) warn(`Agent option "${deprecatedAiActContextOption}" is deprecated; use "aiContexts.aiAct" instead. When both are provided, "aiContexts.aiAct" takes precedence.`);
1014
- const normalizedAIContexts = {
1015
- ...this.opts.aiContexts
1016
- };
1017
- const resolvedAiActContext = normalizedAIContexts.aiAct ?? this.opts.aiActContext ?? this.opts.aiActionContext;
1018
- if (void 0 !== resolvedAiActContext) {
1019
- normalizedAIContexts.aiAct = resolvedAiActContext;
1020
- this.opts.aiActContext = resolvedAiActContext;
1021
- this.opts.aiActionContext = resolvedAiActContext;
1022
- }
1023
- this.opts.aiContexts = normalizedAIContexts;
1024
- if (opts?.modelConfig && ('object' != typeof opts?.modelConfig || Array.isArray(opts.modelConfig))) throw new Error(`opts.modelConfig must be a plain object map of env keys to values, but got ${typeof opts?.modelConfig}`);
912
+ (0, external_agent_options_js_namespaceObject.normalizeAgentOptions)(this.opts, warn);
1025
913
  this.modelConfigManager = opts?.modelConfig ? new env_namespaceObject.ModelConfigManager(opts.modelConfig, opts.createOpenAIClient) : opts?.createOpenAIClient ? new AgentScopedModelConfigManager(env_namespaceObject.globalModelConfigManager, opts.createOpenAIClient) : env_namespaceObject.globalModelConfigManager;
1026
914
  this.onTaskStartTip = this.opts.onTaskStartTip;
1027
915
  this.service = new (external_service_index_js_default())(async ()=>this.getUIContext());
1028
- const cacheConfigObj = this.processCacheConfig(opts || {});
916
+ const cacheConfigObj = (0, external_cache_config_js_namespaceObject.normalizeAgentCacheConfig)(opts || {});
1029
917
  if (cacheConfigObj) this.taskCache = new external_task_cache_js_namespaceObject.TaskCache(cacheConfigObj.id, cacheConfigObj.enabled, void 0, {
1030
918
  readOnly: cacheConfigObj.readOnly,
1031
919
  writeOnly: cacheConfigObj.writeOnly,
@@ -1056,30 +944,26 @@ class Agent {
1056
944
  operationResource: this,
1057
945
  actionSpace: this.fullActionSpace,
1058
946
  hooks: {
947
+ onExecutionCreated: (runner)=>{
948
+ this.reportManager.bindRunner(runner);
949
+ },
1059
950
  onSnapshotChange: async (runner)=>{
951
+ this.reportManager.assertRunnerCurrent(runner);
1060
952
  const executionDump = runner.dump();
1061
953
  this.appendExecutionDump(executionDump, runner);
1062
954
  this.collectUsageMetrics(executionDump);
1063
955
  this.writeOutActionDumps(executionDump);
1064
- await this.reportGenerator.flush();
1065
- const dumpString = this.dumpDataString();
1066
- for (const listener of this.dumpUpdateListeners)try {
1067
- listener(dumpString, executionDump);
1068
- } catch (error) {
1069
- console.error('Error in onDumpUpdate listener', error);
1070
- }
956
+ await this.reportManager.flushPendingWrites();
957
+ this.reportManager.notifyDumpUpdateListeners(executionDump);
1071
958
  },
1072
959
  onProgress: this.progressBus.publish
1073
960
  }
1074
961
  });
1075
- this.dump = this.resetDump();
1076
- this.reportFileName = opts?.reportFileName ?? (0, external_utils_js_namespaceObject_1.getReportFileName)(opts?.testId || this.interface.interfaceType || 'web');
1077
- this.reportGenerator = external_report_generator_js_namespaceObject.ReportGenerator.create(this.reportFileName, {
1078
- generateReport: this.opts.generateReport,
1079
- persistExecutionDump: this.opts.persistExecutionDump,
1080
- outputFormat: this.opts.outputFormat,
1081
- autoPrintReportMsg: this.opts.autoPrintReportMsg,
1082
- reuseExistingReport: this.opts.reportAttributes?.['data-group-id'] === this.reportFileName
962
+ this.reportManager = new external_agent_report_manager_js_namespaceObject.AgentReportManager({
963
+ getOptions: ()=>this.opts,
964
+ getDeviceType: ()=>this.interface.interfaceType,
965
+ isDestroyed: ()=>this.destroyed,
966
+ isExternallyBusy: ()=>Boolean(this.activeObserver) || (0, execution_session_js_namespaceObject.hasActiveYamlExecution)(this) || (0, resource_operations_js_namespaceObject.hasPendingResourceOperation)(this)
1083
967
  });
1084
968
  Object.defineProperty(this, observation_artifact_namespaceObject.observationArtifactAdapterSymbol, {
1085
969
  value: {