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/es/index.js CHANGED
@@ -88,7 +88,9 @@ var ScriptPlayer = class {
88
88
  typeof prompt === "string",
89
89
  "prompt for aiAction must be a string"
90
90
  );
91
- await agent.aiAction(prompt);
91
+ await agent.aiAction(prompt, {
92
+ cacheable: actionTask.cacheable
93
+ });
92
94
  } else if ("aiAssert" in flowItem) {
93
95
  const assertTask = flowItem;
94
96
  const prompt = assertTask.aiAssert;
@@ -290,8 +292,24 @@ function interpolateEnvVars(content) {
290
292
  });
291
293
  }
292
294
  function parseYamlScript(content, filePath, ignoreCheckingTarget) {
293
- const interpolatedContent = interpolateEnvVars(content);
294
- const obj = yaml2.load(interpolatedContent);
295
+ let processedContent = content;
296
+ if (content.indexOf("android") !== -1 && content.match(/deviceId:\s*(\d+)/)) {
297
+ let matchedDeviceId;
298
+ processedContent = content.replace(
299
+ /deviceId:\s*(\d+)/g,
300
+ (match, deviceId) => {
301
+ matchedDeviceId = deviceId;
302
+ return `deviceId: '${deviceId}'`;
303
+ }
304
+ );
305
+ console.warn(
306
+ `please use string-style deviceId in yaml script, for example: deviceId: "${matchedDeviceId}"`
307
+ );
308
+ }
309
+ const interpolatedContent = interpolateEnvVars(processedContent);
310
+ const obj = yaml2.load(interpolatedContent, {
311
+ schema: yaml2.JSON_SCHEMA
312
+ });
295
313
  const pathTip = filePath ? `, failed to load ${filePath}` : "";
296
314
  const android = typeof obj.android !== "undefined" ? Object.assign({}, obj.android || {}) : void 0;
297
315
  const webConfig = obj.web || obj.target;
@@ -347,7 +365,6 @@ import {
347
365
  } from "misoai-core/ai-model";
348
366
  import { sleep } from "misoai-core/utils";
349
367
  import { NodeType } from "misoai-shared/constants";
350
- import { getElementInfosScriptContent } from "misoai-shared/fs";
351
368
  import { getDebug } from "misoai-shared/logger";
352
369
  import { assert as assert4 } from "misoai-shared/utils";
353
370
 
@@ -612,16 +629,18 @@ var PageTaskExecutor = class {
612
629
  );
613
630
  if (info?.id) {
614
631
  elementId = info.id;
632
+ } else {
633
+ debug(
634
+ "no element id found for position node, will not update cache",
635
+ element
636
+ );
615
637
  }
616
638
  }
617
639
  if (!elementId) {
618
640
  return void 0;
619
641
  }
620
642
  try {
621
- const elementInfosScriptContent = getElementInfosScriptContent();
622
- const result = await this.page.evaluateJavaScript?.(
623
- `${elementInfosScriptContent}midscene_element_inspector.getXpathsById('${elementId}')`
624
- );
643
+ const result = await this.page.getXpathsById(elementId);
625
644
  return result;
626
645
  } catch (error) {
627
646
  debug("getXpathsById error: ", error);
@@ -660,7 +679,7 @@ var PageTaskExecutor = class {
660
679
  };
661
680
  return taskWithScreenshot;
662
681
  }
663
- async convertPlanToExecutable(plans) {
682
+ async convertPlanToExecutable(plans, opts) {
664
683
  const tasks = [];
665
684
  plans.forEach((plan2) => {
666
685
  if (plan2.type === "Locate") {
@@ -670,7 +689,10 @@ var PageTaskExecutor = class {
670
689
  const taskFind = {
671
690
  type: "Insight",
672
691
  subType: "Locate",
673
- param: plan2.locate || void 0,
692
+ param: plan2.locate ? {
693
+ ...plan2.locate,
694
+ cacheable: opts?.cacheable
695
+ } : void 0,
674
696
  thought: plan2.thought,
675
697
  locate: plan2.locate,
676
698
  executor: async (param, taskContext) => {
@@ -707,19 +729,21 @@ var PageTaskExecutor = class {
707
729
  let elementFromCache = null;
708
730
  try {
709
731
  if (xpaths?.length && this.taskCache?.isCacheResultUsed && param?.cacheable !== false) {
710
- const elementInfosScriptContent = getElementInfosScriptContent();
711
- const element2 = await this.page.evaluateJavaScript?.(
712
- `${elementInfosScriptContent}midscene_element_inspector.getElementInfoByXpath('${xpaths[0]}')`
713
- );
714
- if (element2?.id) {
715
- elementFromCache = element2;
716
- debug("cache hit, prompt: %s", cachePrompt);
717
- cacheHitFlag = true;
718
- debug(
719
- "found a new new element with same xpath, xpath: %s, id: %s",
720
- xpaths[0],
721
- element2?.id
732
+ for (let i = 0; i < xpaths.length; i++) {
733
+ const element2 = await this.page.getElementInfoByXpath(
734
+ xpaths[i]
722
735
  );
736
+ if (element2?.id) {
737
+ elementFromCache = element2;
738
+ debug("cache hit, prompt: %s", cachePrompt);
739
+ cacheHitFlag = true;
740
+ debug(
741
+ "found a new new element with same xpath, xpath: %s, id: %s",
742
+ xpaths[i],
743
+ element2?.id
744
+ );
745
+ break;
746
+ }
723
747
  }
724
748
  }
725
749
  } catch (error) {
@@ -732,12 +756,14 @@ var PageTaskExecutor = class {
732
756
  context: pageContext
733
757
  })).element;
734
758
  const aiCost = Date.now() - startTime;
759
+ let currentXpaths;
735
760
  if (element && this.taskCache && !cacheHitFlag && param?.cacheable !== false) {
736
761
  const elementXpaths = await this.getElementXpath(
737
762
  pageContext,
738
763
  element
739
764
  );
740
- if (elementXpaths) {
765
+ if (elementXpaths?.length) {
766
+ currentXpaths = elementXpaths;
741
767
  this.taskCache.updateOrAppendCacheRecord(
742
768
  {
743
769
  type: "locate",
@@ -747,7 +773,11 @@ var PageTaskExecutor = class {
747
773
  locateCacheRecord
748
774
  );
749
775
  } else {
750
- debug("no xpaths found, will not update cache", cachePrompt);
776
+ debug(
777
+ "no xpaths found, will not update cache",
778
+ cachePrompt,
779
+ elementXpaths
780
+ );
751
781
  }
752
782
  }
753
783
  if (!element) {
@@ -759,7 +789,9 @@ var PageTaskExecutor = class {
759
789
  },
760
790
  pageContext,
761
791
  cache: {
762
- hit: cacheHitFlag
792
+ hit: cacheHitFlag,
793
+ originalXpaths: xpaths,
794
+ currentXpaths
763
795
  },
764
796
  aiCost
765
797
  };
@@ -1127,6 +1159,7 @@ var PageTaskExecutor = class {
1127
1159
  sleep: sleep3
1128
1160
  } = planResult;
1129
1161
  executorContext.task.log = {
1162
+ ...executorContext.task.log || {},
1130
1163
  rawResponse
1131
1164
  };
1132
1165
  executorContext.task.usage = usage;
@@ -1251,11 +1284,11 @@ var PageTaskExecutor = class {
1251
1284
  };
1252
1285
  return task;
1253
1286
  }
1254
- async runPlans(title, plans) {
1287
+ async runPlans(title, plans, opts) {
1255
1288
  const taskExecutor = new Executor(title, {
1256
1289
  onTaskStart: this.onTaskStartCallback
1257
1290
  });
1258
- const { tasks } = await this.convertPlanToExecutable(plans);
1291
+ const { tasks } = await this.convertPlanToExecutable(plans, opts);
1259
1292
  await taskExecutor.append(tasks);
1260
1293
  const result = await taskExecutor.flush();
1261
1294
  return {
@@ -1263,7 +1296,7 @@ var PageTaskExecutor = class {
1263
1296
  executor: taskExecutor
1264
1297
  };
1265
1298
  }
1266
- async action(userPrompt, actionContext) {
1299
+ async action(userPrompt, actionContext, opts) {
1267
1300
  const taskExecutor = new Executor(taskTitleStr("Action", userPrompt), {
1268
1301
  onTaskStart: this.onTaskStartCallback
1269
1302
  });
@@ -1288,7 +1321,7 @@ var PageTaskExecutor = class {
1288
1321
  yamlFlow.push(...planResult.yamlFlow || []);
1289
1322
  let executables;
1290
1323
  try {
1291
- executables = await this.convertPlanToExecutable(plans);
1324
+ executables = await this.convertPlanToExecutable(plans, opts);
1292
1325
  taskExecutor.append(executables.tasks);
1293
1326
  } catch (error) {
1294
1327
  return this.appendErrorPlan(
@@ -1326,7 +1359,7 @@ var PageTaskExecutor = class {
1326
1359
  executor: taskExecutor
1327
1360
  };
1328
1361
  }
1329
- async actionToGoal(userPrompt) {
1362
+ async actionToGoal(userPrompt, opts) {
1330
1363
  const taskExecutor = new Executor(taskTitleStr("Action", userPrompt), {
1331
1364
  onTaskStart: this.onTaskStartCallback
1332
1365
  });
@@ -1350,7 +1383,7 @@ var PageTaskExecutor = class {
1350
1383
  yamlFlow.push(...output.yamlFlow || []);
1351
1384
  let executables;
1352
1385
  try {
1353
- executables = await this.convertPlanToExecutable(plans);
1386
+ executables = await this.convertPlanToExecutable(plans, opts);
1354
1387
  taskExecutor.append(executables.tasks);
1355
1388
  } catch (error) {
1356
1389
  return this.appendErrorPlan(
@@ -1655,7 +1688,7 @@ import yaml3 from "js-yaml";
1655
1688
  import semver from "semver";
1656
1689
 
1657
1690
  // package.json
1658
- var version = "1.0.2";
1691
+ var version = "1.0.4";
1659
1692
 
1660
1693
  // src/common/task-cache.ts
1661
1694
  var debug3 = getDebug3("cache");
@@ -1998,9 +2031,9 @@ var PageAgent = class {
1998
2031
  buildDetailedLocateParam(locatePrompt, opt) {
1999
2032
  assert7(locatePrompt, "missing locate prompt");
2000
2033
  if (typeof opt === "object") {
2001
- const prompt = opt.prompt || locatePrompt;
2002
- const deepThink = opt.deepThink || false;
2003
- const cacheable = opt.cacheable || true;
2034
+ const prompt = opt.prompt ?? locatePrompt;
2035
+ const deepThink = opt.deepThink ?? false;
2036
+ const cacheable = opt.cacheable ?? true;
2004
2037
  return {
2005
2038
  prompt,
2006
2039
  deepThink,
@@ -2019,7 +2052,8 @@ var PageAgent = class {
2019
2052
  const plans = buildPlans("Tap", detailedLocateParam);
2020
2053
  const { executor, output } = await this.taskExecutor.runPlans(
2021
2054
  taskTitleStr("Tap", locateParamStr(detailedLocateParam)),
2022
- plans
2055
+ plans,
2056
+ { cacheable: opt?.cacheable }
2023
2057
  );
2024
2058
  const metadata = this.afterTaskRunning(executor);
2025
2059
  return {
@@ -2035,7 +2069,8 @@ var PageAgent = class {
2035
2069
  const plans = buildPlans("Hover", detailedLocateParam);
2036
2070
  const { executor, output } = await this.taskExecutor.runPlans(
2037
2071
  taskTitleStr("Hover", locateParamStr(detailedLocateParam)),
2038
- plans
2072
+ plans,
2073
+ { cacheable: opt?.cacheable }
2039
2074
  );
2040
2075
  const metadata = this.afterTaskRunning(executor);
2041
2076
  return {
@@ -2058,7 +2093,8 @@ var PageAgent = class {
2058
2093
  });
2059
2094
  const { executor, output } = await this.taskExecutor.runPlans(
2060
2095
  taskTitleStr("Input", locateParamStr(detailedLocateParam)),
2061
- plans
2096
+ plans,
2097
+ { cacheable: opt?.cacheable }
2062
2098
  );
2063
2099
  const metadata = this.afterTaskRunning(executor);
2064
2100
  return {
@@ -2074,7 +2110,8 @@ var PageAgent = class {
2074
2110
  });
2075
2111
  const { executor, output } = await this.taskExecutor.runPlans(
2076
2112
  taskTitleStr("KeyboardPress", locateParamStr(detailedLocateParam)),
2077
- plans
2113
+ plans,
2114
+ { cacheable: opt?.cacheable }
2078
2115
  );
2079
2116
  const metadata = this.afterTaskRunning(executor);
2080
2117
  return {
@@ -2088,7 +2125,8 @@ var PageAgent = class {
2088
2125
  const paramInTitle = locatePrompt ? `${locateParamStr(detailedLocateParam)} - ${scrollParamStr(scrollParam)}` : scrollParamStr(scrollParam);
2089
2126
  const { executor, output } = await this.taskExecutor.runPlans(
2090
2127
  taskTitleStr("Scroll", paramInTitle),
2091
- plans
2128
+ plans,
2129
+ { cacheable: opt?.cacheable }
2092
2130
  );
2093
2131
  const metadata = this.afterTaskRunning(executor);
2094
2132
  return {
@@ -2097,6 +2135,19 @@ var PageAgent = class {
2097
2135
  };
2098
2136
  }
2099
2137
  async aiAction(taskPrompt, opt) {
2138
+ try {
2139
+ const aiModel = await import("misoai-core/ai-model");
2140
+ const contextStore = aiModel.getContextStore();
2141
+ const processedPrompt = contextStore.replaceAllReferences(taskPrompt, "action");
2142
+ contextStore.addStep({
2143
+ type: "action",
2144
+ summary: `Action: ${processedPrompt}`,
2145
+ prompt: processedPrompt
2146
+ });
2147
+ taskPrompt = processedPrompt;
2148
+ } catch (error) {
2149
+ debug4("Context store not available:", error);
2150
+ }
2100
2151
  const cacheable = opt?.cacheable;
2101
2152
  const isVlmUiTars = vlLocateMode() === "vlm-ui-tars";
2102
2153
  const matchedCache = isVlmUiTars || cacheable === false ? void 0 : this.taskCache?.matchPlanCache(taskPrompt);
@@ -2114,7 +2165,9 @@ var PageAgent = class {
2114
2165
  metadata: metadata2
2115
2166
  };
2116
2167
  }
2117
- const { output, executor } = await (isVlmUiTars ? this.taskExecutor.actionToGoal(taskPrompt) : this.taskExecutor.action(taskPrompt, this.opts.aiActionContext));
2168
+ const { output, executor } = await (isVlmUiTars ? this.taskExecutor.actionToGoal(taskPrompt, { cacheable }) : this.taskExecutor.action(taskPrompt, this.opts.aiActionContext, {
2169
+ cacheable
2170
+ }));
2118
2171
  if (this.taskCache && output?.yamlFlow && cacheable !== false) {
2119
2172
  const yamlContent = {
2120
2173
  tasks: [
@@ -2141,7 +2194,63 @@ var PageAgent = class {
2141
2194
  };
2142
2195
  }
2143
2196
  async aiQuery(demand) {
2144
- const { output, executor } = await this.taskExecutor.query(demand);
2197
+ let processedDemand = demand;
2198
+ let storageKey;
2199
+ try {
2200
+ const aiModel = await import("misoai-core/ai-model");
2201
+ const contextStore = aiModel.getContextStore();
2202
+ if (typeof demand === "string") {
2203
+ const storageInstruction = contextStore.parseStorageInstruction(demand);
2204
+ if (storageInstruction) {
2205
+ storageKey = storageInstruction.key;
2206
+ processedDemand = storageInstruction.cleanText;
2207
+ contextStore._pendingAliases = storageInstruction.aliases;
2208
+ } else {
2209
+ const storageMatch = demand.match(/store\s+(?:as\s+)?(\w+)/i);
2210
+ if (storageMatch) {
2211
+ storageKey = storageMatch[1];
2212
+ processedDemand = demand.replace(/,?\s*store\s+(?:as\s+)?\w+/i, "").trim();
2213
+ }
2214
+ }
2215
+ }
2216
+ } catch (error) {
2217
+ debug4("Context store not available:", error);
2218
+ }
2219
+ const { output, executor } = await this.taskExecutor.query(processedDemand);
2220
+ if (storageKey && output) {
2221
+ try {
2222
+ const aiModel = await import("misoai-core/ai-model");
2223
+ const contextStore = aiModel.getContextStore();
2224
+ const pendingAliases = contextStore._pendingAliases;
2225
+ if (pendingAliases) {
2226
+ contextStore.storeDataWithAliases(storageKey, output, pendingAliases, typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand));
2227
+ delete contextStore._pendingAliases;
2228
+ } else {
2229
+ contextStore.storeData(storageKey, output);
2230
+ }
2231
+ contextStore.addStep({
2232
+ type: "query",
2233
+ summary: `Query: ${typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)} (stored as ${storageKey})`,
2234
+ data: output,
2235
+ prompt: typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)
2236
+ });
2237
+ } catch (error) {
2238
+ debug4("Failed to store query result:", error);
2239
+ }
2240
+ } else {
2241
+ try {
2242
+ const aiModel = await import("misoai-core/ai-model");
2243
+ const contextStore = aiModel.getContextStore();
2244
+ contextStore.addStep({
2245
+ type: "query",
2246
+ summary: `Query: ${typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)}`,
2247
+ data: output,
2248
+ prompt: typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)
2249
+ });
2250
+ } catch (error) {
2251
+ debug4("Failed to add query step:", error);
2252
+ }
2253
+ }
2145
2254
  const metadata = this.afterTaskRunning(executor);
2146
2255
  return {
2147
2256
  result: output,
@@ -2236,7 +2345,8 @@ var PageAgent = class {
2236
2345
  const plans = buildPlans("Locate", detailedLocateParam);
2237
2346
  const { executor, output } = await this.taskExecutor.runPlans(
2238
2347
  taskTitleStr("Locate", locateParamStr(detailedLocateParam)),
2239
- plans
2348
+ plans,
2349
+ { cacheable: opt?.cacheable }
2240
2350
  );
2241
2351
  const metadata = this.afterTaskRunning(executor);
2242
2352
  const { element } = output;
@@ -2250,6 +2360,19 @@ var PageAgent = class {
2250
2360
  };
2251
2361
  }
2252
2362
  async aiAssert(assertion, msg, opt) {
2363
+ let processedAssertion = assertion;
2364
+ try {
2365
+ const aiModel = await import("misoai-core/ai-model");
2366
+ const contextStore = aiModel.getContextStore();
2367
+ processedAssertion = contextStore.replaceAllReferences(assertion, "assertion");
2368
+ contextStore.addStep({
2369
+ type: "assertion",
2370
+ summary: `Assertion: ${processedAssertion}`,
2371
+ prompt: processedAssertion
2372
+ });
2373
+ } catch (error) {
2374
+ debug4("Context store not available:", error);
2375
+ }
2253
2376
  let currentUrl = "";
2254
2377
  if (this.page.url) {
2255
2378
  try {
@@ -2257,7 +2380,7 @@ var PageAgent = class {
2257
2380
  } catch (e) {
2258
2381
  }
2259
2382
  }
2260
- const assertionWithContext = currentUrl ? `For the page at URL "${currentUrl}", ${assertion}` : assertion;
2383
+ const assertionWithContext = currentUrl ? `For the page at URL "${currentUrl}", ${processedAssertion}` : processedAssertion;
2261
2384
  const { output, executor } = await this.taskExecutor.assert(assertionWithContext);
2262
2385
  const metadata = this.afterTaskRunning(executor, true);
2263
2386
  if (output && opt?.keepRawResponse) {
@@ -2477,7 +2600,10 @@ ${errors}`);
2477
2600
  import { sleep as sleep2 } from "misoai-core/utils";
2478
2601
  import { DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT as DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT2 } from "misoai-shared/constants";
2479
2602
  import { treeToList as treeToList2 } from "misoai-shared/extractor";
2480
- import { getExtraReturnLogic } from "misoai-shared/fs";
2603
+ import {
2604
+ getElementInfosScriptContent,
2605
+ getExtraReturnLogic
2606
+ } from "misoai-shared/fs";
2481
2607
  import { getDebug as getDebug5 } from "misoai-shared/logger";
2482
2608
  import { assert as assert8 } from "misoai-shared/utils";
2483
2609
  var debugPage = getDebug5("web:page");
@@ -2532,6 +2658,18 @@ var Page = class {
2532
2658
  debugPage("getElementsInfo end");
2533
2659
  return treeToList2(tree);
2534
2660
  }
2661
+ async getXpathsById(id) {
2662
+ const elementInfosScriptContent = getElementInfosScriptContent();
2663
+ return this.evaluateJavaScript(
2664
+ `${elementInfosScriptContent}midscene_element_inspector.getXpathsById('${id}')`
2665
+ );
2666
+ }
2667
+ async getElementInfoByXpath(xpath) {
2668
+ const elementInfosScriptContent = getElementInfosScriptContent();
2669
+ return this.evaluateJavaScript(
2670
+ `${elementInfosScriptContent}midscene_element_inspector.getElementInfoByXpath('${xpath}')`
2671
+ );
2672
+ }
2535
2673
  async getElementsNodeTree() {
2536
2674
  await this.waitForNavigation();
2537
2675
  const scripts = await getExtraReturnLogic(true);