misoai-web 1.0.2 → 1.0.4

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 (72) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +8 -8
  3. package/bin/midscene-playground +2 -2
  4. package/dist/es/agent.js +167 -44
  5. package/dist/es/agent.js.map +1 -1
  6. package/dist/es/bridge-mode-browser.js +64 -17
  7. package/dist/es/bridge-mode-browser.js.map +1 -1
  8. package/dist/es/bridge-mode.js +169 -46
  9. package/dist/es/bridge-mode.js.map +1 -1
  10. package/dist/es/chrome-extension.js +229 -59
  11. package/dist/es/chrome-extension.js.map +1 -1
  12. package/dist/es/index.js +183 -45
  13. package/dist/es/index.js.map +1 -1
  14. package/dist/es/midscene-playground.js +173 -44
  15. package/dist/es/midscene-playground.js.map +1 -1
  16. package/dist/es/midscene-server.js.map +1 -1
  17. package/dist/es/playground.js +173 -44
  18. package/dist/es/playground.js.map +1 -1
  19. package/dist/es/playwright-report.js.map +1 -1
  20. package/dist/es/playwright.js +183 -45
  21. package/dist/es/playwright.js.map +1 -1
  22. package/dist/es/puppeteer-agent-launcher.js +183 -45
  23. package/dist/es/puppeteer-agent-launcher.js.map +1 -1
  24. package/dist/es/puppeteer.js +183 -45
  25. package/dist/es/puppeteer.js.map +1 -1
  26. package/dist/es/ui-utils.js.map +1 -1
  27. package/dist/es/utils.js.map +1 -1
  28. package/dist/es/yaml.js +21 -3
  29. package/dist/es/yaml.js.map +1 -1
  30. package/dist/lib/agent.js +167 -44
  31. package/dist/lib/agent.js.map +1 -1
  32. package/dist/lib/bridge-mode-browser.js +64 -17
  33. package/dist/lib/bridge-mode-browser.js.map +1 -1
  34. package/dist/lib/bridge-mode.js +169 -46
  35. package/dist/lib/bridge-mode.js.map +1 -1
  36. package/dist/lib/chrome-extension.js +229 -59
  37. package/dist/lib/chrome-extension.js.map +1 -1
  38. package/dist/lib/index.js +181 -46
  39. package/dist/lib/index.js.map +1 -1
  40. package/dist/lib/midscene-playground.js +173 -44
  41. package/dist/lib/midscene-playground.js.map +1 -1
  42. package/dist/lib/midscene-server.js.map +1 -1
  43. package/dist/lib/playground.js +173 -44
  44. package/dist/lib/playground.js.map +1 -1
  45. package/dist/lib/playwright-report.js.map +1 -1
  46. package/dist/lib/playwright.js +181 -46
  47. package/dist/lib/playwright.js.map +1 -1
  48. package/dist/lib/puppeteer-agent-launcher.js +181 -46
  49. package/dist/lib/puppeteer-agent-launcher.js.map +1 -1
  50. package/dist/lib/puppeteer.js +181 -46
  51. package/dist/lib/puppeteer.js.map +1 -1
  52. package/dist/lib/ui-utils.js.map +1 -1
  53. package/dist/lib/utils.js.map +1 -1
  54. package/dist/lib/yaml.js +21 -3
  55. package/dist/lib/yaml.js.map +1 -1
  56. package/dist/types/agent.d.ts +16 -6
  57. package/dist/types/bridge-mode-browser.d.ts +2 -2
  58. package/dist/types/bridge-mode.d.ts +2 -2
  59. package/dist/types/{browser-d447695b.d.ts → browser-a1877d18.d.ts} +1 -1
  60. package/dist/types/chrome-extension.d.ts +2 -2
  61. package/dist/types/index.d.ts +1 -1
  62. package/dist/types/midscene-server.d.ts +1 -1
  63. package/dist/types/{page-b8ada1f3.d.ts → page-663ece08.d.ts} +41 -30
  64. package/dist/types/playground.d.ts +2 -2
  65. package/dist/types/playwright.d.ts +1 -1
  66. package/dist/types/puppeteer-agent-launcher.d.ts +1 -1
  67. package/dist/types/puppeteer.d.ts +1 -1
  68. package/dist/types/utils.d.ts +1 -1
  69. package/dist/types/yaml.d.ts +1 -1
  70. package/iife-script/htmlElement.js +99 -37
  71. package/iife-script/htmlElementDebug.js +92 -9
  72. package/package.json +23 -24
package/dist/lib/agent.js CHANGED
@@ -122,7 +122,9 @@ var ScriptPlayer = class {
122
122
  typeof prompt === "string",
123
123
  "prompt for aiAction must be a string"
124
124
  );
125
- await agent.aiAction(prompt);
125
+ await agent.aiAction(prompt, {
126
+ cacheable: actionTask.cacheable
127
+ });
126
128
  } else if ("aiAssert" in flowItem) {
127
129
  const assertTask = flowItem;
128
130
  const prompt = assertTask.aiAssert;
@@ -324,8 +326,24 @@ function interpolateEnvVars(content) {
324
326
  });
325
327
  }
326
328
  function parseYamlScript(content, filePath, ignoreCheckingTarget) {
327
- const interpolatedContent = interpolateEnvVars(content);
328
- const obj = import_js_yaml2.default.load(interpolatedContent);
329
+ let processedContent = content;
330
+ if (content.indexOf("android") !== -1 && content.match(/deviceId:\s*(\d+)/)) {
331
+ let matchedDeviceId;
332
+ processedContent = content.replace(
333
+ /deviceId:\s*(\d+)/g,
334
+ (match, deviceId) => {
335
+ matchedDeviceId = deviceId;
336
+ return `deviceId: '${deviceId}'`;
337
+ }
338
+ );
339
+ console.warn(
340
+ `please use string-style deviceId in yaml script, for example: deviceId: "${matchedDeviceId}"`
341
+ );
342
+ }
343
+ const interpolatedContent = interpolateEnvVars(processedContent);
344
+ const obj = import_js_yaml2.default.load(interpolatedContent, {
345
+ schema: import_js_yaml2.default.JSON_SCHEMA
346
+ });
329
347
  const pathTip = filePath ? `, failed to load ${filePath}` : "";
330
348
  const android = typeof obj.android !== "undefined" ? Object.assign({}, obj.android || {}) : void 0;
331
349
  const webConfig = obj.web || obj.target;
@@ -366,7 +384,6 @@ var import_misoai_core = require("misoai-core");
366
384
  var import_ai_model2 = require("misoai-core/ai-model");
367
385
  var import_utils5 = require("misoai-core/utils");
368
386
  var import_constants = require("misoai-shared/constants");
369
- var import_fs = require("misoai-shared/fs");
370
387
  var import_logger = require("misoai-shared/logger");
371
388
  var import_utils6 = require("misoai-shared/utils");
372
389
 
@@ -598,16 +615,18 @@ var PageTaskExecutor = class {
598
615
  );
599
616
  if (info?.id) {
600
617
  elementId = info.id;
618
+ } else {
619
+ debug(
620
+ "no element id found for position node, will not update cache",
621
+ element
622
+ );
601
623
  }
602
624
  }
603
625
  if (!elementId) {
604
626
  return void 0;
605
627
  }
606
628
  try {
607
- const elementInfosScriptContent = (0, import_fs.getElementInfosScriptContent)();
608
- const result = await this.page.evaluateJavaScript?.(
609
- `${elementInfosScriptContent}midscene_element_inspector.getXpathsById('${elementId}')`
610
- );
629
+ const result = await this.page.getXpathsById(elementId);
611
630
  return result;
612
631
  } catch (error) {
613
632
  debug("getXpathsById error: ", error);
@@ -646,7 +665,7 @@ var PageTaskExecutor = class {
646
665
  };
647
666
  return taskWithScreenshot;
648
667
  }
649
- async convertPlanToExecutable(plans) {
668
+ async convertPlanToExecutable(plans, opts) {
650
669
  const tasks = [];
651
670
  plans.forEach((plan2) => {
652
671
  if (plan2.type === "Locate") {
@@ -656,7 +675,10 @@ var PageTaskExecutor = class {
656
675
  const taskFind = {
657
676
  type: "Insight",
658
677
  subType: "Locate",
659
- param: plan2.locate || void 0,
678
+ param: plan2.locate ? {
679
+ ...plan2.locate,
680
+ cacheable: opts?.cacheable
681
+ } : void 0,
660
682
  thought: plan2.thought,
661
683
  locate: plan2.locate,
662
684
  executor: async (param, taskContext) => {
@@ -693,19 +715,21 @@ var PageTaskExecutor = class {
693
715
  let elementFromCache = null;
694
716
  try {
695
717
  if (xpaths?.length && this.taskCache?.isCacheResultUsed && param?.cacheable !== false) {
696
- const elementInfosScriptContent = (0, import_fs.getElementInfosScriptContent)();
697
- const element2 = await this.page.evaluateJavaScript?.(
698
- `${elementInfosScriptContent}midscene_element_inspector.getElementInfoByXpath('${xpaths[0]}')`
699
- );
700
- if (element2?.id) {
701
- elementFromCache = element2;
702
- debug("cache hit, prompt: %s", cachePrompt);
703
- cacheHitFlag = true;
704
- debug(
705
- "found a new new element with same xpath, xpath: %s, id: %s",
706
- xpaths[0],
707
- element2?.id
718
+ for (let i = 0; i < xpaths.length; i++) {
719
+ const element2 = await this.page.getElementInfoByXpath(
720
+ xpaths[i]
708
721
  );
722
+ if (element2?.id) {
723
+ elementFromCache = element2;
724
+ debug("cache hit, prompt: %s", cachePrompt);
725
+ cacheHitFlag = true;
726
+ debug(
727
+ "found a new new element with same xpath, xpath: %s, id: %s",
728
+ xpaths[i],
729
+ element2?.id
730
+ );
731
+ break;
732
+ }
709
733
  }
710
734
  }
711
735
  } catch (error) {
@@ -718,12 +742,14 @@ var PageTaskExecutor = class {
718
742
  context: pageContext
719
743
  })).element;
720
744
  const aiCost = Date.now() - startTime;
745
+ let currentXpaths;
721
746
  if (element && this.taskCache && !cacheHitFlag && param?.cacheable !== false) {
722
747
  const elementXpaths = await this.getElementXpath(
723
748
  pageContext,
724
749
  element
725
750
  );
726
- if (elementXpaths) {
751
+ if (elementXpaths?.length) {
752
+ currentXpaths = elementXpaths;
727
753
  this.taskCache.updateOrAppendCacheRecord(
728
754
  {
729
755
  type: "locate",
@@ -733,7 +759,11 @@ var PageTaskExecutor = class {
733
759
  locateCacheRecord
734
760
  );
735
761
  } else {
736
- debug("no xpaths found, will not update cache", cachePrompt);
762
+ debug(
763
+ "no xpaths found, will not update cache",
764
+ cachePrompt,
765
+ elementXpaths
766
+ );
737
767
  }
738
768
  }
739
769
  if (!element) {
@@ -745,7 +775,9 @@ var PageTaskExecutor = class {
745
775
  },
746
776
  pageContext,
747
777
  cache: {
748
- hit: cacheHitFlag
778
+ hit: cacheHitFlag,
779
+ originalXpaths: xpaths,
780
+ currentXpaths
749
781
  },
750
782
  aiCost
751
783
  };
@@ -1113,6 +1145,7 @@ var PageTaskExecutor = class {
1113
1145
  sleep: sleep2
1114
1146
  } = planResult;
1115
1147
  executorContext.task.log = {
1148
+ ...executorContext.task.log || {},
1116
1149
  rawResponse
1117
1150
  };
1118
1151
  executorContext.task.usage = usage;
@@ -1237,11 +1270,11 @@ var PageTaskExecutor = class {
1237
1270
  };
1238
1271
  return task;
1239
1272
  }
1240
- async runPlans(title, plans) {
1273
+ async runPlans(title, plans, opts) {
1241
1274
  const taskExecutor = new import_misoai_core.Executor(title, {
1242
1275
  onTaskStart: this.onTaskStartCallback
1243
1276
  });
1244
- const { tasks } = await this.convertPlanToExecutable(plans);
1277
+ const { tasks } = await this.convertPlanToExecutable(plans, opts);
1245
1278
  await taskExecutor.append(tasks);
1246
1279
  const result = await taskExecutor.flush();
1247
1280
  return {
@@ -1249,7 +1282,7 @@ var PageTaskExecutor = class {
1249
1282
  executor: taskExecutor
1250
1283
  };
1251
1284
  }
1252
- async action(userPrompt, actionContext) {
1285
+ async action(userPrompt, actionContext, opts) {
1253
1286
  const taskExecutor = new import_misoai_core.Executor(taskTitleStr("Action", userPrompt), {
1254
1287
  onTaskStart: this.onTaskStartCallback
1255
1288
  });
@@ -1274,7 +1307,7 @@ var PageTaskExecutor = class {
1274
1307
  yamlFlow.push(...planResult.yamlFlow || []);
1275
1308
  let executables;
1276
1309
  try {
1277
- executables = await this.convertPlanToExecutable(plans);
1310
+ executables = await this.convertPlanToExecutable(plans, opts);
1278
1311
  taskExecutor.append(executables.tasks);
1279
1312
  } catch (error) {
1280
1313
  return this.appendErrorPlan(
@@ -1312,7 +1345,7 @@ var PageTaskExecutor = class {
1312
1345
  executor: taskExecutor
1313
1346
  };
1314
1347
  }
1315
- async actionToGoal(userPrompt) {
1348
+ async actionToGoal(userPrompt, opts) {
1316
1349
  const taskExecutor = new import_misoai_core.Executor(taskTitleStr("Action", userPrompt), {
1317
1350
  onTaskStart: this.onTaskStartCallback
1318
1351
  });
@@ -1336,7 +1369,7 @@ var PageTaskExecutor = class {
1336
1369
  yamlFlow.push(...output.yamlFlow || []);
1337
1370
  let executables;
1338
1371
  try {
1339
- executables = await this.convertPlanToExecutable(plans);
1372
+ executables = await this.convertPlanToExecutable(plans, opts);
1340
1373
  taskExecutor.append(executables.tasks);
1341
1374
  } catch (error) {
1342
1375
  return this.appendErrorPlan(
@@ -1641,7 +1674,7 @@ var import_js_yaml3 = __toESM(require("js-yaml"));
1641
1674
  var import_semver = __toESM(require("semver"));
1642
1675
 
1643
1676
  // package.json
1644
- var version = "1.0.2";
1677
+ var version = "1.0.4";
1645
1678
 
1646
1679
  // src/common/task-cache.ts
1647
1680
  var debug3 = (0, import_logger3.getDebug)("cache");
@@ -1984,9 +2017,9 @@ var PageAgent = class {
1984
2017
  buildDetailedLocateParam(locatePrompt, opt) {
1985
2018
  (0, import_utils12.assert)(locatePrompt, "missing locate prompt");
1986
2019
  if (typeof opt === "object") {
1987
- const prompt = opt.prompt || locatePrompt;
1988
- const deepThink = opt.deepThink || false;
1989
- const cacheable = opt.cacheable || true;
2020
+ const prompt = opt.prompt ?? locatePrompt;
2021
+ const deepThink = opt.deepThink ?? false;
2022
+ const cacheable = opt.cacheable ?? true;
1990
2023
  return {
1991
2024
  prompt,
1992
2025
  deepThink,
@@ -2005,7 +2038,8 @@ var PageAgent = class {
2005
2038
  const plans = buildPlans("Tap", detailedLocateParam);
2006
2039
  const { executor, output } = await this.taskExecutor.runPlans(
2007
2040
  taskTitleStr("Tap", locateParamStr(detailedLocateParam)),
2008
- plans
2041
+ plans,
2042
+ { cacheable: opt?.cacheable }
2009
2043
  );
2010
2044
  const metadata = this.afterTaskRunning(executor);
2011
2045
  return {
@@ -2021,7 +2055,8 @@ var PageAgent = class {
2021
2055
  const plans = buildPlans("Hover", detailedLocateParam);
2022
2056
  const { executor, output } = await this.taskExecutor.runPlans(
2023
2057
  taskTitleStr("Hover", locateParamStr(detailedLocateParam)),
2024
- plans
2058
+ plans,
2059
+ { cacheable: opt?.cacheable }
2025
2060
  );
2026
2061
  const metadata = this.afterTaskRunning(executor);
2027
2062
  return {
@@ -2044,7 +2079,8 @@ var PageAgent = class {
2044
2079
  });
2045
2080
  const { executor, output } = await this.taskExecutor.runPlans(
2046
2081
  taskTitleStr("Input", locateParamStr(detailedLocateParam)),
2047
- plans
2082
+ plans,
2083
+ { cacheable: opt?.cacheable }
2048
2084
  );
2049
2085
  const metadata = this.afterTaskRunning(executor);
2050
2086
  return {
@@ -2060,7 +2096,8 @@ var PageAgent = class {
2060
2096
  });
2061
2097
  const { executor, output } = await this.taskExecutor.runPlans(
2062
2098
  taskTitleStr("KeyboardPress", locateParamStr(detailedLocateParam)),
2063
- plans
2099
+ plans,
2100
+ { cacheable: opt?.cacheable }
2064
2101
  );
2065
2102
  const metadata = this.afterTaskRunning(executor);
2066
2103
  return {
@@ -2074,7 +2111,8 @@ var PageAgent = class {
2074
2111
  const paramInTitle = locatePrompt ? `${locateParamStr(detailedLocateParam)} - ${scrollParamStr(scrollParam)}` : scrollParamStr(scrollParam);
2075
2112
  const { executor, output } = await this.taskExecutor.runPlans(
2076
2113
  taskTitleStr("Scroll", paramInTitle),
2077
- plans
2114
+ plans,
2115
+ { cacheable: opt?.cacheable }
2078
2116
  );
2079
2117
  const metadata = this.afterTaskRunning(executor);
2080
2118
  return {
@@ -2083,6 +2121,19 @@ var PageAgent = class {
2083
2121
  };
2084
2122
  }
2085
2123
  async aiAction(taskPrompt, opt) {
2124
+ try {
2125
+ const aiModel = await import("misoai-core/ai-model");
2126
+ const contextStore = aiModel.getContextStore();
2127
+ const processedPrompt = contextStore.replaceAllReferences(taskPrompt, "action");
2128
+ contextStore.addStep({
2129
+ type: "action",
2130
+ summary: `Action: ${processedPrompt}`,
2131
+ prompt: processedPrompt
2132
+ });
2133
+ taskPrompt = processedPrompt;
2134
+ } catch (error) {
2135
+ debug4("Context store not available:", error);
2136
+ }
2086
2137
  const cacheable = opt?.cacheable;
2087
2138
  const isVlmUiTars = (0, import_env2.vlLocateMode)() === "vlm-ui-tars";
2088
2139
  const matchedCache = isVlmUiTars || cacheable === false ? void 0 : this.taskCache?.matchPlanCache(taskPrompt);
@@ -2100,7 +2151,9 @@ var PageAgent = class {
2100
2151
  metadata: metadata2
2101
2152
  };
2102
2153
  }
2103
- const { output, executor } = await (isVlmUiTars ? this.taskExecutor.actionToGoal(taskPrompt) : this.taskExecutor.action(taskPrompt, this.opts.aiActionContext));
2154
+ const { output, executor } = await (isVlmUiTars ? this.taskExecutor.actionToGoal(taskPrompt, { cacheable }) : this.taskExecutor.action(taskPrompt, this.opts.aiActionContext, {
2155
+ cacheable
2156
+ }));
2104
2157
  if (this.taskCache && output?.yamlFlow && cacheable !== false) {
2105
2158
  const yamlContent = {
2106
2159
  tasks: [
@@ -2127,7 +2180,63 @@ var PageAgent = class {
2127
2180
  };
2128
2181
  }
2129
2182
  async aiQuery(demand) {
2130
- const { output, executor } = await this.taskExecutor.query(demand);
2183
+ let processedDemand = demand;
2184
+ let storageKey;
2185
+ try {
2186
+ const aiModel = await import("misoai-core/ai-model");
2187
+ const contextStore = aiModel.getContextStore();
2188
+ if (typeof demand === "string") {
2189
+ const storageInstruction = contextStore.parseStorageInstruction(demand);
2190
+ if (storageInstruction) {
2191
+ storageKey = storageInstruction.key;
2192
+ processedDemand = storageInstruction.cleanText;
2193
+ contextStore._pendingAliases = storageInstruction.aliases;
2194
+ } else {
2195
+ const storageMatch = demand.match(/store\s+(?:as\s+)?(\w+)/i);
2196
+ if (storageMatch) {
2197
+ storageKey = storageMatch[1];
2198
+ processedDemand = demand.replace(/,?\s*store\s+(?:as\s+)?\w+/i, "").trim();
2199
+ }
2200
+ }
2201
+ }
2202
+ } catch (error) {
2203
+ debug4("Context store not available:", error);
2204
+ }
2205
+ const { output, executor } = await this.taskExecutor.query(processedDemand);
2206
+ if (storageKey && output) {
2207
+ try {
2208
+ const aiModel = await import("misoai-core/ai-model");
2209
+ const contextStore = aiModel.getContextStore();
2210
+ const pendingAliases = contextStore._pendingAliases;
2211
+ if (pendingAliases) {
2212
+ contextStore.storeDataWithAliases(storageKey, output, pendingAliases, typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand));
2213
+ delete contextStore._pendingAliases;
2214
+ } else {
2215
+ contextStore.storeData(storageKey, output);
2216
+ }
2217
+ contextStore.addStep({
2218
+ type: "query",
2219
+ summary: `Query: ${typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)} (stored as ${storageKey})`,
2220
+ data: output,
2221
+ prompt: typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)
2222
+ });
2223
+ } catch (error) {
2224
+ debug4("Failed to store query result:", error);
2225
+ }
2226
+ } else {
2227
+ try {
2228
+ const aiModel = await import("misoai-core/ai-model");
2229
+ const contextStore = aiModel.getContextStore();
2230
+ contextStore.addStep({
2231
+ type: "query",
2232
+ summary: `Query: ${typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)}`,
2233
+ data: output,
2234
+ prompt: typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)
2235
+ });
2236
+ } catch (error) {
2237
+ debug4("Failed to add query step:", error);
2238
+ }
2239
+ }
2131
2240
  const metadata = this.afterTaskRunning(executor);
2132
2241
  return {
2133
2242
  result: output,
@@ -2222,7 +2331,8 @@ var PageAgent = class {
2222
2331
  const plans = buildPlans("Locate", detailedLocateParam);
2223
2332
  const { executor, output } = await this.taskExecutor.runPlans(
2224
2333
  taskTitleStr("Locate", locateParamStr(detailedLocateParam)),
2225
- plans
2334
+ plans,
2335
+ { cacheable: opt?.cacheable }
2226
2336
  );
2227
2337
  const metadata = this.afterTaskRunning(executor);
2228
2338
  const { element } = output;
@@ -2236,6 +2346,19 @@ var PageAgent = class {
2236
2346
  };
2237
2347
  }
2238
2348
  async aiAssert(assertion, msg, opt) {
2349
+ let processedAssertion = assertion;
2350
+ try {
2351
+ const aiModel = await import("misoai-core/ai-model");
2352
+ const contextStore = aiModel.getContextStore();
2353
+ processedAssertion = contextStore.replaceAllReferences(assertion, "assertion");
2354
+ contextStore.addStep({
2355
+ type: "assertion",
2356
+ summary: `Assertion: ${processedAssertion}`,
2357
+ prompt: processedAssertion
2358
+ });
2359
+ } catch (error) {
2360
+ debug4("Context store not available:", error);
2361
+ }
2239
2362
  let currentUrl = "";
2240
2363
  if (this.page.url) {
2241
2364
  try {
@@ -2243,7 +2366,7 @@ var PageAgent = class {
2243
2366
  } catch (e) {
2244
2367
  }
2245
2368
  }
2246
- const assertionWithContext = currentUrl ? `For the page at URL "${currentUrl}", ${assertion}` : assertion;
2369
+ const assertionWithContext = currentUrl ? `For the page at URL "${currentUrl}", ${processedAssertion}` : processedAssertion;
2247
2370
  const { output, executor } = await this.taskExecutor.assert(assertionWithContext);
2248
2371
  const metadata = this.afterTaskRunning(executor, true);
2249
2372
  if (output && opt?.keepRawResponse) {