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/index.js CHANGED
@@ -131,7 +131,9 @@ var ScriptPlayer = class {
131
131
  typeof prompt === "string",
132
132
  "prompt for aiAction must be a string"
133
133
  );
134
- await agent.aiAction(prompt);
134
+ await agent.aiAction(prompt, {
135
+ cacheable: actionTask.cacheable
136
+ });
135
137
  } else if ("aiAssert" in flowItem) {
136
138
  const assertTask = flowItem;
137
139
  const prompt = assertTask.aiAssert;
@@ -333,8 +335,24 @@ function interpolateEnvVars(content) {
333
335
  });
334
336
  }
335
337
  function parseYamlScript(content, filePath, ignoreCheckingTarget) {
336
- const interpolatedContent = interpolateEnvVars(content);
337
- const obj = import_js_yaml2.default.load(interpolatedContent);
338
+ let processedContent = content;
339
+ if (content.indexOf("android") !== -1 && content.match(/deviceId:\s*(\d+)/)) {
340
+ let matchedDeviceId;
341
+ processedContent = content.replace(
342
+ /deviceId:\s*(\d+)/g,
343
+ (match, deviceId) => {
344
+ matchedDeviceId = deviceId;
345
+ return `deviceId: '${deviceId}'`;
346
+ }
347
+ );
348
+ console.warn(
349
+ `please use string-style deviceId in yaml script, for example: deviceId: "${matchedDeviceId}"`
350
+ );
351
+ }
352
+ const interpolatedContent = interpolateEnvVars(processedContent);
353
+ const obj = import_js_yaml2.default.load(interpolatedContent, {
354
+ schema: import_js_yaml2.default.JSON_SCHEMA
355
+ });
338
356
  const pathTip = filePath ? `, failed to load ${filePath}` : "";
339
357
  const android = typeof obj.android !== "undefined" ? Object.assign({}, obj.android || {}) : void 0;
340
358
  const webConfig = obj.web || obj.target;
@@ -375,7 +393,6 @@ var import_misoai_core = require("misoai-core");
375
393
  var import_ai_model2 = require("misoai-core/ai-model");
376
394
  var import_utils5 = require("misoai-core/utils");
377
395
  var import_constants = require("misoai-shared/constants");
378
- var import_fs = require("misoai-shared/fs");
379
396
  var import_logger = require("misoai-shared/logger");
380
397
  var import_utils6 = require("misoai-shared/utils");
381
398
 
@@ -635,16 +652,18 @@ var PageTaskExecutor = class {
635
652
  );
636
653
  if (info?.id) {
637
654
  elementId = info.id;
655
+ } else {
656
+ debug(
657
+ "no element id found for position node, will not update cache",
658
+ element
659
+ );
638
660
  }
639
661
  }
640
662
  if (!elementId) {
641
663
  return void 0;
642
664
  }
643
665
  try {
644
- const elementInfosScriptContent = (0, import_fs.getElementInfosScriptContent)();
645
- const result = await this.page.evaluateJavaScript?.(
646
- `${elementInfosScriptContent}midscene_element_inspector.getXpathsById('${elementId}')`
647
- );
666
+ const result = await this.page.getXpathsById(elementId);
648
667
  return result;
649
668
  } catch (error) {
650
669
  debug("getXpathsById error: ", error);
@@ -683,7 +702,7 @@ var PageTaskExecutor = class {
683
702
  };
684
703
  return taskWithScreenshot;
685
704
  }
686
- async convertPlanToExecutable(plans) {
705
+ async convertPlanToExecutable(plans, opts) {
687
706
  const tasks = [];
688
707
  plans.forEach((plan2) => {
689
708
  if (plan2.type === "Locate") {
@@ -693,7 +712,10 @@ var PageTaskExecutor = class {
693
712
  const taskFind = {
694
713
  type: "Insight",
695
714
  subType: "Locate",
696
- param: plan2.locate || void 0,
715
+ param: plan2.locate ? {
716
+ ...plan2.locate,
717
+ cacheable: opts?.cacheable
718
+ } : void 0,
697
719
  thought: plan2.thought,
698
720
  locate: plan2.locate,
699
721
  executor: async (param, taskContext) => {
@@ -730,19 +752,21 @@ var PageTaskExecutor = class {
730
752
  let elementFromCache = null;
731
753
  try {
732
754
  if (xpaths?.length && this.taskCache?.isCacheResultUsed && param?.cacheable !== false) {
733
- const elementInfosScriptContent = (0, import_fs.getElementInfosScriptContent)();
734
- const element2 = await this.page.evaluateJavaScript?.(
735
- `${elementInfosScriptContent}midscene_element_inspector.getElementInfoByXpath('${xpaths[0]}')`
736
- );
737
- if (element2?.id) {
738
- elementFromCache = element2;
739
- debug("cache hit, prompt: %s", cachePrompt);
740
- cacheHitFlag = true;
741
- debug(
742
- "found a new new element with same xpath, xpath: %s, id: %s",
743
- xpaths[0],
744
- element2?.id
755
+ for (let i = 0; i < xpaths.length; i++) {
756
+ const element2 = await this.page.getElementInfoByXpath(
757
+ xpaths[i]
745
758
  );
759
+ if (element2?.id) {
760
+ elementFromCache = element2;
761
+ debug("cache hit, prompt: %s", cachePrompt);
762
+ cacheHitFlag = true;
763
+ debug(
764
+ "found a new new element with same xpath, xpath: %s, id: %s",
765
+ xpaths[i],
766
+ element2?.id
767
+ );
768
+ break;
769
+ }
746
770
  }
747
771
  }
748
772
  } catch (error) {
@@ -755,12 +779,14 @@ var PageTaskExecutor = class {
755
779
  context: pageContext
756
780
  })).element;
757
781
  const aiCost = Date.now() - startTime;
782
+ let currentXpaths;
758
783
  if (element && this.taskCache && !cacheHitFlag && param?.cacheable !== false) {
759
784
  const elementXpaths = await this.getElementXpath(
760
785
  pageContext,
761
786
  element
762
787
  );
763
- if (elementXpaths) {
788
+ if (elementXpaths?.length) {
789
+ currentXpaths = elementXpaths;
764
790
  this.taskCache.updateOrAppendCacheRecord(
765
791
  {
766
792
  type: "locate",
@@ -770,7 +796,11 @@ var PageTaskExecutor = class {
770
796
  locateCacheRecord
771
797
  );
772
798
  } else {
773
- debug("no xpaths found, will not update cache", cachePrompt);
799
+ debug(
800
+ "no xpaths found, will not update cache",
801
+ cachePrompt,
802
+ elementXpaths
803
+ );
774
804
  }
775
805
  }
776
806
  if (!element) {
@@ -782,7 +812,9 @@ var PageTaskExecutor = class {
782
812
  },
783
813
  pageContext,
784
814
  cache: {
785
- hit: cacheHitFlag
815
+ hit: cacheHitFlag,
816
+ originalXpaths: xpaths,
817
+ currentXpaths
786
818
  },
787
819
  aiCost
788
820
  };
@@ -1150,6 +1182,7 @@ var PageTaskExecutor = class {
1150
1182
  sleep: sleep3
1151
1183
  } = planResult;
1152
1184
  executorContext.task.log = {
1185
+ ...executorContext.task.log || {},
1153
1186
  rawResponse
1154
1187
  };
1155
1188
  executorContext.task.usage = usage;
@@ -1274,11 +1307,11 @@ var PageTaskExecutor = class {
1274
1307
  };
1275
1308
  return task;
1276
1309
  }
1277
- async runPlans(title, plans) {
1310
+ async runPlans(title, plans, opts) {
1278
1311
  const taskExecutor = new import_misoai_core.Executor(title, {
1279
1312
  onTaskStart: this.onTaskStartCallback
1280
1313
  });
1281
- const { tasks } = await this.convertPlanToExecutable(plans);
1314
+ const { tasks } = await this.convertPlanToExecutable(plans, opts);
1282
1315
  await taskExecutor.append(tasks);
1283
1316
  const result = await taskExecutor.flush();
1284
1317
  return {
@@ -1286,7 +1319,7 @@ var PageTaskExecutor = class {
1286
1319
  executor: taskExecutor
1287
1320
  };
1288
1321
  }
1289
- async action(userPrompt, actionContext) {
1322
+ async action(userPrompt, actionContext, opts) {
1290
1323
  const taskExecutor = new import_misoai_core.Executor(taskTitleStr("Action", userPrompt), {
1291
1324
  onTaskStart: this.onTaskStartCallback
1292
1325
  });
@@ -1311,7 +1344,7 @@ var PageTaskExecutor = class {
1311
1344
  yamlFlow.push(...planResult.yamlFlow || []);
1312
1345
  let executables;
1313
1346
  try {
1314
- executables = await this.convertPlanToExecutable(plans);
1347
+ executables = await this.convertPlanToExecutable(plans, opts);
1315
1348
  taskExecutor.append(executables.tasks);
1316
1349
  } catch (error) {
1317
1350
  return this.appendErrorPlan(
@@ -1349,7 +1382,7 @@ var PageTaskExecutor = class {
1349
1382
  executor: taskExecutor
1350
1383
  };
1351
1384
  }
1352
- async actionToGoal(userPrompt) {
1385
+ async actionToGoal(userPrompt, opts) {
1353
1386
  const taskExecutor = new import_misoai_core.Executor(taskTitleStr("Action", userPrompt), {
1354
1387
  onTaskStart: this.onTaskStartCallback
1355
1388
  });
@@ -1373,7 +1406,7 @@ var PageTaskExecutor = class {
1373
1406
  yamlFlow.push(...output.yamlFlow || []);
1374
1407
  let executables;
1375
1408
  try {
1376
- executables = await this.convertPlanToExecutable(plans);
1409
+ executables = await this.convertPlanToExecutable(plans, opts);
1377
1410
  taskExecutor.append(executables.tasks);
1378
1411
  } catch (error) {
1379
1412
  return this.appendErrorPlan(
@@ -1678,7 +1711,7 @@ var import_js_yaml3 = __toESM(require("js-yaml"));
1678
1711
  var import_semver = __toESM(require("semver"));
1679
1712
 
1680
1713
  // package.json
1681
- var version = "1.0.2";
1714
+ var version = "1.0.4";
1682
1715
 
1683
1716
  // src/common/task-cache.ts
1684
1717
  var debug3 = (0, import_logger3.getDebug)("cache");
@@ -2021,9 +2054,9 @@ var PageAgent = class {
2021
2054
  buildDetailedLocateParam(locatePrompt, opt) {
2022
2055
  (0, import_utils12.assert)(locatePrompt, "missing locate prompt");
2023
2056
  if (typeof opt === "object") {
2024
- const prompt = opt.prompt || locatePrompt;
2025
- const deepThink = opt.deepThink || false;
2026
- const cacheable = opt.cacheable || true;
2057
+ const prompt = opt.prompt ?? locatePrompt;
2058
+ const deepThink = opt.deepThink ?? false;
2059
+ const cacheable = opt.cacheable ?? true;
2027
2060
  return {
2028
2061
  prompt,
2029
2062
  deepThink,
@@ -2042,7 +2075,8 @@ var PageAgent = class {
2042
2075
  const plans = buildPlans("Tap", detailedLocateParam);
2043
2076
  const { executor, output } = await this.taskExecutor.runPlans(
2044
2077
  taskTitleStr("Tap", locateParamStr(detailedLocateParam)),
2045
- plans
2078
+ plans,
2079
+ { cacheable: opt?.cacheable }
2046
2080
  );
2047
2081
  const metadata = this.afterTaskRunning(executor);
2048
2082
  return {
@@ -2058,7 +2092,8 @@ var PageAgent = class {
2058
2092
  const plans = buildPlans("Hover", detailedLocateParam);
2059
2093
  const { executor, output } = await this.taskExecutor.runPlans(
2060
2094
  taskTitleStr("Hover", locateParamStr(detailedLocateParam)),
2061
- plans
2095
+ plans,
2096
+ { cacheable: opt?.cacheable }
2062
2097
  );
2063
2098
  const metadata = this.afterTaskRunning(executor);
2064
2099
  return {
@@ -2081,7 +2116,8 @@ var PageAgent = class {
2081
2116
  });
2082
2117
  const { executor, output } = await this.taskExecutor.runPlans(
2083
2118
  taskTitleStr("Input", locateParamStr(detailedLocateParam)),
2084
- plans
2119
+ plans,
2120
+ { cacheable: opt?.cacheable }
2085
2121
  );
2086
2122
  const metadata = this.afterTaskRunning(executor);
2087
2123
  return {
@@ -2097,7 +2133,8 @@ var PageAgent = class {
2097
2133
  });
2098
2134
  const { executor, output } = await this.taskExecutor.runPlans(
2099
2135
  taskTitleStr("KeyboardPress", locateParamStr(detailedLocateParam)),
2100
- plans
2136
+ plans,
2137
+ { cacheable: opt?.cacheable }
2101
2138
  );
2102
2139
  const metadata = this.afterTaskRunning(executor);
2103
2140
  return {
@@ -2111,7 +2148,8 @@ var PageAgent = class {
2111
2148
  const paramInTitle = locatePrompt ? `${locateParamStr(detailedLocateParam)} - ${scrollParamStr(scrollParam)}` : scrollParamStr(scrollParam);
2112
2149
  const { executor, output } = await this.taskExecutor.runPlans(
2113
2150
  taskTitleStr("Scroll", paramInTitle),
2114
- plans
2151
+ plans,
2152
+ { cacheable: opt?.cacheable }
2115
2153
  );
2116
2154
  const metadata = this.afterTaskRunning(executor);
2117
2155
  return {
@@ -2120,6 +2158,19 @@ var PageAgent = class {
2120
2158
  };
2121
2159
  }
2122
2160
  async aiAction(taskPrompt, opt) {
2161
+ try {
2162
+ const aiModel = await import("misoai-core/ai-model");
2163
+ const contextStore = aiModel.getContextStore();
2164
+ const processedPrompt = contextStore.replaceAllReferences(taskPrompt, "action");
2165
+ contextStore.addStep({
2166
+ type: "action",
2167
+ summary: `Action: ${processedPrompt}`,
2168
+ prompt: processedPrompt
2169
+ });
2170
+ taskPrompt = processedPrompt;
2171
+ } catch (error) {
2172
+ debug4("Context store not available:", error);
2173
+ }
2123
2174
  const cacheable = opt?.cacheable;
2124
2175
  const isVlmUiTars = (0, import_env2.vlLocateMode)() === "vlm-ui-tars";
2125
2176
  const matchedCache = isVlmUiTars || cacheable === false ? void 0 : this.taskCache?.matchPlanCache(taskPrompt);
@@ -2137,7 +2188,9 @@ var PageAgent = class {
2137
2188
  metadata: metadata2
2138
2189
  };
2139
2190
  }
2140
- const { output, executor } = await (isVlmUiTars ? this.taskExecutor.actionToGoal(taskPrompt) : this.taskExecutor.action(taskPrompt, this.opts.aiActionContext));
2191
+ const { output, executor } = await (isVlmUiTars ? this.taskExecutor.actionToGoal(taskPrompt, { cacheable }) : this.taskExecutor.action(taskPrompt, this.opts.aiActionContext, {
2192
+ cacheable
2193
+ }));
2141
2194
  if (this.taskCache && output?.yamlFlow && cacheable !== false) {
2142
2195
  const yamlContent = {
2143
2196
  tasks: [
@@ -2164,7 +2217,63 @@ var PageAgent = class {
2164
2217
  };
2165
2218
  }
2166
2219
  async aiQuery(demand) {
2167
- const { output, executor } = await this.taskExecutor.query(demand);
2220
+ let processedDemand = demand;
2221
+ let storageKey;
2222
+ try {
2223
+ const aiModel = await import("misoai-core/ai-model");
2224
+ const contextStore = aiModel.getContextStore();
2225
+ if (typeof demand === "string") {
2226
+ const storageInstruction = contextStore.parseStorageInstruction(demand);
2227
+ if (storageInstruction) {
2228
+ storageKey = storageInstruction.key;
2229
+ processedDemand = storageInstruction.cleanText;
2230
+ contextStore._pendingAliases = storageInstruction.aliases;
2231
+ } else {
2232
+ const storageMatch = demand.match(/store\s+(?:as\s+)?(\w+)/i);
2233
+ if (storageMatch) {
2234
+ storageKey = storageMatch[1];
2235
+ processedDemand = demand.replace(/,?\s*store\s+(?:as\s+)?\w+/i, "").trim();
2236
+ }
2237
+ }
2238
+ }
2239
+ } catch (error) {
2240
+ debug4("Context store not available:", error);
2241
+ }
2242
+ const { output, executor } = await this.taskExecutor.query(processedDemand);
2243
+ if (storageKey && output) {
2244
+ try {
2245
+ const aiModel = await import("misoai-core/ai-model");
2246
+ const contextStore = aiModel.getContextStore();
2247
+ const pendingAliases = contextStore._pendingAliases;
2248
+ if (pendingAliases) {
2249
+ contextStore.storeDataWithAliases(storageKey, output, pendingAliases, typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand));
2250
+ delete contextStore._pendingAliases;
2251
+ } else {
2252
+ contextStore.storeData(storageKey, output);
2253
+ }
2254
+ contextStore.addStep({
2255
+ type: "query",
2256
+ summary: `Query: ${typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)} (stored as ${storageKey})`,
2257
+ data: output,
2258
+ prompt: typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)
2259
+ });
2260
+ } catch (error) {
2261
+ debug4("Failed to store query result:", error);
2262
+ }
2263
+ } else {
2264
+ try {
2265
+ const aiModel = await import("misoai-core/ai-model");
2266
+ const contextStore = aiModel.getContextStore();
2267
+ contextStore.addStep({
2268
+ type: "query",
2269
+ summary: `Query: ${typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)}`,
2270
+ data: output,
2271
+ prompt: typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)
2272
+ });
2273
+ } catch (error) {
2274
+ debug4("Failed to add query step:", error);
2275
+ }
2276
+ }
2168
2277
  const metadata = this.afterTaskRunning(executor);
2169
2278
  return {
2170
2279
  result: output,
@@ -2259,7 +2368,8 @@ var PageAgent = class {
2259
2368
  const plans = buildPlans("Locate", detailedLocateParam);
2260
2369
  const { executor, output } = await this.taskExecutor.runPlans(
2261
2370
  taskTitleStr("Locate", locateParamStr(detailedLocateParam)),
2262
- plans
2371
+ plans,
2372
+ { cacheable: opt?.cacheable }
2263
2373
  );
2264
2374
  const metadata = this.afterTaskRunning(executor);
2265
2375
  const { element } = output;
@@ -2273,6 +2383,19 @@ var PageAgent = class {
2273
2383
  };
2274
2384
  }
2275
2385
  async aiAssert(assertion, msg, opt) {
2386
+ let processedAssertion = assertion;
2387
+ try {
2388
+ const aiModel = await import("misoai-core/ai-model");
2389
+ const contextStore = aiModel.getContextStore();
2390
+ processedAssertion = contextStore.replaceAllReferences(assertion, "assertion");
2391
+ contextStore.addStep({
2392
+ type: "assertion",
2393
+ summary: `Assertion: ${processedAssertion}`,
2394
+ prompt: processedAssertion
2395
+ });
2396
+ } catch (error) {
2397
+ debug4("Context store not available:", error);
2398
+ }
2276
2399
  let currentUrl = "";
2277
2400
  if (this.page.url) {
2278
2401
  try {
@@ -2280,7 +2403,7 @@ var PageAgent = class {
2280
2403
  } catch (e) {
2281
2404
  }
2282
2405
  }
2283
- const assertionWithContext = currentUrl ? `For the page at URL "${currentUrl}", ${assertion}` : assertion;
2406
+ const assertionWithContext = currentUrl ? `For the page at URL "${currentUrl}", ${processedAssertion}` : processedAssertion;
2284
2407
  const { output, executor } = await this.taskExecutor.assert(assertionWithContext);
2285
2408
  const metadata = this.afterTaskRunning(executor, true);
2286
2409
  if (output && opt?.keepRawResponse) {
@@ -2500,7 +2623,7 @@ ${errors}`);
2500
2623
  var import_utils15 = require("misoai-core/utils");
2501
2624
  var import_constants3 = require("misoai-shared/constants");
2502
2625
  var import_extractor2 = require("misoai-shared/extractor");
2503
- var import_fs2 = require("misoai-shared/fs");
2626
+ var import_fs = require("misoai-shared/fs");
2504
2627
  var import_logger5 = require("misoai-shared/logger");
2505
2628
  var import_utils16 = require("misoai-shared/utils");
2506
2629
  var debugPage = (0, import_logger5.getDebug)("web:page");
@@ -2555,9 +2678,21 @@ var Page = class {
2555
2678
  debugPage("getElementsInfo end");
2556
2679
  return (0, import_extractor2.treeToList)(tree);
2557
2680
  }
2681
+ async getXpathsById(id) {
2682
+ const elementInfosScriptContent = (0, import_fs.getElementInfosScriptContent)();
2683
+ return this.evaluateJavaScript(
2684
+ `${elementInfosScriptContent}midscene_element_inspector.getXpathsById('${id}')`
2685
+ );
2686
+ }
2687
+ async getElementInfoByXpath(xpath) {
2688
+ const elementInfosScriptContent = (0, import_fs.getElementInfosScriptContent)();
2689
+ return this.evaluateJavaScript(
2690
+ `${elementInfosScriptContent}midscene_element_inspector.getElementInfoByXpath('${xpath}')`
2691
+ );
2692
+ }
2558
2693
  async getElementsNodeTree() {
2559
2694
  await this.waitForNavigation();
2560
- const scripts = await (0, import_fs2.getExtraReturnLogic)(true);
2695
+ const scripts = await (0, import_fs.getExtraReturnLogic)(true);
2561
2696
  (0, import_utils16.assert)(scripts, "scripts should be set before writing report in browser");
2562
2697
  const captureElementSnapshot = await this.evaluate(scripts);
2563
2698
  return captureElementSnapshot;