misoai-web 1.0.6 → 1.5.7

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 (76) hide show
  1. package/README.md +5 -349
  2. package/dist/es/agent.js +165 -428
  3. package/dist/es/agent.js.map +1 -1
  4. package/dist/es/bridge-mode-browser.js +10 -9
  5. package/dist/es/bridge-mode-browser.js.map +1 -1
  6. package/dist/es/bridge-mode.js +167 -430
  7. package/dist/es/bridge-mode.js.map +1 -1
  8. package/dist/es/chrome-extension.js +173 -435
  9. package/dist/es/chrome-extension.js.map +1 -1
  10. package/dist/es/index.js +185 -432
  11. package/dist/es/index.js.map +1 -1
  12. package/dist/es/midscene-playground.js +165 -428
  13. package/dist/es/midscene-playground.js.map +1 -1
  14. package/dist/es/midscene-server.js.map +1 -1
  15. package/dist/es/playground.js +165 -428
  16. package/dist/es/playground.js.map +1 -1
  17. package/dist/es/playwright-report.js +1 -1
  18. package/dist/es/playwright-report.js.map +1 -1
  19. package/dist/es/playwright.js +182 -429
  20. package/dist/es/playwright.js.map +1 -1
  21. package/dist/es/puppeteer-agent-launcher.js +169 -432
  22. package/dist/es/puppeteer-agent-launcher.js.map +1 -1
  23. package/dist/es/puppeteer.js +169 -432
  24. package/dist/es/puppeteer.js.map +1 -1
  25. package/dist/es/ui-utils.js.map +1 -1
  26. package/dist/es/utils.js +7 -4
  27. package/dist/es/utils.js.map +1 -1
  28. package/dist/es/yaml.js +29 -3
  29. package/dist/es/yaml.js.map +1 -1
  30. package/dist/lib/agent.js +163 -426
  31. package/dist/lib/agent.js.map +1 -1
  32. package/dist/lib/bridge-mode-browser.js +10 -9
  33. package/dist/lib/bridge-mode-browser.js.map +1 -1
  34. package/dist/lib/bridge-mode.js +165 -428
  35. package/dist/lib/bridge-mode.js.map +1 -1
  36. package/dist/lib/chrome-extension.js +171 -433
  37. package/dist/lib/chrome-extension.js.map +1 -1
  38. package/dist/lib/index.js +183 -430
  39. package/dist/lib/index.js.map +1 -1
  40. package/dist/lib/midscene-playground.js +163 -426
  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 +163 -426
  44. package/dist/lib/playground.js.map +1 -1
  45. package/dist/lib/playwright-report.js +1 -1
  46. package/dist/lib/playwright-report.js.map +1 -1
  47. package/dist/lib/playwright.js +180 -427
  48. package/dist/lib/playwright.js.map +1 -1
  49. package/dist/lib/puppeteer-agent-launcher.js +167 -430
  50. package/dist/lib/puppeteer-agent-launcher.js.map +1 -1
  51. package/dist/lib/puppeteer.js +167 -430
  52. package/dist/lib/puppeteer.js.map +1 -1
  53. package/dist/lib/ui-utils.js.map +1 -1
  54. package/dist/lib/utils.js +7 -4
  55. package/dist/lib/utils.js.map +1 -1
  56. package/dist/lib/yaml.js +29 -3
  57. package/dist/lib/yaml.js.map +1 -1
  58. package/dist/types/agent.d.ts +13 -51
  59. package/dist/types/bridge-mode-browser.d.ts +2 -3
  60. package/dist/types/bridge-mode.d.ts +2 -3
  61. package/dist/types/{browser-aec1055d.d.ts → browser-9b472ffb.d.ts} +1 -1
  62. package/dist/types/chrome-extension.d.ts +2 -3
  63. package/dist/types/index.d.ts +1 -2
  64. package/dist/types/midscene-server.d.ts +1 -2
  65. package/dist/types/{page-86ab0fe1.d.ts → page-ed0ecb44.d.ts} +19 -9
  66. package/dist/types/playground.d.ts +2 -3
  67. package/dist/types/playwright.d.ts +9 -2
  68. package/dist/types/puppeteer-agent-launcher.d.ts +1 -2
  69. package/dist/types/puppeteer.d.ts +6 -5
  70. package/dist/types/ui-utils.d.ts +1 -1
  71. package/dist/types/utils.d.ts +1 -2
  72. package/dist/types/yaml.d.ts +1 -2
  73. package/iife-script/htmlElement.js +53 -75
  74. package/iife-script/htmlElementDebug.js +35 -56
  75. package/package.json +24 -24
  76. package/LICENSE +0 -21
@@ -22,10 +22,11 @@ var ScriptPlayer = class {
22
22
  this.unnamedResultIndex = 0;
23
23
  this.pageAgent = null;
24
24
  this.result = {};
25
+ const target = script.target || script.web || script.android;
25
26
  if (ifInBrowser) {
26
27
  this.output = void 0;
27
- } else if (script.target?.output) {
28
- this.output = resolve(process.cwd(), script.target.output);
28
+ } else if (target?.output) {
29
+ this.output = resolve(process.cwd(), target.output);
29
30
  } else {
30
31
  this.output = join(getMidsceneRunSubDir("output"), `${process.pid}.json`);
31
32
  }
@@ -99,15 +100,20 @@ var ScriptPlayer = class {
99
100
  } else if ("aiAssert" in flowItem) {
100
101
  const assertTask = flowItem;
101
102
  const prompt = assertTask.aiAssert;
103
+ const msg = assertTask.errorMessage;
102
104
  assert(prompt, "missing prompt for aiAssert");
103
105
  assert(
104
106
  typeof prompt === "string",
105
107
  "prompt for aiAssert must be a string"
106
108
  );
107
- await agent.aiAssert(prompt);
109
+ await agent.aiAssert(prompt, msg);
108
110
  } else if ("aiQuery" in flowItem) {
109
111
  const queryTask = flowItem;
110
112
  const prompt = queryTask.aiQuery;
113
+ const options = {
114
+ domIncluded: queryTask.domIncluded,
115
+ screenshotIncluded: queryTask.screenshotIncluded
116
+ };
111
117
  assert(prompt, "missing prompt for aiQuery");
112
118
  assert(
113
119
  typeof prompt === "string",
@@ -118,6 +124,10 @@ var ScriptPlayer = class {
118
124
  } else if ("aiNumber" in flowItem) {
119
125
  const numberTask = flowItem;
120
126
  const prompt = numberTask.aiNumber;
127
+ const options = {
128
+ domIncluded: numberTask.domIncluded,
129
+ screenshotIncluded: numberTask.screenshotIncluded
130
+ };
121
131
  assert(prompt, "missing prompt for number");
122
132
  assert(
123
133
  typeof prompt === "string",
@@ -128,6 +138,10 @@ var ScriptPlayer = class {
128
138
  } else if ("aiString" in flowItem) {
129
139
  const stringTask = flowItem;
130
140
  const prompt = stringTask.aiString;
141
+ const options = {
142
+ domIncluded: stringTask.domIncluded,
143
+ screenshotIncluded: stringTask.screenshotIncluded
144
+ };
131
145
  assert(prompt, "missing prompt for string");
132
146
  assert(
133
147
  typeof prompt === "string",
@@ -138,6 +152,10 @@ var ScriptPlayer = class {
138
152
  } else if ("aiBoolean" in flowItem) {
139
153
  const booleanTask = flowItem;
140
154
  const prompt = booleanTask.aiBoolean;
155
+ const options = {
156
+ domIncluded: booleanTask.domIncluded,
157
+ screenshotIncluded: booleanTask.screenshotIncluded
158
+ };
141
159
  assert(prompt, "missing prompt for boolean");
142
160
  assert(
143
161
  typeof prompt === "string",
@@ -180,6 +198,9 @@ var ScriptPlayer = class {
180
198
  } else if ("aiTap" in flowItem) {
181
199
  const tapTask = flowItem;
182
200
  await agent.aiTap(tapTask.aiTap, tapTask);
201
+ } else if ("aiRightClick" in flowItem) {
202
+ const rightClickTask = flowItem;
203
+ await agent.aiRightClick(rightClickTask.aiRightClick, rightClickTask);
183
204
  } else if ("aiHover" in flowItem) {
184
205
  const hoverTask = flowItem;
185
206
  await agent.aiHover(hoverTask.aiHover, hoverTask);
@@ -202,6 +223,11 @@ var ScriptPlayer = class {
202
223
  evaluateJavaScriptTask.javascript
203
224
  );
204
225
  this.setResult(evaluateJavaScriptTask.name, result);
226
+ } else if ("logScreenshot" in flowItem) {
227
+ const logScreenshotTask = flowItem;
228
+ await agent.logScreenshot(logScreenshotTask.logScreenshot, {
229
+ content: logScreenshotTask.content || ""
230
+ });
205
231
  } else {
206
232
  throw new Error(`unknown flowItem: ${JSON.stringify(flowItem)}`);
207
233
  }
@@ -470,7 +496,8 @@ var WebElementInfo = class {
470
496
  id,
471
497
  attributes,
472
498
  indexId,
473
- xpaths
499
+ xpaths,
500
+ isVisible
474
501
  }) {
475
502
  this.content = content;
476
503
  this.rect = rect;
@@ -483,6 +510,7 @@ var WebElementInfo = class {
483
510
  this.attributes = attributes;
484
511
  this.indexId = indexId;
485
512
  this.xpaths = xpaths;
513
+ this.isVisible = isVisible;
486
514
  }
487
515
  };
488
516
 
@@ -505,14 +533,15 @@ async function parseContextFromWebPage(page, _opt) {
505
533
  })
506
534
  ]);
507
535
  const webTree = traverseTree(tree, (elementInfo) => {
508
- const { rect, id, content, attributes, locator, indexId } = elementInfo;
536
+ const { rect, id, content, attributes, locator, indexId, isVisible } = elementInfo;
509
537
  return new WebElementInfo({
510
538
  rect,
511
539
  locator,
512
540
  id,
513
541
  content,
514
542
  attributes,
515
- indexId
543
+ indexId,
544
+ isVisible
516
545
  });
517
546
  });
518
547
  assert3(screenshotBase64, "screenshotBase64 is required");
@@ -542,7 +571,7 @@ function printReportMsg(filepath) {
542
571
  logMsg(`Midscene - report file updated: ${filepath}`);
543
572
  }
544
573
  function replaceIllegalPathCharsAndSpace(str) {
545
- return str.replace(/[/\\:*?"<>| ]/g, "-");
574
+ return str.replace(/[:*?"<>| ]/g, "-");
546
575
  }
547
576
  function forceClosePopup(page, debug6) {
548
577
  page.on("popup", async (popup) => {
@@ -856,10 +885,10 @@ var PageTaskExecutor = class {
856
885
  if (!taskParam || !taskParam.value) {
857
886
  return;
858
887
  }
859
- await this.page.keyboard.type(taskParam.value);
860
- } else {
861
- await this.page.keyboard.type(taskParam.value);
862
888
  }
889
+ await this.page.keyboard.type(taskParam.value, {
890
+ autoDismissKeyboard: taskParam.autoDismissKeyboard
891
+ });
863
892
  }
864
893
  };
865
894
  tasks.push(taskActionInput);
@@ -888,6 +917,22 @@ var PageTaskExecutor = class {
888
917
  }
889
918
  };
890
919
  tasks.push(taskActionTap);
920
+ } else if (plan2.type === "RightClick") {
921
+ const taskActionRightClick = {
922
+ type: "Action",
923
+ subType: "RightClick",
924
+ thought: plan2.thought,
925
+ locate: plan2.locate,
926
+ executor: async (param, { element }) => {
927
+ assert4(element, "Element not found, cannot right click");
928
+ await this.page.mouse.click(
929
+ element.center[0],
930
+ element.center[1],
931
+ { button: "right" }
932
+ );
933
+ }
934
+ };
935
+ tasks.push(taskActionRightClick);
891
936
  } else if (plan2.type === "Drag") {
892
937
  const taskActionDrag = {
893
938
  type: "Action",
@@ -1416,7 +1461,7 @@ var PageTaskExecutor = class {
1416
1461
  executor: taskExecutor
1417
1462
  };
1418
1463
  }
1419
- async createTypeQueryTask(type, demand) {
1464
+ async createTypeQueryTask(type, demand, opt) {
1420
1465
  const taskExecutor = new Executor(
1421
1466
  taskTitleStr(
1422
1467
  type,
@@ -1447,7 +1492,10 @@ var PageTaskExecutor = class {
1447
1492
  result: `${type}, ${demand}`
1448
1493
  };
1449
1494
  }
1450
- const { data, usage } = await this.insight.extract(demandInput);
1495
+ const { data, usage } = await this.insight.extract(
1496
+ demandInput,
1497
+ opt
1498
+ );
1451
1499
  let outputResult = data;
1452
1500
  if (ifTypeRestricted) {
1453
1501
  assert4(data?.result !== void 0, "No result in query data");
@@ -1467,17 +1515,17 @@ var PageTaskExecutor = class {
1467
1515
  executor: taskExecutor
1468
1516
  };
1469
1517
  }
1470
- async query(demand) {
1471
- return this.createTypeQueryTask("Query", demand);
1518
+ async query(demand, opt) {
1519
+ return this.createTypeQueryTask("Query", demand, opt);
1472
1520
  }
1473
- async boolean(prompt) {
1474
- return this.createTypeQueryTask("Boolean", prompt);
1521
+ async boolean(prompt, opt) {
1522
+ return this.createTypeQueryTask("Boolean", prompt, opt);
1475
1523
  }
1476
- async number(prompt) {
1477
- return this.createTypeQueryTask("Number", prompt);
1524
+ async number(prompt, opt) {
1525
+ return this.createTypeQueryTask("Number", prompt, opt);
1478
1526
  }
1479
- async string(prompt) {
1480
- return this.createTypeQueryTask("String", prompt);
1527
+ async string(prompt, opt) {
1528
+ return this.createTypeQueryTask("String", prompt, opt);
1481
1529
  }
1482
1530
  async assert(assertion) {
1483
1531
  const description = `assert: ${assertion}`;
@@ -1613,7 +1661,7 @@ function buildPlans(type, locateParam, param) {
1613
1661
  param: locateParam,
1614
1662
  thought: ""
1615
1663
  } : null;
1616
- if (type === "Tap" || type === "Hover") {
1664
+ if (type === "Tap" || type === "Hover" || type === "RightClick") {
1617
1665
  assert5(locateParam, `missing locate info for action "${type}"`);
1618
1666
  assert5(locatePlan, `missing locate info for action "${type}"`);
1619
1667
  const tapPlan = {
@@ -1684,8 +1732,8 @@ function buildPlans(type, locateParam, param) {
1684
1732
 
1685
1733
  // src/common/task-cache.ts
1686
1734
  import assert6 from "assert";
1687
- import { existsSync as existsSync2, readFileSync, writeFileSync as writeFileSync2 } from "fs";
1688
- import { join as join2 } from "path";
1735
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync, writeFileSync as writeFileSync2 } from "fs";
1736
+ import { dirname as dirname2, join as join2 } from "path";
1689
1737
  import { getMidsceneRunSubDir as getMidsceneRunSubDir2 } from "misoai-shared/common";
1690
1738
  import { getDebug as getDebug3 } from "misoai-shared/logger";
1691
1739
  import { ifInBrowser as ifInBrowser2 } from "misoai-shared/utils";
@@ -1693,7 +1741,7 @@ import yaml3 from "js-yaml";
1693
1741
  import semver from "semver";
1694
1742
 
1695
1743
  // package.json
1696
- var version = "1.0.5";
1744
+ var version = "1.0.3";
1697
1745
 
1698
1746
  // src/common/task-cache.ts
1699
1747
  var debug3 = getDebug3("cache");
@@ -1721,70 +1769,44 @@ var TaskCache = class {
1721
1769
  this.cache = cacheContent;
1722
1770
  this.cacheOriginalLength = this.cache.caches.length;
1723
1771
  }
1724
- matchCache(prompt, type, contextData) {
1725
- const contextHash = contextData ? this.generateContextHash(contextData) : void 0;
1772
+ matchCache(prompt, type) {
1726
1773
  for (let i = 0; i < this.cacheOriginalLength; i++) {
1727
1774
  const item = this.cache.caches[i];
1728
1775
  const key = `${type}:${prompt}:${i}`;
1729
- if (item.type !== type || item.prompt !== prompt || this.matchedCacheIndices.has(key)) {
1730
- continue;
1731
- }
1732
- if (type === "plan" && item.type === "plan") {
1733
- const planItem = item;
1734
- if (contextHash && planItem.contextHash) {
1735
- if (contextHash !== planItem.contextHash) {
1736
- debug3("cache context mismatch, type: %s, prompt: %s, index: %d", type, prompt, i);
1737
- continue;
1776
+ if (item.type === type && item.prompt === prompt && !this.matchedCacheIndices.has(key)) {
1777
+ this.matchedCacheIndices.add(key);
1778
+ debug3(
1779
+ "cache found and marked as used, type: %s, prompt: %s, index: %d",
1780
+ type,
1781
+ prompt,
1782
+ i
1783
+ );
1784
+ return {
1785
+ cacheContent: item,
1786
+ updateFn: (cb) => {
1787
+ debug3(
1788
+ "will call updateFn to update cache, type: %s, prompt: %s, index: %d",
1789
+ type,
1790
+ prompt,
1791
+ i
1792
+ );
1793
+ cb(item);
1794
+ debug3(
1795
+ "cache updated, will flush to file, type: %s, prompt: %s, index: %d",
1796
+ type,
1797
+ prompt,
1798
+ i
1799
+ );
1800
+ this.flushCacheToFile();
1738
1801
  }
1739
- } else if (contextHash || planItem.contextHash) {
1740
- debug3("cache context availability mismatch, type: %s, prompt: %s, index: %d", type, prompt, i);
1741
- continue;
1742
- }
1802
+ };
1743
1803
  }
1744
- this.matchedCacheIndices.add(key);
1745
- debug3(
1746
- "cache found and marked as used, type: %s, prompt: %s, index: %d, contextMatch: %s",
1747
- type,
1748
- prompt,
1749
- i,
1750
- contextHash ? "yes" : "no-context"
1751
- );
1752
- return {
1753
- cacheContent: item,
1754
- updateFn: (cb) => {
1755
- debug3(
1756
- "will call updateFn to update cache, type: %s, prompt: %s, index: %d",
1757
- type,
1758
- prompt,
1759
- i
1760
- );
1761
- cb(item);
1762
- debug3(
1763
- "cache updated, will flush to file, type: %s, prompt: %s, index: %d",
1764
- type,
1765
- prompt,
1766
- i
1767
- );
1768
- this.flushCacheToFile();
1769
- }
1770
- };
1771
1804
  }
1772
- debug3("no unused cache found, type: %s, prompt: %s, contextHash: %s", type, prompt, contextHash);
1805
+ debug3("no unused cache found, type: %s, prompt: %s", type, prompt);
1773
1806
  return void 0;
1774
1807
  }
1775
- generateContextHash(contextData) {
1776
- const sortedKeys = Object.keys(contextData).sort();
1777
- const stableString = sortedKeys.map((key) => `${key}:${JSON.stringify(contextData[key])}`).join("|");
1778
- let hash = 0;
1779
- for (let i = 0; i < stableString.length; i++) {
1780
- const char = stableString.charCodeAt(i);
1781
- hash = (hash << 5) - hash + char;
1782
- hash = hash & hash;
1783
- }
1784
- return hash.toString(36);
1785
- }
1786
- matchPlanCache(prompt, contextData) {
1787
- return this.matchCache(prompt, "plan", contextData);
1808
+ matchPlanCache(prompt) {
1809
+ return this.matchCache(prompt, "plan");
1788
1810
  }
1789
1811
  matchLocateCache(prompt) {
1790
1812
  return this.matchCache(prompt, "locate");
@@ -1850,8 +1872,14 @@ cache file: ${cacheFile}`
1850
1872
  return;
1851
1873
  }
1852
1874
  try {
1875
+ const dir = dirname2(this.cacheFilePath);
1876
+ if (!existsSync2(dir)) {
1877
+ mkdirSync2(dir, { recursive: true });
1878
+ debug3("created cache directory: %s", dir);
1879
+ }
1853
1880
  const yamlData = yaml3.dump(this.cache);
1854
1881
  writeFileSync2(this.cacheFilePath, yamlData);
1882
+ debug3("cache flushed to file: %s", this.cacheFilePath);
1855
1883
  } catch (err) {
1856
1884
  debug3(
1857
1885
  "write cache to file failed, path: %s, error: %s",
@@ -1860,16 +1888,11 @@ cache file: ${cacheFile}`
1860
1888
  );
1861
1889
  }
1862
1890
  }
1863
- updateOrAppendCacheRecord(newRecord, cachedRecord, contextData) {
1891
+ updateOrAppendCacheRecord(newRecord, cachedRecord) {
1864
1892
  if (cachedRecord) {
1865
1893
  if (newRecord.type === "plan") {
1866
1894
  cachedRecord.updateFn((cache) => {
1867
- const planCache = cache;
1868
- planCache.yamlWorkflow = newRecord.yamlWorkflow;
1869
- if (contextData) {
1870
- planCache.contextHash = this.generateContextHash(contextData);
1871
- planCache.contextData = { ...contextData };
1872
- }
1895
+ cache.yamlWorkflow = newRecord.yamlWorkflow;
1873
1896
  });
1874
1897
  } else {
1875
1898
  cachedRecord.updateFn((cache) => {
@@ -1877,11 +1900,6 @@ cache file: ${cacheFile}`
1877
1900
  });
1878
1901
  }
1879
1902
  } else {
1880
- if (newRecord.type === "plan" && contextData) {
1881
- const planRecord = newRecord;
1882
- planRecord.contextHash = this.generateContextHash(contextData);
1883
- planRecord.contextData = { ...contextData };
1884
- }
1885
1903
  this.appendCache(newRecord);
1886
1904
  }
1887
1905
  }
@@ -1911,13 +1929,10 @@ var PageAgent = class {
1911
1929
  generateReport: true,
1912
1930
  autoPrintReportMsg: true,
1913
1931
  groupName: "Midscene Report",
1914
- groupDescription: "",
1915
- enableCumulativeContext: true,
1916
- autoClearContext: false
1932
+ groupDescription: ""
1917
1933
  },
1918
1934
  opts || {}
1919
1935
  );
1920
- this.initializeContextStore();
1921
1936
  if (this.page.pageType === "puppeteer" || this.page.pageType === "playwright") {
1922
1937
  this.page.waitForNavigationTimeout = this.opts.waitForNavigationTimeout || DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT;
1923
1938
  this.page.waitForNetworkIdleTimeout = this.opts.waitForNetworkIdleTimeout || DEFAULT_WAIT_FOR_NETWORK_IDLE_TIMEOUT;
@@ -1944,69 +1959,6 @@ var PageAgent = class {
1944
1959
  opts?.testId || this.page.pageType || "web"
1945
1960
  );
1946
1961
  }
1947
- /**
1948
- * Initialize context store for cumulative context functionality
1949
- */
1950
- async initializeContextStore() {
1951
- if (!this.opts.enableCumulativeContext) {
1952
- debug4("Cumulative context disabled via options");
1953
- return;
1954
- }
1955
- try {
1956
- const aiModel = await import("misoai-core/ai-model");
1957
- this.contextStore = aiModel.getContextStore();
1958
- debug4("Context store initialized successfully", {
1959
- autoClearContext: this.opts.autoClearContext,
1960
- testId: this.opts.testId
1961
- });
1962
- if (this.opts.autoClearContext) {
1963
- this.contextStore.clear();
1964
- debug4("Context store cleared due to autoClearContext option");
1965
- } else {
1966
- const existingData = this.contextStore.getAllData();
1967
- const existingSteps = this.contextStore.getRecentSteps(100).length;
1968
- debug4("Context store preserving existing data", {
1969
- existingDataKeys: Object.keys(existingData),
1970
- existingStepsCount: existingSteps
1971
- });
1972
- }
1973
- } catch (error) {
1974
- debug4("Failed to initialize context store:", error);
1975
- console.warn("⚠️ Could not initialize context store:", error);
1976
- }
1977
- }
1978
- /**
1979
- * Get the context store instance
1980
- */
1981
- getContextStore() {
1982
- return this.contextStore;
1983
- }
1984
- /**
1985
- * Clear the context store
1986
- */
1987
- clearContext() {
1988
- if (this.contextStore) {
1989
- this.contextStore.clear();
1990
- }
1991
- }
1992
- /**
1993
- * Get all stored data from context store
1994
- */
1995
- getStoredData() {
1996
- if (this.contextStore) {
1997
- return this.contextStore.getAllData();
1998
- }
1999
- return {};
2000
- }
2001
- /**
2002
- * Get step summary from context store
2003
- */
2004
- getStepSummary() {
2005
- if (this.contextStore) {
2006
- return this.contextStore.getStepSummary();
2007
- }
2008
- return "";
2009
- }
2010
1962
  async getUIContext(action) {
2011
1963
  if (action && (action === "extract" || action === "assert" || action === "captcha")) {
2012
1964
  return await parseContextFromWebPage(this.page, {
@@ -2185,6 +2137,23 @@ var PageAgent = class {
2185
2137
  metadata
2186
2138
  };
2187
2139
  }
2140
+ async aiRightClick(locatePrompt, opt) {
2141
+ const detailedLocateParam = this.buildDetailedLocateParam(
2142
+ locatePrompt,
2143
+ opt
2144
+ );
2145
+ const plans = buildPlans("RightClick", detailedLocateParam);
2146
+ const { executor, output } = await this.taskExecutor.runPlans(
2147
+ taskTitleStr("RightClick", locateParamStr(detailedLocateParam)),
2148
+ plans,
2149
+ { cacheable: opt?.cacheable }
2150
+ );
2151
+ const metadata = this.afterTaskRunning(executor);
2152
+ return {
2153
+ result: output,
2154
+ metadata
2155
+ };
2156
+ }
2188
2157
  async aiInput(value, locatePrompt, opt) {
2189
2158
  assert7(
2190
2159
  typeof value === "string",
@@ -2242,35 +2211,9 @@ var PageAgent = class {
2242
2211
  };
2243
2212
  }
2244
2213
  async aiAction(taskPrompt, opt) {
2245
- const originalPrompt = taskPrompt;
2246
- let processedPrompt = taskPrompt;
2247
- if (this.opts.enableCumulativeContext && this.contextStore) {
2248
- try {
2249
- const storedData = this.contextStore.getAllData();
2250
- if (Object.keys(storedData).length > 0) {
2251
- debug4("Available data for aiAction:", {
2252
- prompt: taskPrompt,
2253
- availableData: storedData
2254
- });
2255
- }
2256
- } catch (error) {
2257
- debug4("Context store operation failed:", error);
2258
- }
2259
- }
2260
2214
  const cacheable = opt?.cacheable;
2261
2215
  const isVlmUiTars = vlLocateMode() === "vlm-ui-tars";
2262
- let contextData;
2263
- if (this.opts.enableCumulativeContext && this.contextStore) {
2264
- try {
2265
- contextData = this.contextStore.getAllData();
2266
- if (contextData && Object.keys(contextData).length === 0) {
2267
- contextData = void 0;
2268
- }
2269
- } catch (error) {
2270
- debug4("Failed to get context data for cache:", error);
2271
- }
2272
- }
2273
- const matchedCache = isVlmUiTars || cacheable === false ? void 0 : this.taskCache?.matchPlanCache(taskPrompt, contextData);
2216
+ const matchedCache = isVlmUiTars || cacheable === false ? void 0 : this.taskCache?.matchPlanCache(taskPrompt);
2274
2217
  if (matchedCache && this.taskCache?.isCacheResultUsed) {
2275
2218
  const { executor: executor2 } = await this.taskExecutor.loadYamlFlowAsPlanning(
2276
2219
  taskPrompt,
@@ -2280,28 +2223,6 @@ var PageAgent = class {
2280
2223
  debug4("matched cache, will call .runYaml to run the action");
2281
2224
  const yaml5 = matchedCache.cacheContent?.yamlWorkflow;
2282
2225
  const result = await this.runYaml(yaml5);
2283
- if (this.opts.enableCumulativeContext && this.contextStore) {
2284
- try {
2285
- const executionResult = {
2286
- success: true,
2287
- actionType: "cached",
2288
- description: `Executed cached action: ${processedPrompt}`,
2289
- timing: result.metadata?.totalTime
2290
- };
2291
- this.contextStore.addStep({
2292
- type: "action",
2293
- summary: `Action: ${processedPrompt} (cached)`,
2294
- prompt: processedPrompt,
2295
- executionResult
2296
- });
2297
- debug4("Added cached action step to context store:", {
2298
- stepNumber: this.contextStore.getRecentSteps(1)[0]?.stepNumber,
2299
- totalSteps: this.contextStore.getRecentSteps(100).length
2300
- });
2301
- } catch (error) {
2302
- debug4("Failed to add cached action step:", error);
2303
- }
2304
- }
2305
2226
  return {
2306
2227
  result: result.result,
2307
2228
  metadata: metadata2
@@ -2326,114 +2247,17 @@ var PageAgent = class {
2326
2247
  prompt: taskPrompt,
2327
2248
  yamlWorkflow: yamlFlowStr
2328
2249
  },
2329
- matchedCache,
2330
- contextData
2331
- // Pass context data for cache creation
2250
+ matchedCache
2332
2251
  );
2333
2252
  }
2334
2253
  const metadata = this.afterTaskRunning(executor);
2335
- if (this.opts.enableCumulativeContext && this.contextStore) {
2336
- try {
2337
- const executionResult = this.analyzeExecutionResults(executor, originalPrompt);
2338
- this.contextStore.addStep({
2339
- type: "action",
2340
- summary: `Action: ${processedPrompt}`,
2341
- prompt: processedPrompt,
2342
- executionResult
2343
- });
2344
- debug4("Added action step with execution result to context store:", {
2345
- stepNumber: this.contextStore.getRecentSteps(1)[0]?.stepNumber,
2346
- totalSteps: this.contextStore.getRecentSteps(100).length,
2347
- executionResult
2348
- });
2349
- } catch (error) {
2350
- debug4("Failed to analyze execution results, adding step without execution result:", error);
2351
- try {
2352
- this.contextStore.addStep({
2353
- type: "action",
2354
- summary: `Action: ${processedPrompt}`,
2355
- prompt: processedPrompt
2356
- });
2357
- } catch (stepError) {
2358
- debug4("Failed to add action step:", stepError);
2359
- }
2360
- }
2361
- }
2362
2254
  return {
2363
2255
  result: output,
2364
2256
  metadata
2365
2257
  };
2366
2258
  }
2367
2259
  async aiQuery(demand) {
2368
- let processedDemand = demand;
2369
- let storageKey;
2370
- try {
2371
- const aiModel = await import("misoai-core/ai-model");
2372
- const contextStore = aiModel.getContextStore();
2373
- if (typeof demand === "string") {
2374
- const storageInstruction = contextStore.parseStorageInstruction(demand);
2375
- if (storageInstruction) {
2376
- storageKey = storageInstruction.key;
2377
- processedDemand = storageInstruction.cleanText;
2378
- contextStore._pendingAliases = storageInstruction.aliases;
2379
- } else {
2380
- const storageMatch = demand.match(/store\s+(?:as\s+)?(\w+)/i);
2381
- if (storageMatch) {
2382
- storageKey = storageMatch[1];
2383
- processedDemand = demand.replace(/,?\s*store\s+(?:as\s+)?\w+/i, "").trim();
2384
- }
2385
- }
2386
- }
2387
- } catch (error) {
2388
- debug4("Context store not available:", error);
2389
- }
2390
- const { output, executor } = await this.taskExecutor.query(processedDemand);
2391
- if (this.opts.enableCumulativeContext && this.contextStore) {
2392
- if (storageKey && output) {
2393
- try {
2394
- const pendingAliases = this.contextStore._pendingAliases;
2395
- if (pendingAliases) {
2396
- this.contextStore.storeDataWithAliases(storageKey, output, pendingAliases, typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand));
2397
- delete this.contextStore._pendingAliases;
2398
- debug4("Stored query result with aliases:", {
2399
- key: storageKey,
2400
- value: output,
2401
- aliases: pendingAliases
2402
- });
2403
- } else {
2404
- this.contextStore.storeData(storageKey, output);
2405
- debug4("Stored query result:", {
2406
- key: storageKey,
2407
- value: output
2408
- });
2409
- }
2410
- this.contextStore.addStep({
2411
- type: "query",
2412
- summary: `Query: ${typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)} (stored as ${storageKey})`,
2413
- data: output,
2414
- prompt: typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)
2415
- });
2416
- debug4("Added query step to context store:", {
2417
- storageKey,
2418
- totalStoredItems: Object.keys(this.contextStore.getAllData()).length,
2419
- totalSteps: this.contextStore.getRecentSteps(100).length
2420
- });
2421
- } catch (error) {
2422
- debug4("Failed to store query result:", error);
2423
- }
2424
- } else {
2425
- try {
2426
- this.contextStore.addStep({
2427
- type: "query",
2428
- summary: `Query: ${typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)}`,
2429
- data: output,
2430
- prompt: typeof processedDemand === "string" ? processedDemand : JSON.stringify(processedDemand)
2431
- });
2432
- } catch (error) {
2433
- debug4("Failed to add query step:", error);
2434
- }
2435
- }
2436
- }
2260
+ const { output, executor } = await this.taskExecutor.query(demand);
2437
2261
  const metadata = this.afterTaskRunning(executor);
2438
2262
  return {
2439
2263
  result: output,
@@ -2543,48 +2367,6 @@ var PageAgent = class {
2543
2367
  };
2544
2368
  }
2545
2369
  async aiAssert(assertion, msg, opt) {
2546
- let executionContext = "";
2547
- if (this.opts.enableCumulativeContext && this.contextStore) {
2548
- try {
2549
- const recentSteps = this.contextStore.getRecentSteps(3);
2550
- const stepsWithExecutionResults = recentSteps.filter((step) => step.executionResult);
2551
- const storedData = this.contextStore.getAllData();
2552
- if (stepsWithExecutionResults.length > 0) {
2553
- const recentActions = stepsWithExecutionResults.map((step) => {
2554
- const result = step.executionResult;
2555
- return `- ${result.description}${result.success ? "" : " (FAILED)"}`;
2556
- }).join("\n");
2557
- executionContext = `
2558
-
2559
- Recent actions performed:
2560
- ${recentActions}
2561
-
2562
- This context may help verify the assertion.`;
2563
- }
2564
- if (storedData && Object.keys(storedData).length > 0) {
2565
- executionContext += `
2566
-
2567
- Available data for reference:
2568
- ${JSON.stringify(storedData, null, 2)}
2569
-
2570
- Note: If the assertion references any data keys or natural language equivalents, consider the stored values when verifying.`;
2571
- debug4("Available data for aiAssert:", {
2572
- assertion,
2573
- availableData: storedData
2574
- });
2575
- }
2576
- this.contextStore.addStep({
2577
- type: "assertion",
2578
- summary: `Assertion: ${assertion}`,
2579
- prompt: assertion
2580
- });
2581
- debug4("Added assertion step to context store:", {
2582
- totalSteps: this.contextStore.getRecentSteps(100).length
2583
- });
2584
- } catch (error) {
2585
- debug4("Context store operation failed:", error);
2586
- }
2587
- }
2588
2370
  let currentUrl = "";
2589
2371
  if (this.page.url) {
2590
2372
  try {
@@ -2592,13 +2374,7 @@ Note: If the assertion references any data keys or natural language equivalents,
2592
2374
  } catch (e) {
2593
2375
  }
2594
2376
  }
2595
- let assertionWithContext = assertion;
2596
- if (currentUrl) {
2597
- assertionWithContext = `For the page at URL "${currentUrl}", ${assertion}`;
2598
- }
2599
- if (executionContext) {
2600
- assertionWithContext += executionContext;
2601
- }
2377
+ const assertionWithContext = currentUrl ? `For the page at URL "${currentUrl}", ${assertion}` : assertion;
2602
2378
  const { output, executor } = await this.taskExecutor.assert(assertionWithContext);
2603
2379
  const metadata = this.afterTaskRunning(executor, true);
2604
2380
  if (output && opt?.keepRawResponse) {
@@ -2809,81 +2585,42 @@ ${errors}`);
2809
2585
  }
2810
2586
  throw new Error("evaluateJavaScript is not supported in current agent");
2811
2587
  }
2812
- async destroy() {
2813
- await this.page.destroy();
2814
- }
2815
- /**
2816
- * Analyze execution results from executor to generate meaningful descriptions
2817
- */
2818
- analyzeExecutionResults(executor, originalPrompt) {
2819
- const tasks = executor.tasks;
2820
- const success = !executor.isInErrorState();
2821
- if (!success) {
2822
- const errorTask = executor.latestErrorTask();
2823
- return {
2824
- success: false,
2825
- actionType: "error",
2826
- description: `Failed to execute: ${originalPrompt}`,
2827
- error: errorTask?.error
2828
- };
2829
- }
2830
- const actionTasks = tasks.filter((t) => t.type === "Action" && t.status === "finished");
2831
- const locateTasks = tasks.filter((t) => t.type === "Insight" && t.subType === "Locate");
2832
- const lastAction = actionTasks[actionTasks.length - 1];
2833
- const lastLocate = locateTasks[locateTasks.length - 1];
2834
- if (!lastAction) {
2835
- return {
2836
- success: true,
2837
- actionType: "unknown",
2838
- description: `Completed: ${originalPrompt}`
2588
+ async logScreenshot(title, options) {
2589
+ const screenshotTitle = title || "untitled";
2590
+ const content = options?.content || "";
2591
+ const screenshot = await this.page.screenshotBase64?.();
2592
+ if (screenshot) {
2593
+ const executionDump = {
2594
+ name: screenshotTitle,
2595
+ description: content,
2596
+ tasks: [{
2597
+ type: "Screenshot",
2598
+ subType: "log",
2599
+ status: "finished",
2600
+ executor: null,
2601
+ param: {
2602
+ title: screenshotTitle,
2603
+ content
2604
+ },
2605
+ output: {
2606
+ screenshot
2607
+ },
2608
+ thought: `Logged screenshot: ${screenshotTitle}`,
2609
+ timing: {
2610
+ start: Date.now(),
2611
+ end: Date.now(),
2612
+ cost: 0
2613
+ }
2614
+ }],
2615
+ sdkVersion: "1.0.0",
2616
+ logTime: Date.now(),
2617
+ model_name: "screenshot"
2839
2618
  };
2619
+ this.appendExecutionDump(executionDump);
2840
2620
  }
2841
- const actionType = lastAction.subType || "unknown";
2842
- const elementInfo = this.extractElementInfo(lastLocate, lastAction);
2843
- const description = this.generateActionDescription(actionType, lastAction.param, elementInfo);
2844
- return {
2845
- success: true,
2846
- actionType,
2847
- description,
2848
- elementInfo,
2849
- timing: lastAction.timing?.cost
2850
- };
2851
- }
2852
- /**
2853
- * Extract element information from locate task
2854
- */
2855
- extractElementInfo(locateTask, _actionTask) {
2856
- if (!locateTask?.output?.element)
2857
- return void 0;
2858
- const element = locateTask.output.element;
2859
- return {
2860
- type: element.attributes?.nodeType || "unknown",
2861
- text: element.content || element.attributes?.placeholder || element.attributes?.title || "",
2862
- location: `(${element.center[0]}, ${element.center[1]})`
2863
- };
2864
2621
  }
2865
- /**
2866
- * Generate natural language description for actions
2867
- */
2868
- generateActionDescription(actionType, param, elementInfo) {
2869
- const elementDesc = elementInfo ? `'${elementInfo.text || elementInfo.type}' element` : "element";
2870
- switch (actionType) {
2871
- case "Tap":
2872
- return `Clicked on ${elementDesc}`;
2873
- case "Input":
2874
- const inputValue = param?.value || "";
2875
- return `Entered "${inputValue}" into ${elementDesc}`;
2876
- case "KeyboardPress":
2877
- return `Pressed ${param?.value || "key"}`;
2878
- case "Scroll":
2879
- return `Scrolled ${param?.direction || "on page"}`;
2880
- case "Hover":
2881
- return `Hovered over ${elementDesc}`;
2882
- case "Drag":
2883
- return `Dragged ${elementDesc}`;
2884
- default:
2885
- return `Performed ${actionType} action on ${elementDesc}`;
2886
- }
2622
+ async destroy() {
2623
+ await this.page.destroy();
2887
2624
  }
2888
2625
  };
2889
2626
 
@@ -2914,7 +2651,7 @@ var Page = class {
2914
2651
  this.everMoved = false;
2915
2652
  this.underlyingPage = underlyingPage;
2916
2653
  this.pageType = pageType;
2917
- this.waitForNavigationTimeout = opts?.waitForNavigationTimeout || DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT2;
2654
+ this.waitForNavigationTimeout = opts?.waitForNavigationTimeout ?? DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT2;
2918
2655
  }
2919
2656
  async evaluate(pageFunction, arg) {
2920
2657
  let result;
@@ -3194,9 +2931,9 @@ var WebPage = class extends Page {
3194
2931
  }
3195
2932
  async waitUntilNetworkIdle(options) {
3196
2933
  await this.underlyingPage.waitForNetworkIdle({
3197
- idleTime: options?.idleTime || DEFAULT_WAIT_FOR_NETWORK_IDLE_TIME,
3198
- concurrency: options?.concurrency || DEFAULT_WAIT_FOR_NETWORK_IDLE_CONCURRENCY,
3199
- timeout: options?.timeout || this.waitForNetworkIdleTimeout
2934
+ idleTime: options?.idleTime ?? DEFAULT_WAIT_FOR_NETWORK_IDLE_TIME,
2935
+ concurrency: options?.concurrency ?? DEFAULT_WAIT_FOR_NETWORK_IDLE_CONCURRENCY,
2936
+ timeout: options?.timeout ?? this.waitForNetworkIdleTimeout
3200
2937
  });
3201
2938
  }
3202
2939
  };