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
@@ -93,7 +93,9 @@ var ScriptPlayer = class {
93
93
  typeof prompt === "string",
94
94
  "prompt for aiAction must be a string"
95
95
  );
96
- await agent.aiAction(prompt);
96
+ await agent.aiAction(prompt, {
97
+ cacheable: actionTask.cacheable
98
+ });
97
99
  } else if ("aiAssert" in flowItem) {
98
100
  const assertTask = flowItem;
99
101
  const prompt = assertTask.aiAssert;
@@ -295,8 +297,24 @@ function interpolateEnvVars(content) {
295
297
  });
296
298
  }
297
299
  function parseYamlScript(content, filePath, ignoreCheckingTarget) {
298
- const interpolatedContent = interpolateEnvVars(content);
299
- const obj = yaml2.load(interpolatedContent);
300
+ let processedContent = content;
301
+ if (content.indexOf("android") !== -1 && content.match(/deviceId:\s*(\d+)/)) {
302
+ let matchedDeviceId;
303
+ processedContent = content.replace(
304
+ /deviceId:\s*(\d+)/g,
305
+ (match, deviceId) => {
306
+ matchedDeviceId = deviceId;
307
+ return `deviceId: '${deviceId}'`;
308
+ }
309
+ );
310
+ console.warn(
311
+ `please use string-style deviceId in yaml script, for example: deviceId: "${matchedDeviceId}"`
312
+ );
313
+ }
314
+ const interpolatedContent = interpolateEnvVars(processedContent);
315
+ const obj = yaml2.load(interpolatedContent, {
316
+ schema: yaml2.JSON_SCHEMA
317
+ });
300
318
  const pathTip = filePath ? `, failed to load ${filePath}` : "";
301
319
  const android = typeof obj.android !== "undefined" ? Object.assign({}, obj.android || {}) : void 0;
302
320
  const webConfig = obj.web || obj.target;
@@ -352,7 +370,6 @@ import {
352
370
  } from "misoai-core/ai-model";
353
371
  import { sleep } from "misoai-core/utils";
354
372
  import { NodeType } from "misoai-shared/constants";
355
- import { getElementInfosScriptContent } from "misoai-shared/fs";
356
373
  import { getDebug } from "misoai-shared/logger";
357
374
  import { assert as assert4 } from "misoai-shared/utils";
358
375
 
@@ -617,16 +634,18 @@ var PageTaskExecutor = class {
617
634
  );
618
635
  if (info?.id) {
619
636
  elementId = info.id;
637
+ } else {
638
+ debug(
639
+ "no element id found for position node, will not update cache",
640
+ element
641
+ );
620
642
  }
621
643
  }
622
644
  if (!elementId) {
623
645
  return void 0;
624
646
  }
625
647
  try {
626
- const elementInfosScriptContent = getElementInfosScriptContent();
627
- const result = await this.page.evaluateJavaScript?.(
628
- `${elementInfosScriptContent}midscene_element_inspector.getXpathsById('${elementId}')`
629
- );
648
+ const result = await this.page.getXpathsById(elementId);
630
649
  return result;
631
650
  } catch (error) {
632
651
  debug("getXpathsById error: ", error);
@@ -665,7 +684,7 @@ var PageTaskExecutor = class {
665
684
  };
666
685
  return taskWithScreenshot;
667
686
  }
668
- async convertPlanToExecutable(plans) {
687
+ async convertPlanToExecutable(plans, opts) {
669
688
  const tasks = [];
670
689
  plans.forEach((plan2) => {
671
690
  if (plan2.type === "Locate") {
@@ -675,7 +694,10 @@ var PageTaskExecutor = class {
675
694
  const taskFind = {
676
695
  type: "Insight",
677
696
  subType: "Locate",
678
- param: plan2.locate || void 0,
697
+ param: plan2.locate ? {
698
+ ...plan2.locate,
699
+ cacheable: opts?.cacheable
700
+ } : void 0,
679
701
  thought: plan2.thought,
680
702
  locate: plan2.locate,
681
703
  executor: async (param, taskContext) => {
@@ -712,19 +734,21 @@ var PageTaskExecutor = class {
712
734
  let elementFromCache = null;
713
735
  try {
714
736
  if (xpaths?.length && this.taskCache?.isCacheResultUsed && param?.cacheable !== false) {
715
- const elementInfosScriptContent = getElementInfosScriptContent();
716
- const element2 = await this.page.evaluateJavaScript?.(
717
- `${elementInfosScriptContent}midscene_element_inspector.getElementInfoByXpath('${xpaths[0]}')`
718
- );
719
- if (element2?.id) {
720
- elementFromCache = element2;
721
- debug("cache hit, prompt: %s", cachePrompt);
722
- cacheHitFlag = true;
723
- debug(
724
- "found a new new element with same xpath, xpath: %s, id: %s",
725
- xpaths[0],
726
- element2?.id
737
+ for (let i = 0; i < xpaths.length; i++) {
738
+ const element2 = await this.page.getElementInfoByXpath(
739
+ xpaths[i]
727
740
  );
741
+ if (element2?.id) {
742
+ elementFromCache = element2;
743
+ debug("cache hit, prompt: %s", cachePrompt);
744
+ cacheHitFlag = true;
745
+ debug(
746
+ "found a new new element with same xpath, xpath: %s, id: %s",
747
+ xpaths[i],
748
+ element2?.id
749
+ );
750
+ break;
751
+ }
728
752
  }
729
753
  }
730
754
  } catch (error) {
@@ -737,12 +761,14 @@ var PageTaskExecutor = class {
737
761
  context: pageContext
738
762
  })).element;
739
763
  const aiCost = Date.now() - startTime;
764
+ let currentXpaths;
740
765
  if (element && this.taskCache && !cacheHitFlag && param?.cacheable !== false) {
741
766
  const elementXpaths = await this.getElementXpath(
742
767
  pageContext,
743
768
  element
744
769
  );
745
- if (elementXpaths) {
770
+ if (elementXpaths?.length) {
771
+ currentXpaths = elementXpaths;
746
772
  this.taskCache.updateOrAppendCacheRecord(
747
773
  {
748
774
  type: "locate",
@@ -752,7 +778,11 @@ var PageTaskExecutor = class {
752
778
  locateCacheRecord
753
779
  );
754
780
  } else {
755
- debug("no xpaths found, will not update cache", cachePrompt);
781
+ debug(
782
+ "no xpaths found, will not update cache",
783
+ cachePrompt,
784
+ elementXpaths
785
+ );
756
786
  }
757
787
  }
758
788
  if (!element) {
@@ -764,7 +794,9 @@ var PageTaskExecutor = class {
764
794
  },
765
795
  pageContext,
766
796
  cache: {
767
- hit: cacheHitFlag
797
+ hit: cacheHitFlag,
798
+ originalXpaths: xpaths,
799
+ currentXpaths
768
800
  },
769
801
  aiCost
770
802
  };
@@ -1132,6 +1164,7 @@ var PageTaskExecutor = class {
1132
1164
  sleep: sleep3
1133
1165
  } = planResult;
1134
1166
  executorContext.task.log = {
1167
+ ...executorContext.task.log || {},
1135
1168
  rawResponse
1136
1169
  };
1137
1170
  executorContext.task.usage = usage;
@@ -1256,11 +1289,11 @@ var PageTaskExecutor = class {
1256
1289
  };
1257
1290
  return task;
1258
1291
  }
1259
- async runPlans(title, plans) {
1292
+ async runPlans(title, plans, opts) {
1260
1293
  const taskExecutor = new Executor(title, {
1261
1294
  onTaskStart: this.onTaskStartCallback
1262
1295
  });
1263
- const { tasks } = await this.convertPlanToExecutable(plans);
1296
+ const { tasks } = await this.convertPlanToExecutable(plans, opts);
1264
1297
  await taskExecutor.append(tasks);
1265
1298
  const result = await taskExecutor.flush();
1266
1299
  return {
@@ -1268,7 +1301,7 @@ var PageTaskExecutor = class {
1268
1301
  executor: taskExecutor
1269
1302
  };
1270
1303
  }
1271
- async action(userPrompt, actionContext) {
1304
+ async action(userPrompt, actionContext, opts) {
1272
1305
  const taskExecutor = new Executor(taskTitleStr("Action", userPrompt), {
1273
1306
  onTaskStart: this.onTaskStartCallback
1274
1307
  });
@@ -1293,7 +1326,7 @@ var PageTaskExecutor = class {
1293
1326
  yamlFlow.push(...planResult.yamlFlow || []);
1294
1327
  let executables;
1295
1328
  try {
1296
- executables = await this.convertPlanToExecutable(plans);
1329
+ executables = await this.convertPlanToExecutable(plans, opts);
1297
1330
  taskExecutor.append(executables.tasks);
1298
1331
  } catch (error) {
1299
1332
  return this.appendErrorPlan(
@@ -1331,7 +1364,7 @@ var PageTaskExecutor = class {
1331
1364
  executor: taskExecutor
1332
1365
  };
1333
1366
  }
1334
- async actionToGoal(userPrompt) {
1367
+ async actionToGoal(userPrompt, opts) {
1335
1368
  const taskExecutor = new Executor(taskTitleStr("Action", userPrompt), {
1336
1369
  onTaskStart: this.onTaskStartCallback
1337
1370
  });
@@ -1355,7 +1388,7 @@ var PageTaskExecutor = class {
1355
1388
  yamlFlow.push(...output.yamlFlow || []);
1356
1389
  let executables;
1357
1390
  try {
1358
- executables = await this.convertPlanToExecutable(plans);
1391
+ executables = await this.convertPlanToExecutable(plans, opts);
1359
1392
  taskExecutor.append(executables.tasks);
1360
1393
  } catch (error) {
1361
1394
  return this.appendErrorPlan(
@@ -1660,7 +1693,7 @@ import yaml3 from "js-yaml";
1660
1693
  import semver from "semver";
1661
1694
 
1662
1695
  // package.json
1663
- var version = "1.0.2";
1696
+ var version = "1.0.4";
1664
1697
 
1665
1698
  // src/common/task-cache.ts
1666
1699
  var debug3 = getDebug3("cache");
@@ -2003,9 +2036,9 @@ var PageAgent = class {
2003
2036
  buildDetailedLocateParam(locatePrompt, opt) {
2004
2037
  assert7(locatePrompt, "missing locate prompt");
2005
2038
  if (typeof opt === "object") {
2006
- const prompt = opt.prompt || locatePrompt;
2007
- const deepThink = opt.deepThink || false;
2008
- const cacheable = opt.cacheable || true;
2039
+ const prompt = opt.prompt ?? locatePrompt;
2040
+ const deepThink = opt.deepThink ?? false;
2041
+ const cacheable = opt.cacheable ?? true;
2009
2042
  return {
2010
2043
  prompt,
2011
2044
  deepThink,
@@ -2024,7 +2057,8 @@ var PageAgent = class {
2024
2057
  const plans = buildPlans("Tap", detailedLocateParam);
2025
2058
  const { executor, output } = await this.taskExecutor.runPlans(
2026
2059
  taskTitleStr("Tap", locateParamStr(detailedLocateParam)),
2027
- plans
2060
+ plans,
2061
+ { cacheable: opt?.cacheable }
2028
2062
  );
2029
2063
  const metadata = this.afterTaskRunning(executor);
2030
2064
  return {
@@ -2040,7 +2074,8 @@ var PageAgent = class {
2040
2074
  const plans = buildPlans("Hover", detailedLocateParam);
2041
2075
  const { executor, output } = await this.taskExecutor.runPlans(
2042
2076
  taskTitleStr("Hover", locateParamStr(detailedLocateParam)),
2043
- plans
2077
+ plans,
2078
+ { cacheable: opt?.cacheable }
2044
2079
  );
2045
2080
  const metadata = this.afterTaskRunning(executor);
2046
2081
  return {
@@ -2063,7 +2098,8 @@ var PageAgent = class {
2063
2098
  });
2064
2099
  const { executor, output } = await this.taskExecutor.runPlans(
2065
2100
  taskTitleStr("Input", locateParamStr(detailedLocateParam)),
2066
- plans
2101
+ plans,
2102
+ { cacheable: opt?.cacheable }
2067
2103
  );
2068
2104
  const metadata = this.afterTaskRunning(executor);
2069
2105
  return {
@@ -2079,7 +2115,8 @@ var PageAgent = class {
2079
2115
  });
2080
2116
  const { executor, output } = await this.taskExecutor.runPlans(
2081
2117
  taskTitleStr("KeyboardPress", locateParamStr(detailedLocateParam)),
2082
- plans
2118
+ plans,
2119
+ { cacheable: opt?.cacheable }
2083
2120
  );
2084
2121
  const metadata = this.afterTaskRunning(executor);
2085
2122
  return {
@@ -2093,7 +2130,8 @@ var PageAgent = class {
2093
2130
  const paramInTitle = locatePrompt ? `${locateParamStr(detailedLocateParam)} - ${scrollParamStr(scrollParam)}` : scrollParamStr(scrollParam);
2094
2131
  const { executor, output } = await this.taskExecutor.runPlans(
2095
2132
  taskTitleStr("Scroll", paramInTitle),
2096
- plans
2133
+ plans,
2134
+ { cacheable: opt?.cacheable }
2097
2135
  );
2098
2136
  const metadata = this.afterTaskRunning(executor);
2099
2137
  return {
@@ -2102,6 +2140,19 @@ var PageAgent = class {
2102
2140
  };
2103
2141
  }
2104
2142
  async aiAction(taskPrompt, opt) {
2143
+ try {
2144
+ const aiModel = await import("misoai-core/ai-model");
2145
+ const contextStore = aiModel.getContextStore();
2146
+ const processedPrompt = contextStore.replaceAllReferences(taskPrompt, "action");
2147
+ contextStore.addStep({
2148
+ type: "action",
2149
+ summary: `Action: ${processedPrompt}`,
2150
+ prompt: processedPrompt
2151
+ });
2152
+ taskPrompt = processedPrompt;
2153
+ } catch (error) {
2154
+ debug4("Context store not available:", error);
2155
+ }
2105
2156
  const cacheable = opt?.cacheable;
2106
2157
  const isVlmUiTars = vlLocateMode() === "vlm-ui-tars";
2107
2158
  const matchedCache = isVlmUiTars || cacheable === false ? void 0 : this.taskCache?.matchPlanCache(taskPrompt);
@@ -2119,7 +2170,9 @@ var PageAgent = class {
2119
2170
  metadata: metadata2
2120
2171
  };
2121
2172
  }
2122
- const { output, executor } = await (isVlmUiTars ? this.taskExecutor.actionToGoal(taskPrompt) : this.taskExecutor.action(taskPrompt, this.opts.aiActionContext));
2173
+ const { output, executor } = await (isVlmUiTars ? this.taskExecutor.actionToGoal(taskPrompt, { cacheable }) : this.taskExecutor.action(taskPrompt, this.opts.aiActionContext, {
2174
+ cacheable
2175
+ }));
2123
2176
  if (this.taskCache && output?.yamlFlow && cacheable !== false) {
2124
2177
  const yamlContent = {
2125
2178
  tasks: [
@@ -2146,7 +2199,63 @@ var PageAgent = class {
2146
2199
  };
2147
2200
  }
2148
2201
  async aiQuery(demand) {
2149
- const { output, executor } = await this.taskExecutor.query(demand);
2202
+ let processedDemand = demand;
2203
+ let storageKey;
2204
+ try {
2205
+ const aiModel = await import("misoai-core/ai-model");
2206
+ const contextStore = aiModel.getContextStore();
2207
+ if (typeof demand === "string") {
2208
+ const storageInstruction = contextStore.parseStorageInstruction(demand);
2209
+ if (storageInstruction) {
2210
+ storageKey = storageInstruction.key;
2211
+ processedDemand = storageInstruction.cleanText;
2212
+ contextStore._pendingAliases = storageInstruction.aliases;
2213
+ } else {
2214
+ const storageMatch = demand.match(/store\s+(?:as\s+)?(\w+)/i);
2215
+ if (storageMatch) {
2216
+ storageKey = storageMatch[1];
2217
+ processedDemand = demand.replace(/,?\s*store\s+(?:as\s+)?\w+/i, "").trim();
2218
+ }
2219
+ }
2220
+ }
2221
+ } catch (error) {
2222
+ debug4("Context store not available:", error);
2223
+ }
2224
+ const { output, executor } = await this.taskExecutor.query(processedDemand);
2225
+ if (storageKey && output) {
2226
+ try {
2227
+ const aiModel = await import("misoai-core/ai-model");
2228
+ const contextStore = aiModel.getContextStore();
2229
+ const pendingAliases = contextStore._pendingAliases;
2230
+ if (pendingAliases) {
2231
+ contextStore.storeDataWithAliases(storageKey, output, pendingAliases, typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand));
2232
+ delete contextStore._pendingAliases;
2233
+ } else {
2234
+ contextStore.storeData(storageKey, output);
2235
+ }
2236
+ contextStore.addStep({
2237
+ type: "query",
2238
+ summary: `Query: ${typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)} (stored as ${storageKey})`,
2239
+ data: output,
2240
+ prompt: typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)
2241
+ });
2242
+ } catch (error) {
2243
+ debug4("Failed to store query result:", error);
2244
+ }
2245
+ } else {
2246
+ try {
2247
+ const aiModel = await import("misoai-core/ai-model");
2248
+ const contextStore = aiModel.getContextStore();
2249
+ contextStore.addStep({
2250
+ type: "query",
2251
+ summary: `Query: ${typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)}`,
2252
+ data: output,
2253
+ prompt: typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)
2254
+ });
2255
+ } catch (error) {
2256
+ debug4("Failed to add query step:", error);
2257
+ }
2258
+ }
2150
2259
  const metadata = this.afterTaskRunning(executor);
2151
2260
  return {
2152
2261
  result: output,
@@ -2241,7 +2350,8 @@ var PageAgent = class {
2241
2350
  const plans = buildPlans("Locate", detailedLocateParam);
2242
2351
  const { executor, output } = await this.taskExecutor.runPlans(
2243
2352
  taskTitleStr("Locate", locateParamStr(detailedLocateParam)),
2244
- plans
2353
+ plans,
2354
+ { cacheable: opt?.cacheable }
2245
2355
  );
2246
2356
  const metadata = this.afterTaskRunning(executor);
2247
2357
  const { element } = output;
@@ -2255,6 +2365,19 @@ var PageAgent = class {
2255
2365
  };
2256
2366
  }
2257
2367
  async aiAssert(assertion, msg, opt) {
2368
+ let processedAssertion = assertion;
2369
+ try {
2370
+ const aiModel = await import("misoai-core/ai-model");
2371
+ const contextStore = aiModel.getContextStore();
2372
+ processedAssertion = contextStore.replaceAllReferences(assertion, "assertion");
2373
+ contextStore.addStep({
2374
+ type: "assertion",
2375
+ summary: `Assertion: ${processedAssertion}`,
2376
+ prompt: processedAssertion
2377
+ });
2378
+ } catch (error) {
2379
+ debug4("Context store not available:", error);
2380
+ }
2258
2381
  let currentUrl = "";
2259
2382
  if (this.page.url) {
2260
2383
  try {
@@ -2262,7 +2385,7 @@ var PageAgent = class {
2262
2385
  } catch (e) {
2263
2386
  }
2264
2387
  }
2265
- const assertionWithContext = currentUrl ? `For the page at URL "${currentUrl}", ${assertion}` : assertion;
2388
+ const assertionWithContext = currentUrl ? `For the page at URL "${currentUrl}", ${processedAssertion}` : processedAssertion;
2266
2389
  const { output, executor } = await this.taskExecutor.assert(assertionWithContext);
2267
2390
  const metadata = this.afterTaskRunning(executor, true);
2268
2391
  if (output && opt?.keepRawResponse) {
@@ -2493,7 +2616,10 @@ import {
2493
2616
  import { sleep as sleep2 } from "misoai-core/utils";
2494
2617
  import { DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT as DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT2 } from "misoai-shared/constants";
2495
2618
  import { treeToList as treeToList2 } from "misoai-shared/extractor";
2496
- import { getExtraReturnLogic } from "misoai-shared/fs";
2619
+ import {
2620
+ getElementInfosScriptContent,
2621
+ getExtraReturnLogic
2622
+ } from "misoai-shared/fs";
2497
2623
  import { getDebug as getDebug5 } from "misoai-shared/logger";
2498
2624
  import { assert as assert8 } from "misoai-shared/utils";
2499
2625
  var debugPage = getDebug5("web:page");
@@ -2548,6 +2674,18 @@ var Page = class {
2548
2674
  debugPage("getElementsInfo end");
2549
2675
  return treeToList2(tree);
2550
2676
  }
2677
+ async getXpathsById(id) {
2678
+ const elementInfosScriptContent = getElementInfosScriptContent();
2679
+ return this.evaluateJavaScript(
2680
+ `${elementInfosScriptContent}midscene_element_inspector.getXpathsById('${id}')`
2681
+ );
2682
+ }
2683
+ async getElementInfoByXpath(xpath) {
2684
+ const elementInfosScriptContent = getElementInfosScriptContent();
2685
+ return this.evaluateJavaScript(
2686
+ `${elementInfosScriptContent}midscene_element_inspector.getElementInfoByXpath('${xpath}')`
2687
+ );
2688
+ }
2551
2689
  async getElementsNodeTree() {
2552
2690
  await this.waitForNavigation();
2553
2691
  const scripts = await getExtraReturnLogic(true);