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
@@ -126,7 +126,9 @@ var ScriptPlayer = class {
126
126
  typeof prompt === "string",
127
127
  "prompt for aiAction must be a string"
128
128
  );
129
- await agent.aiAction(prompt);
129
+ await agent.aiAction(prompt, {
130
+ cacheable: actionTask.cacheable
131
+ });
130
132
  } else if ("aiAssert" in flowItem) {
131
133
  const assertTask = flowItem;
132
134
  const prompt = assertTask.aiAssert;
@@ -328,8 +330,24 @@ function interpolateEnvVars(content) {
328
330
  });
329
331
  }
330
332
  function parseYamlScript(content, filePath, ignoreCheckingTarget) {
331
- const interpolatedContent = interpolateEnvVars(content);
332
- const obj = import_js_yaml2.default.load(interpolatedContent);
333
+ let processedContent = content;
334
+ if (content.indexOf("android") !== -1 && content.match(/deviceId:\s*(\d+)/)) {
335
+ let matchedDeviceId;
336
+ processedContent = content.replace(
337
+ /deviceId:\s*(\d+)/g,
338
+ (match, deviceId) => {
339
+ matchedDeviceId = deviceId;
340
+ return `deviceId: '${deviceId}'`;
341
+ }
342
+ );
343
+ console.warn(
344
+ `please use string-style deviceId in yaml script, for example: deviceId: "${matchedDeviceId}"`
345
+ );
346
+ }
347
+ const interpolatedContent = interpolateEnvVars(processedContent);
348
+ const obj = import_js_yaml2.default.load(interpolatedContent, {
349
+ schema: import_js_yaml2.default.JSON_SCHEMA
350
+ });
333
351
  const pathTip = filePath ? `, failed to load ${filePath}` : "";
334
352
  const android = typeof obj.android !== "undefined" ? Object.assign({}, obj.android || {}) : void 0;
335
353
  const webConfig = obj.web || obj.target;
@@ -370,7 +388,6 @@ var import_misoai_core = require("misoai-core");
370
388
  var import_ai_model2 = require("misoai-core/ai-model");
371
389
  var import_utils5 = require("misoai-core/utils");
372
390
  var import_constants = require("misoai-shared/constants");
373
- var import_fs = require("misoai-shared/fs");
374
391
  var import_logger = require("misoai-shared/logger");
375
392
  var import_utils6 = require("misoai-shared/utils");
376
393
 
@@ -630,16 +647,18 @@ var PageTaskExecutor = class {
630
647
  );
631
648
  if (info?.id) {
632
649
  elementId = info.id;
650
+ } else {
651
+ debug(
652
+ "no element id found for position node, will not update cache",
653
+ element
654
+ );
633
655
  }
634
656
  }
635
657
  if (!elementId) {
636
658
  return void 0;
637
659
  }
638
660
  try {
639
- const elementInfosScriptContent = (0, import_fs.getElementInfosScriptContent)();
640
- const result = await this.page.evaluateJavaScript?.(
641
- `${elementInfosScriptContent}midscene_element_inspector.getXpathsById('${elementId}')`
642
- );
661
+ const result = await this.page.getXpathsById(elementId);
643
662
  return result;
644
663
  } catch (error) {
645
664
  debug("getXpathsById error: ", error);
@@ -678,7 +697,7 @@ var PageTaskExecutor = class {
678
697
  };
679
698
  return taskWithScreenshot;
680
699
  }
681
- async convertPlanToExecutable(plans) {
700
+ async convertPlanToExecutable(plans, opts) {
682
701
  const tasks = [];
683
702
  plans.forEach((plan2) => {
684
703
  if (plan2.type === "Locate") {
@@ -688,7 +707,10 @@ var PageTaskExecutor = class {
688
707
  const taskFind = {
689
708
  type: "Insight",
690
709
  subType: "Locate",
691
- param: plan2.locate || void 0,
710
+ param: plan2.locate ? {
711
+ ...plan2.locate,
712
+ cacheable: opts?.cacheable
713
+ } : void 0,
692
714
  thought: plan2.thought,
693
715
  locate: plan2.locate,
694
716
  executor: async (param, taskContext) => {
@@ -725,19 +747,21 @@ var PageTaskExecutor = class {
725
747
  let elementFromCache = null;
726
748
  try {
727
749
  if (xpaths?.length && this.taskCache?.isCacheResultUsed && param?.cacheable !== false) {
728
- const elementInfosScriptContent = (0, import_fs.getElementInfosScriptContent)();
729
- const element2 = await this.page.evaluateJavaScript?.(
730
- `${elementInfosScriptContent}midscene_element_inspector.getElementInfoByXpath('${xpaths[0]}')`
731
- );
732
- if (element2?.id) {
733
- elementFromCache = element2;
734
- debug("cache hit, prompt: %s", cachePrompt);
735
- cacheHitFlag = true;
736
- debug(
737
- "found a new new element with same xpath, xpath: %s, id: %s",
738
- xpaths[0],
739
- element2?.id
750
+ for (let i = 0; i < xpaths.length; i++) {
751
+ const element2 = await this.page.getElementInfoByXpath(
752
+ xpaths[i]
740
753
  );
754
+ if (element2?.id) {
755
+ elementFromCache = element2;
756
+ debug("cache hit, prompt: %s", cachePrompt);
757
+ cacheHitFlag = true;
758
+ debug(
759
+ "found a new new element with same xpath, xpath: %s, id: %s",
760
+ xpaths[i],
761
+ element2?.id
762
+ );
763
+ break;
764
+ }
741
765
  }
742
766
  }
743
767
  } catch (error) {
@@ -750,12 +774,14 @@ var PageTaskExecutor = class {
750
774
  context: pageContext
751
775
  })).element;
752
776
  const aiCost = Date.now() - startTime;
777
+ let currentXpaths;
753
778
  if (element && this.taskCache && !cacheHitFlag && param?.cacheable !== false) {
754
779
  const elementXpaths = await this.getElementXpath(
755
780
  pageContext,
756
781
  element
757
782
  );
758
- if (elementXpaths) {
783
+ if (elementXpaths?.length) {
784
+ currentXpaths = elementXpaths;
759
785
  this.taskCache.updateOrAppendCacheRecord(
760
786
  {
761
787
  type: "locate",
@@ -765,7 +791,11 @@ var PageTaskExecutor = class {
765
791
  locateCacheRecord
766
792
  );
767
793
  } else {
768
- debug("no xpaths found, will not update cache", cachePrompt);
794
+ debug(
795
+ "no xpaths found, will not update cache",
796
+ cachePrompt,
797
+ elementXpaths
798
+ );
769
799
  }
770
800
  }
771
801
  if (!element) {
@@ -777,7 +807,9 @@ var PageTaskExecutor = class {
777
807
  },
778
808
  pageContext,
779
809
  cache: {
780
- hit: cacheHitFlag
810
+ hit: cacheHitFlag,
811
+ originalXpaths: xpaths,
812
+ currentXpaths
781
813
  },
782
814
  aiCost
783
815
  };
@@ -1145,6 +1177,7 @@ var PageTaskExecutor = class {
1145
1177
  sleep: sleep3
1146
1178
  } = planResult;
1147
1179
  executorContext.task.log = {
1180
+ ...executorContext.task.log || {},
1148
1181
  rawResponse
1149
1182
  };
1150
1183
  executorContext.task.usage = usage;
@@ -1269,11 +1302,11 @@ var PageTaskExecutor = class {
1269
1302
  };
1270
1303
  return task;
1271
1304
  }
1272
- async runPlans(title, plans) {
1305
+ async runPlans(title, plans, opts) {
1273
1306
  const taskExecutor = new import_misoai_core.Executor(title, {
1274
1307
  onTaskStart: this.onTaskStartCallback
1275
1308
  });
1276
- const { tasks } = await this.convertPlanToExecutable(plans);
1309
+ const { tasks } = await this.convertPlanToExecutable(plans, opts);
1277
1310
  await taskExecutor.append(tasks);
1278
1311
  const result = await taskExecutor.flush();
1279
1312
  return {
@@ -1281,7 +1314,7 @@ var PageTaskExecutor = class {
1281
1314
  executor: taskExecutor
1282
1315
  };
1283
1316
  }
1284
- async action(userPrompt, actionContext) {
1317
+ async action(userPrompt, actionContext, opts) {
1285
1318
  const taskExecutor = new import_misoai_core.Executor(taskTitleStr("Action", userPrompt), {
1286
1319
  onTaskStart: this.onTaskStartCallback
1287
1320
  });
@@ -1306,7 +1339,7 @@ var PageTaskExecutor = class {
1306
1339
  yamlFlow.push(...planResult.yamlFlow || []);
1307
1340
  let executables;
1308
1341
  try {
1309
- executables = await this.convertPlanToExecutable(plans);
1342
+ executables = await this.convertPlanToExecutable(plans, opts);
1310
1343
  taskExecutor.append(executables.tasks);
1311
1344
  } catch (error) {
1312
1345
  return this.appendErrorPlan(
@@ -1344,7 +1377,7 @@ var PageTaskExecutor = class {
1344
1377
  executor: taskExecutor
1345
1378
  };
1346
1379
  }
1347
- async actionToGoal(userPrompt) {
1380
+ async actionToGoal(userPrompt, opts) {
1348
1381
  const taskExecutor = new import_misoai_core.Executor(taskTitleStr("Action", userPrompt), {
1349
1382
  onTaskStart: this.onTaskStartCallback
1350
1383
  });
@@ -1368,7 +1401,7 @@ var PageTaskExecutor = class {
1368
1401
  yamlFlow.push(...output.yamlFlow || []);
1369
1402
  let executables;
1370
1403
  try {
1371
- executables = await this.convertPlanToExecutable(plans);
1404
+ executables = await this.convertPlanToExecutable(plans, opts);
1372
1405
  taskExecutor.append(executables.tasks);
1373
1406
  } catch (error) {
1374
1407
  return this.appendErrorPlan(
@@ -1673,7 +1706,7 @@ var import_js_yaml3 = __toESM(require("js-yaml"));
1673
1706
  var import_semver = __toESM(require("semver"));
1674
1707
 
1675
1708
  // package.json
1676
- var version = "1.0.2";
1709
+ var version = "1.0.4";
1677
1710
 
1678
1711
  // src/common/task-cache.ts
1679
1712
  var debug3 = (0, import_logger3.getDebug)("cache");
@@ -2016,9 +2049,9 @@ var PageAgent = class {
2016
2049
  buildDetailedLocateParam(locatePrompt, opt) {
2017
2050
  (0, import_utils12.assert)(locatePrompt, "missing locate prompt");
2018
2051
  if (typeof opt === "object") {
2019
- const prompt = opt.prompt || locatePrompt;
2020
- const deepThink = opt.deepThink || false;
2021
- const cacheable = opt.cacheable || true;
2052
+ const prompt = opt.prompt ?? locatePrompt;
2053
+ const deepThink = opt.deepThink ?? false;
2054
+ const cacheable = opt.cacheable ?? true;
2022
2055
  return {
2023
2056
  prompt,
2024
2057
  deepThink,
@@ -2037,7 +2070,8 @@ var PageAgent = class {
2037
2070
  const plans = buildPlans("Tap", detailedLocateParam);
2038
2071
  const { executor, output } = await this.taskExecutor.runPlans(
2039
2072
  taskTitleStr("Tap", locateParamStr(detailedLocateParam)),
2040
- plans
2073
+ plans,
2074
+ { cacheable: opt?.cacheable }
2041
2075
  );
2042
2076
  const metadata = this.afterTaskRunning(executor);
2043
2077
  return {
@@ -2053,7 +2087,8 @@ var PageAgent = class {
2053
2087
  const plans = buildPlans("Hover", detailedLocateParam);
2054
2088
  const { executor, output } = await this.taskExecutor.runPlans(
2055
2089
  taskTitleStr("Hover", locateParamStr(detailedLocateParam)),
2056
- plans
2090
+ plans,
2091
+ { cacheable: opt?.cacheable }
2057
2092
  );
2058
2093
  const metadata = this.afterTaskRunning(executor);
2059
2094
  return {
@@ -2076,7 +2111,8 @@ var PageAgent = class {
2076
2111
  });
2077
2112
  const { executor, output } = await this.taskExecutor.runPlans(
2078
2113
  taskTitleStr("Input", locateParamStr(detailedLocateParam)),
2079
- plans
2114
+ plans,
2115
+ { cacheable: opt?.cacheable }
2080
2116
  );
2081
2117
  const metadata = this.afterTaskRunning(executor);
2082
2118
  return {
@@ -2092,7 +2128,8 @@ var PageAgent = class {
2092
2128
  });
2093
2129
  const { executor, output } = await this.taskExecutor.runPlans(
2094
2130
  taskTitleStr("KeyboardPress", locateParamStr(detailedLocateParam)),
2095
- plans
2131
+ plans,
2132
+ { cacheable: opt?.cacheable }
2096
2133
  );
2097
2134
  const metadata = this.afterTaskRunning(executor);
2098
2135
  return {
@@ -2106,7 +2143,8 @@ var PageAgent = class {
2106
2143
  const paramInTitle = locatePrompt ? `${locateParamStr(detailedLocateParam)} - ${scrollParamStr(scrollParam)}` : scrollParamStr(scrollParam);
2107
2144
  const { executor, output } = await this.taskExecutor.runPlans(
2108
2145
  taskTitleStr("Scroll", paramInTitle),
2109
- plans
2146
+ plans,
2147
+ { cacheable: opt?.cacheable }
2110
2148
  );
2111
2149
  const metadata = this.afterTaskRunning(executor);
2112
2150
  return {
@@ -2115,6 +2153,19 @@ var PageAgent = class {
2115
2153
  };
2116
2154
  }
2117
2155
  async aiAction(taskPrompt, opt) {
2156
+ try {
2157
+ const aiModel = await import("misoai-core/ai-model");
2158
+ const contextStore = aiModel.getContextStore();
2159
+ const processedPrompt = contextStore.replaceAllReferences(taskPrompt, "action");
2160
+ contextStore.addStep({
2161
+ type: "action",
2162
+ summary: `Action: ${processedPrompt}`,
2163
+ prompt: processedPrompt
2164
+ });
2165
+ taskPrompt = processedPrompt;
2166
+ } catch (error) {
2167
+ debug4("Context store not available:", error);
2168
+ }
2118
2169
  const cacheable = opt?.cacheable;
2119
2170
  const isVlmUiTars = (0, import_env2.vlLocateMode)() === "vlm-ui-tars";
2120
2171
  const matchedCache = isVlmUiTars || cacheable === false ? void 0 : this.taskCache?.matchPlanCache(taskPrompt);
@@ -2132,7 +2183,9 @@ var PageAgent = class {
2132
2183
  metadata: metadata2
2133
2184
  };
2134
2185
  }
2135
- const { output, executor } = await (isVlmUiTars ? this.taskExecutor.actionToGoal(taskPrompt) : this.taskExecutor.action(taskPrompt, this.opts.aiActionContext));
2186
+ const { output, executor } = await (isVlmUiTars ? this.taskExecutor.actionToGoal(taskPrompt, { cacheable }) : this.taskExecutor.action(taskPrompt, this.opts.aiActionContext, {
2187
+ cacheable
2188
+ }));
2136
2189
  if (this.taskCache && output?.yamlFlow && cacheable !== false) {
2137
2190
  const yamlContent = {
2138
2191
  tasks: [
@@ -2159,7 +2212,63 @@ var PageAgent = class {
2159
2212
  };
2160
2213
  }
2161
2214
  async aiQuery(demand) {
2162
- const { output, executor } = await this.taskExecutor.query(demand);
2215
+ let processedDemand = demand;
2216
+ let storageKey;
2217
+ try {
2218
+ const aiModel = await import("misoai-core/ai-model");
2219
+ const contextStore = aiModel.getContextStore();
2220
+ if (typeof demand === "string") {
2221
+ const storageInstruction = contextStore.parseStorageInstruction(demand);
2222
+ if (storageInstruction) {
2223
+ storageKey = storageInstruction.key;
2224
+ processedDemand = storageInstruction.cleanText;
2225
+ contextStore._pendingAliases = storageInstruction.aliases;
2226
+ } else {
2227
+ const storageMatch = demand.match(/store\s+(?:as\s+)?(\w+)/i);
2228
+ if (storageMatch) {
2229
+ storageKey = storageMatch[1];
2230
+ processedDemand = demand.replace(/,?\s*store\s+(?:as\s+)?\w+/i, "").trim();
2231
+ }
2232
+ }
2233
+ }
2234
+ } catch (error) {
2235
+ debug4("Context store not available:", error);
2236
+ }
2237
+ const { output, executor } = await this.taskExecutor.query(processedDemand);
2238
+ if (storageKey && output) {
2239
+ try {
2240
+ const aiModel = await import("misoai-core/ai-model");
2241
+ const contextStore = aiModel.getContextStore();
2242
+ const pendingAliases = contextStore._pendingAliases;
2243
+ if (pendingAliases) {
2244
+ contextStore.storeDataWithAliases(storageKey, output, pendingAliases, typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand));
2245
+ delete contextStore._pendingAliases;
2246
+ } else {
2247
+ contextStore.storeData(storageKey, output);
2248
+ }
2249
+ contextStore.addStep({
2250
+ type: "query",
2251
+ summary: `Query: ${typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)} (stored as ${storageKey})`,
2252
+ data: output,
2253
+ prompt: typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)
2254
+ });
2255
+ } catch (error) {
2256
+ debug4("Failed to store query result:", error);
2257
+ }
2258
+ } else {
2259
+ try {
2260
+ const aiModel = await import("misoai-core/ai-model");
2261
+ const contextStore = aiModel.getContextStore();
2262
+ contextStore.addStep({
2263
+ type: "query",
2264
+ summary: `Query: ${typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)}`,
2265
+ data: output,
2266
+ prompt: typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)
2267
+ });
2268
+ } catch (error) {
2269
+ debug4("Failed to add query step:", error);
2270
+ }
2271
+ }
2163
2272
  const metadata = this.afterTaskRunning(executor);
2164
2273
  return {
2165
2274
  result: output,
@@ -2254,7 +2363,8 @@ var PageAgent = class {
2254
2363
  const plans = buildPlans("Locate", detailedLocateParam);
2255
2364
  const { executor, output } = await this.taskExecutor.runPlans(
2256
2365
  taskTitleStr("Locate", locateParamStr(detailedLocateParam)),
2257
- plans
2366
+ plans,
2367
+ { cacheable: opt?.cacheable }
2258
2368
  );
2259
2369
  const metadata = this.afterTaskRunning(executor);
2260
2370
  const { element } = output;
@@ -2268,6 +2378,19 @@ var PageAgent = class {
2268
2378
  };
2269
2379
  }
2270
2380
  async aiAssert(assertion, msg, opt) {
2381
+ let processedAssertion = assertion;
2382
+ try {
2383
+ const aiModel = await import("misoai-core/ai-model");
2384
+ const contextStore = aiModel.getContextStore();
2385
+ processedAssertion = contextStore.replaceAllReferences(assertion, "assertion");
2386
+ contextStore.addStep({
2387
+ type: "assertion",
2388
+ summary: `Assertion: ${processedAssertion}`,
2389
+ prompt: processedAssertion
2390
+ });
2391
+ } catch (error) {
2392
+ debug4("Context store not available:", error);
2393
+ }
2271
2394
  let currentUrl = "";
2272
2395
  if (this.page.url) {
2273
2396
  try {
@@ -2275,7 +2398,7 @@ var PageAgent = class {
2275
2398
  } catch (e) {
2276
2399
  }
2277
2400
  }
2278
- const assertionWithContext = currentUrl ? `For the page at URL "${currentUrl}", ${assertion}` : assertion;
2401
+ const assertionWithContext = currentUrl ? `For the page at URL "${currentUrl}", ${processedAssertion}` : processedAssertion;
2279
2402
  const { output, executor } = await this.taskExecutor.assert(assertionWithContext);
2280
2403
  const metadata = this.afterTaskRunning(executor, true);
2281
2404
  if (output && opt?.keepRawResponse) {
@@ -2501,7 +2624,7 @@ var import_constants4 = require("misoai-shared/constants");
2501
2624
  var import_utils15 = require("misoai-core/utils");
2502
2625
  var import_constants3 = require("misoai-shared/constants");
2503
2626
  var import_extractor2 = require("misoai-shared/extractor");
2504
- var import_fs2 = require("misoai-shared/fs");
2627
+ var import_fs = require("misoai-shared/fs");
2505
2628
  var import_logger5 = require("misoai-shared/logger");
2506
2629
  var import_utils16 = require("misoai-shared/utils");
2507
2630
  var debugPage = (0, import_logger5.getDebug)("web:page");
@@ -2556,9 +2679,21 @@ var Page = class {
2556
2679
  debugPage("getElementsInfo end");
2557
2680
  return (0, import_extractor2.treeToList)(tree);
2558
2681
  }
2682
+ async getXpathsById(id) {
2683
+ const elementInfosScriptContent = (0, import_fs.getElementInfosScriptContent)();
2684
+ return this.evaluateJavaScript(
2685
+ `${elementInfosScriptContent}midscene_element_inspector.getXpathsById('${id}')`
2686
+ );
2687
+ }
2688
+ async getElementInfoByXpath(xpath) {
2689
+ const elementInfosScriptContent = (0, import_fs.getElementInfosScriptContent)();
2690
+ return this.evaluateJavaScript(
2691
+ `${elementInfosScriptContent}midscene_element_inspector.getElementInfoByXpath('${xpath}')`
2692
+ );
2693
+ }
2559
2694
  async getElementsNodeTree() {
2560
2695
  await this.waitForNavigation();
2561
- const scripts = await (0, import_fs2.getExtraReturnLogic)(true);
2696
+ const scripts = await (0, import_fs.getExtraReturnLogic)(true);
2562
2697
  (0, import_utils16.assert)(scripts, "scripts should be set before writing report in browser");
2563
2698
  const captureElementSnapshot = await this.evaluate(scripts);
2564
2699
  return captureElementSnapshot;