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
@@ -133,7 +133,9 @@ var ScriptPlayer = class {
133
133
  typeof prompt === "string",
134
134
  "prompt for aiAction must be a string"
135
135
  );
136
- await agent.aiAction(prompt);
136
+ await agent.aiAction(prompt, {
137
+ cacheable: actionTask.cacheable
138
+ });
137
139
  } else if ("aiAssert" in flowItem) {
138
140
  const assertTask = flowItem;
139
141
  const prompt = assertTask.aiAssert;
@@ -335,8 +337,24 @@ function interpolateEnvVars(content) {
335
337
  });
336
338
  }
337
339
  function parseYamlScript(content, filePath, ignoreCheckingTarget) {
338
- const interpolatedContent = interpolateEnvVars(content);
339
- const obj = import_js_yaml2.default.load(interpolatedContent);
340
+ let processedContent = content;
341
+ if (content.indexOf("android") !== -1 && content.match(/deviceId:\s*(\d+)/)) {
342
+ let matchedDeviceId;
343
+ processedContent = content.replace(
344
+ /deviceId:\s*(\d+)/g,
345
+ (match, deviceId) => {
346
+ matchedDeviceId = deviceId;
347
+ return `deviceId: '${deviceId}'`;
348
+ }
349
+ );
350
+ console.warn(
351
+ `please use string-style deviceId in yaml script, for example: deviceId: "${matchedDeviceId}"`
352
+ );
353
+ }
354
+ const interpolatedContent = interpolateEnvVars(processedContent);
355
+ const obj = import_js_yaml2.default.load(interpolatedContent, {
356
+ schema: import_js_yaml2.default.JSON_SCHEMA
357
+ });
340
358
  const pathTip = filePath ? `, failed to load ${filePath}` : "";
341
359
  const android = typeof obj.android !== "undefined" ? Object.assign({}, obj.android || {}) : void 0;
342
360
  const webConfig = obj.web || obj.target;
@@ -377,7 +395,6 @@ var import_misoai_core = require("misoai-core");
377
395
  var import_ai_model2 = require("misoai-core/ai-model");
378
396
  var import_utils5 = require("misoai-core/utils");
379
397
  var import_constants = require("misoai-shared/constants");
380
- var import_fs = require("misoai-shared/fs");
381
398
  var import_logger = require("misoai-shared/logger");
382
399
  var import_utils6 = require("misoai-shared/utils");
383
400
 
@@ -637,16 +654,18 @@ var PageTaskExecutor = class {
637
654
  );
638
655
  if (info?.id) {
639
656
  elementId = info.id;
657
+ } else {
658
+ debug(
659
+ "no element id found for position node, will not update cache",
660
+ element
661
+ );
640
662
  }
641
663
  }
642
664
  if (!elementId) {
643
665
  return void 0;
644
666
  }
645
667
  try {
646
- const elementInfosScriptContent = (0, import_fs.getElementInfosScriptContent)();
647
- const result = await this.page.evaluateJavaScript?.(
648
- `${elementInfosScriptContent}midscene_element_inspector.getXpathsById('${elementId}')`
649
- );
668
+ const result = await this.page.getXpathsById(elementId);
650
669
  return result;
651
670
  } catch (error) {
652
671
  debug("getXpathsById error: ", error);
@@ -685,7 +704,7 @@ var PageTaskExecutor = class {
685
704
  };
686
705
  return taskWithScreenshot;
687
706
  }
688
- async convertPlanToExecutable(plans) {
707
+ async convertPlanToExecutable(plans, opts) {
689
708
  const tasks = [];
690
709
  plans.forEach((plan2) => {
691
710
  if (plan2.type === "Locate") {
@@ -695,7 +714,10 @@ var PageTaskExecutor = class {
695
714
  const taskFind = {
696
715
  type: "Insight",
697
716
  subType: "Locate",
698
- param: plan2.locate || void 0,
717
+ param: plan2.locate ? {
718
+ ...plan2.locate,
719
+ cacheable: opts?.cacheable
720
+ } : void 0,
699
721
  thought: plan2.thought,
700
722
  locate: plan2.locate,
701
723
  executor: async (param, taskContext) => {
@@ -732,19 +754,21 @@ var PageTaskExecutor = class {
732
754
  let elementFromCache = null;
733
755
  try {
734
756
  if (xpaths?.length && this.taskCache?.isCacheResultUsed && param?.cacheable !== false) {
735
- const elementInfosScriptContent = (0, import_fs.getElementInfosScriptContent)();
736
- const element2 = await this.page.evaluateJavaScript?.(
737
- `${elementInfosScriptContent}midscene_element_inspector.getElementInfoByXpath('${xpaths[0]}')`
738
- );
739
- if (element2?.id) {
740
- elementFromCache = element2;
741
- debug("cache hit, prompt: %s", cachePrompt);
742
- cacheHitFlag = true;
743
- debug(
744
- "found a new new element with same xpath, xpath: %s, id: %s",
745
- xpaths[0],
746
- element2?.id
757
+ for (let i = 0; i < xpaths.length; i++) {
758
+ const element2 = await this.page.getElementInfoByXpath(
759
+ xpaths[i]
747
760
  );
761
+ if (element2?.id) {
762
+ elementFromCache = element2;
763
+ debug("cache hit, prompt: %s", cachePrompt);
764
+ cacheHitFlag = true;
765
+ debug(
766
+ "found a new new element with same xpath, xpath: %s, id: %s",
767
+ xpaths[i],
768
+ element2?.id
769
+ );
770
+ break;
771
+ }
748
772
  }
749
773
  }
750
774
  } catch (error) {
@@ -757,12 +781,14 @@ var PageTaskExecutor = class {
757
781
  context: pageContext
758
782
  })).element;
759
783
  const aiCost = Date.now() - startTime;
784
+ let currentXpaths;
760
785
  if (element && this.taskCache && !cacheHitFlag && param?.cacheable !== false) {
761
786
  const elementXpaths = await this.getElementXpath(
762
787
  pageContext,
763
788
  element
764
789
  );
765
- if (elementXpaths) {
790
+ if (elementXpaths?.length) {
791
+ currentXpaths = elementXpaths;
766
792
  this.taskCache.updateOrAppendCacheRecord(
767
793
  {
768
794
  type: "locate",
@@ -772,7 +798,11 @@ var PageTaskExecutor = class {
772
798
  locateCacheRecord
773
799
  );
774
800
  } else {
775
- debug("no xpaths found, will not update cache", cachePrompt);
801
+ debug(
802
+ "no xpaths found, will not update cache",
803
+ cachePrompt,
804
+ elementXpaths
805
+ );
776
806
  }
777
807
  }
778
808
  if (!element) {
@@ -784,7 +814,9 @@ var PageTaskExecutor = class {
784
814
  },
785
815
  pageContext,
786
816
  cache: {
787
- hit: cacheHitFlag
817
+ hit: cacheHitFlag,
818
+ originalXpaths: xpaths,
819
+ currentXpaths
788
820
  },
789
821
  aiCost
790
822
  };
@@ -1152,6 +1184,7 @@ var PageTaskExecutor = class {
1152
1184
  sleep: sleep3
1153
1185
  } = planResult;
1154
1186
  executorContext.task.log = {
1187
+ ...executorContext.task.log || {},
1155
1188
  rawResponse
1156
1189
  };
1157
1190
  executorContext.task.usage = usage;
@@ -1276,11 +1309,11 @@ var PageTaskExecutor = class {
1276
1309
  };
1277
1310
  return task;
1278
1311
  }
1279
- async runPlans(title, plans) {
1312
+ async runPlans(title, plans, opts) {
1280
1313
  const taskExecutor = new import_misoai_core.Executor(title, {
1281
1314
  onTaskStart: this.onTaskStartCallback
1282
1315
  });
1283
- const { tasks } = await this.convertPlanToExecutable(plans);
1316
+ const { tasks } = await this.convertPlanToExecutable(plans, opts);
1284
1317
  await taskExecutor.append(tasks);
1285
1318
  const result = await taskExecutor.flush();
1286
1319
  return {
@@ -1288,7 +1321,7 @@ var PageTaskExecutor = class {
1288
1321
  executor: taskExecutor
1289
1322
  };
1290
1323
  }
1291
- async action(userPrompt, actionContext) {
1324
+ async action(userPrompt, actionContext, opts) {
1292
1325
  const taskExecutor = new import_misoai_core.Executor(taskTitleStr("Action", userPrompt), {
1293
1326
  onTaskStart: this.onTaskStartCallback
1294
1327
  });
@@ -1313,7 +1346,7 @@ var PageTaskExecutor = class {
1313
1346
  yamlFlow.push(...planResult.yamlFlow || []);
1314
1347
  let executables;
1315
1348
  try {
1316
- executables = await this.convertPlanToExecutable(plans);
1349
+ executables = await this.convertPlanToExecutable(plans, opts);
1317
1350
  taskExecutor.append(executables.tasks);
1318
1351
  } catch (error) {
1319
1352
  return this.appendErrorPlan(
@@ -1351,7 +1384,7 @@ var PageTaskExecutor = class {
1351
1384
  executor: taskExecutor
1352
1385
  };
1353
1386
  }
1354
- async actionToGoal(userPrompt) {
1387
+ async actionToGoal(userPrompt, opts) {
1355
1388
  const taskExecutor = new import_misoai_core.Executor(taskTitleStr("Action", userPrompt), {
1356
1389
  onTaskStart: this.onTaskStartCallback
1357
1390
  });
@@ -1375,7 +1408,7 @@ var PageTaskExecutor = class {
1375
1408
  yamlFlow.push(...output.yamlFlow || []);
1376
1409
  let executables;
1377
1410
  try {
1378
- executables = await this.convertPlanToExecutable(plans);
1411
+ executables = await this.convertPlanToExecutable(plans, opts);
1379
1412
  taskExecutor.append(executables.tasks);
1380
1413
  } catch (error) {
1381
1414
  return this.appendErrorPlan(
@@ -1680,7 +1713,7 @@ var import_js_yaml3 = __toESM(require("js-yaml"));
1680
1713
  var import_semver = __toESM(require("semver"));
1681
1714
 
1682
1715
  // package.json
1683
- var version = "1.0.2";
1716
+ var version = "1.0.4";
1684
1717
 
1685
1718
  // src/common/task-cache.ts
1686
1719
  var debug3 = (0, import_logger3.getDebug)("cache");
@@ -2023,9 +2056,9 @@ var PageAgent = class {
2023
2056
  buildDetailedLocateParam(locatePrompt, opt) {
2024
2057
  (0, import_utils12.assert)(locatePrompt, "missing locate prompt");
2025
2058
  if (typeof opt === "object") {
2026
- const prompt = opt.prompt || locatePrompt;
2027
- const deepThink = opt.deepThink || false;
2028
- const cacheable = opt.cacheable || true;
2059
+ const prompt = opt.prompt ?? locatePrompt;
2060
+ const deepThink = opt.deepThink ?? false;
2061
+ const cacheable = opt.cacheable ?? true;
2029
2062
  return {
2030
2063
  prompt,
2031
2064
  deepThink,
@@ -2044,7 +2077,8 @@ var PageAgent = class {
2044
2077
  const plans = buildPlans("Tap", detailedLocateParam);
2045
2078
  const { executor, output } = await this.taskExecutor.runPlans(
2046
2079
  taskTitleStr("Tap", locateParamStr(detailedLocateParam)),
2047
- plans
2080
+ plans,
2081
+ { cacheable: opt?.cacheable }
2048
2082
  );
2049
2083
  const metadata = this.afterTaskRunning(executor);
2050
2084
  return {
@@ -2060,7 +2094,8 @@ var PageAgent = class {
2060
2094
  const plans = buildPlans("Hover", detailedLocateParam);
2061
2095
  const { executor, output } = await this.taskExecutor.runPlans(
2062
2096
  taskTitleStr("Hover", locateParamStr(detailedLocateParam)),
2063
- plans
2097
+ plans,
2098
+ { cacheable: opt?.cacheable }
2064
2099
  );
2065
2100
  const metadata = this.afterTaskRunning(executor);
2066
2101
  return {
@@ -2083,7 +2118,8 @@ var PageAgent = class {
2083
2118
  });
2084
2119
  const { executor, output } = await this.taskExecutor.runPlans(
2085
2120
  taskTitleStr("Input", locateParamStr(detailedLocateParam)),
2086
- plans
2121
+ plans,
2122
+ { cacheable: opt?.cacheable }
2087
2123
  );
2088
2124
  const metadata = this.afterTaskRunning(executor);
2089
2125
  return {
@@ -2099,7 +2135,8 @@ var PageAgent = class {
2099
2135
  });
2100
2136
  const { executor, output } = await this.taskExecutor.runPlans(
2101
2137
  taskTitleStr("KeyboardPress", locateParamStr(detailedLocateParam)),
2102
- plans
2138
+ plans,
2139
+ { cacheable: opt?.cacheable }
2103
2140
  );
2104
2141
  const metadata = this.afterTaskRunning(executor);
2105
2142
  return {
@@ -2113,7 +2150,8 @@ var PageAgent = class {
2113
2150
  const paramInTitle = locatePrompt ? `${locateParamStr(detailedLocateParam)} - ${scrollParamStr(scrollParam)}` : scrollParamStr(scrollParam);
2114
2151
  const { executor, output } = await this.taskExecutor.runPlans(
2115
2152
  taskTitleStr("Scroll", paramInTitle),
2116
- plans
2153
+ plans,
2154
+ { cacheable: opt?.cacheable }
2117
2155
  );
2118
2156
  const metadata = this.afterTaskRunning(executor);
2119
2157
  return {
@@ -2122,6 +2160,19 @@ var PageAgent = class {
2122
2160
  };
2123
2161
  }
2124
2162
  async aiAction(taskPrompt, opt) {
2163
+ try {
2164
+ const aiModel = await import("misoai-core/ai-model");
2165
+ const contextStore = aiModel.getContextStore();
2166
+ const processedPrompt = contextStore.replaceAllReferences(taskPrompt, "action");
2167
+ contextStore.addStep({
2168
+ type: "action",
2169
+ summary: `Action: ${processedPrompt}`,
2170
+ prompt: processedPrompt
2171
+ });
2172
+ taskPrompt = processedPrompt;
2173
+ } catch (error) {
2174
+ debug4("Context store not available:", error);
2175
+ }
2125
2176
  const cacheable = opt?.cacheable;
2126
2177
  const isVlmUiTars = (0, import_env2.vlLocateMode)() === "vlm-ui-tars";
2127
2178
  const matchedCache = isVlmUiTars || cacheable === false ? void 0 : this.taskCache?.matchPlanCache(taskPrompt);
@@ -2139,7 +2190,9 @@ var PageAgent = class {
2139
2190
  metadata: metadata2
2140
2191
  };
2141
2192
  }
2142
- const { output, executor } = await (isVlmUiTars ? this.taskExecutor.actionToGoal(taskPrompt) : this.taskExecutor.action(taskPrompt, this.opts.aiActionContext));
2193
+ const { output, executor } = await (isVlmUiTars ? this.taskExecutor.actionToGoal(taskPrompt, { cacheable }) : this.taskExecutor.action(taskPrompt, this.opts.aiActionContext, {
2194
+ cacheable
2195
+ }));
2143
2196
  if (this.taskCache && output?.yamlFlow && cacheable !== false) {
2144
2197
  const yamlContent = {
2145
2198
  tasks: [
@@ -2166,7 +2219,63 @@ var PageAgent = class {
2166
2219
  };
2167
2220
  }
2168
2221
  async aiQuery(demand) {
2169
- const { output, executor } = await this.taskExecutor.query(demand);
2222
+ let processedDemand = demand;
2223
+ let storageKey;
2224
+ try {
2225
+ const aiModel = await import("misoai-core/ai-model");
2226
+ const contextStore = aiModel.getContextStore();
2227
+ if (typeof demand === "string") {
2228
+ const storageInstruction = contextStore.parseStorageInstruction(demand);
2229
+ if (storageInstruction) {
2230
+ storageKey = storageInstruction.key;
2231
+ processedDemand = storageInstruction.cleanText;
2232
+ contextStore._pendingAliases = storageInstruction.aliases;
2233
+ } else {
2234
+ const storageMatch = demand.match(/store\s+(?:as\s+)?(\w+)/i);
2235
+ if (storageMatch) {
2236
+ storageKey = storageMatch[1];
2237
+ processedDemand = demand.replace(/,?\s*store\s+(?:as\s+)?\w+/i, "").trim();
2238
+ }
2239
+ }
2240
+ }
2241
+ } catch (error) {
2242
+ debug4("Context store not available:", error);
2243
+ }
2244
+ const { output, executor } = await this.taskExecutor.query(processedDemand);
2245
+ if (storageKey && output) {
2246
+ try {
2247
+ const aiModel = await import("misoai-core/ai-model");
2248
+ const contextStore = aiModel.getContextStore();
2249
+ const pendingAliases = contextStore._pendingAliases;
2250
+ if (pendingAliases) {
2251
+ contextStore.storeDataWithAliases(storageKey, output, pendingAliases, typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand));
2252
+ delete contextStore._pendingAliases;
2253
+ } else {
2254
+ contextStore.storeData(storageKey, output);
2255
+ }
2256
+ contextStore.addStep({
2257
+ type: "query",
2258
+ summary: `Query: ${typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)} (stored as ${storageKey})`,
2259
+ data: output,
2260
+ prompt: typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)
2261
+ });
2262
+ } catch (error) {
2263
+ debug4("Failed to store query result:", error);
2264
+ }
2265
+ } else {
2266
+ try {
2267
+ const aiModel = await import("misoai-core/ai-model");
2268
+ const contextStore = aiModel.getContextStore();
2269
+ contextStore.addStep({
2270
+ type: "query",
2271
+ summary: `Query: ${typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)}`,
2272
+ data: output,
2273
+ prompt: typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)
2274
+ });
2275
+ } catch (error) {
2276
+ debug4("Failed to add query step:", error);
2277
+ }
2278
+ }
2170
2279
  const metadata = this.afterTaskRunning(executor);
2171
2280
  return {
2172
2281
  result: output,
@@ -2261,7 +2370,8 @@ var PageAgent = class {
2261
2370
  const plans = buildPlans("Locate", detailedLocateParam);
2262
2371
  const { executor, output } = await this.taskExecutor.runPlans(
2263
2372
  taskTitleStr("Locate", locateParamStr(detailedLocateParam)),
2264
- plans
2373
+ plans,
2374
+ { cacheable: opt?.cacheable }
2265
2375
  );
2266
2376
  const metadata = this.afterTaskRunning(executor);
2267
2377
  const { element } = output;
@@ -2275,6 +2385,19 @@ var PageAgent = class {
2275
2385
  };
2276
2386
  }
2277
2387
  async aiAssert(assertion, msg, opt) {
2388
+ let processedAssertion = assertion;
2389
+ try {
2390
+ const aiModel = await import("misoai-core/ai-model");
2391
+ const contextStore = aiModel.getContextStore();
2392
+ processedAssertion = contextStore.replaceAllReferences(assertion, "assertion");
2393
+ contextStore.addStep({
2394
+ type: "assertion",
2395
+ summary: `Assertion: ${processedAssertion}`,
2396
+ prompt: processedAssertion
2397
+ });
2398
+ } catch (error) {
2399
+ debug4("Context store not available:", error);
2400
+ }
2278
2401
  let currentUrl = "";
2279
2402
  if (this.page.url) {
2280
2403
  try {
@@ -2282,7 +2405,7 @@ var PageAgent = class {
2282
2405
  } catch (e) {
2283
2406
  }
2284
2407
  }
2285
- const assertionWithContext = currentUrl ? `For the page at URL "${currentUrl}", ${assertion}` : assertion;
2408
+ const assertionWithContext = currentUrl ? `For the page at URL "${currentUrl}", ${processedAssertion}` : processedAssertion;
2286
2409
  const { output, executor } = await this.taskExecutor.assert(assertionWithContext);
2287
2410
  const metadata = this.afterTaskRunning(executor, true);
2288
2411
  if (output && opt?.keepRawResponse) {
@@ -2508,7 +2631,7 @@ var import_constants4 = require("misoai-shared/constants");
2508
2631
  var import_utils15 = require("misoai-core/utils");
2509
2632
  var import_constants3 = require("misoai-shared/constants");
2510
2633
  var import_extractor2 = require("misoai-shared/extractor");
2511
- var import_fs2 = require("misoai-shared/fs");
2634
+ var import_fs = require("misoai-shared/fs");
2512
2635
  var import_logger5 = require("misoai-shared/logger");
2513
2636
  var import_utils16 = require("misoai-shared/utils");
2514
2637
  var debugPage = (0, import_logger5.getDebug)("web:page");
@@ -2563,9 +2686,21 @@ var Page = class {
2563
2686
  debugPage("getElementsInfo end");
2564
2687
  return (0, import_extractor2.treeToList)(tree);
2565
2688
  }
2689
+ async getXpathsById(id) {
2690
+ const elementInfosScriptContent = (0, import_fs.getElementInfosScriptContent)();
2691
+ return this.evaluateJavaScript(
2692
+ `${elementInfosScriptContent}midscene_element_inspector.getXpathsById('${id}')`
2693
+ );
2694
+ }
2695
+ async getElementInfoByXpath(xpath) {
2696
+ const elementInfosScriptContent = (0, import_fs.getElementInfosScriptContent)();
2697
+ return this.evaluateJavaScript(
2698
+ `${elementInfosScriptContent}midscene_element_inspector.getElementInfoByXpath('${xpath}')`
2699
+ );
2700
+ }
2566
2701
  async getElementsNodeTree() {
2567
2702
  await this.waitForNavigation();
2568
- const scripts = await (0, import_fs2.getExtraReturnLogic)(true);
2703
+ const scripts = await (0, import_fs.getExtraReturnLogic)(true);
2569
2704
  (0, import_utils16.assert)(scripts, "scripts should be set before writing report in browser");
2570
2705
  const captureElementSnapshot = await this.evaluate(scripts);
2571
2706
  return captureElementSnapshot;